schemaTests method
void
schemaTests()
Implementation
void schemaTests() {
group('Schema operations', () {
Connection? connection;
tearDown(() async {
await connection?.close();
});
group('initialization', () {
group('AddCollection', () {
test('collection is available after connection', () async {
final schema = CollectionSchema(
tableName,
properties: [
PropertySchema("name", type: PropertyType.text),
PropertySchema("age", type: PropertyType.integer),
],
);
connection = await connector.connect((Connection connection) async {
final initCursor = await connection.cursor();
await initCursor.execute(AddCollection(schema));
});
final cursor = await connection!.cursor();
await cursor.execute(Query(from: schema));
expect(await cursor.fetchall(), equals([]));
});
test('ifNotExists does not complain if run twice', () async {
final schema = CollectionSchema(
tableName,
properties: [
PropertySchema("name", type: PropertyType.text),
PropertySchema("age", type: PropertyType.integer),
],
);
connection = await connector.connect((Connection connection) async {
final initCursor = await connection.cursor();
await initCursor.execute(AddCollection(schema));
await initCursor.execute(AddCollection(
schema,
ifNotExists: true,
));
});
final cursor = await connection!.cursor();
await cursor.execute(Query(from: schema));
expect(await cursor.fetchall(), equals([]));
});
test('cannot add collections with same name', () async {
final failing = connector.connect((Connection connection) async {
final initCursor = await connection.cursor();
final op = AddCollection(
CollectionSchema(
tableName,
properties: [
PropertySchema("name", type: PropertyType.text),
PropertySchema("age", type: PropertyType.integer),
],
),
);
await initCursor.execute(op);
await initCursor.execute(op);
});
expectLater(failing, throwsA(isA<ProgrammingError>()));
});
});
group('RemoveCollection', () {
test('It removes the collection', () async {
final schema = CollectionSchema(
tableName,
properties: [
PropertySchema("name", type: PropertyType.text),
PropertySchema("age", type: PropertyType.integer),
],
);
connection = await connector.connect((Connection connection) async {
final initCursor = await connection.cursor();
await initCursor.execute(AddCollection(schema));
await initCursor.execute(RemoveCollection(tableName));
});
final cursor = await connection!.cursor();
final failing = cursor.execute(Query(from: schema));
expectLater(failing, throwsA(isA<ProgrammingError>()));
});
test('Cannot remove a non-existant collection', () async {
connection = await connector.connect((Connection connection) async {
final initCursor = await connection.cursor();
final failing =
initCursor.execute(RemoveCollection(" I do not exist"));
expectLater(failing, throwsA(isA<ProgrammingError>()));
});
});
}, skip: requireFeature(DatabaseFeature.removeCollection));
group('AddProperty', () {
test('It adds a property to the collection', () async {
connection = await connector.connect((Connection connection) async {
final initCursor = await connection.cursor();
final collectionSchema = CollectionSchema(
tableName,
properties: [
PropertySchema("name", type: PropertyType.text),
PropertySchema("age", type: PropertyType.integer),
],
);
await initCursor.execute(AddCollection(collectionSchema));
await initCursor.execute(AddProperty(
collection: collectionSchema,
property: PropertySchema("email", type: PropertyType.text)));
});
final finalSchema = CollectionSchema(
tableName,
properties: [
PropertySchema("name", type: PropertyType.text),
PropertySchema("age", type: PropertyType.integer),
PropertySchema("email", type: PropertyType.text),
],
);
final cursor = await connection!.cursor();
await cursor.execute(Insert(finalSchema, [
{
"name": "Me",
"age": 123,
"email": "me@me.com",
}
]));
await cursor.execute(Query(from: finalSchema));
final results = await cursor.fetchall();
expect(results[0]["email"], "me@me.com");
});
test('Cannot add existing property', () async {
connection = await connector.connect((Connection connection) async {
final initCursor = await connection.cursor();
final collection = CollectionSchema(
tableName,
properties: [
PropertySchema("name", type: PropertyType.text),
PropertySchema("age", type: PropertyType.integer),
],
);
await initCursor.execute(AddCollection(collection));
final failing = initCursor.execute(AddProperty(
collection: collection,
property: PropertySchema("name", type: PropertyType.text)));
expectLater(failing, throwsA(isA<ProgrammingError>()));
});
});
test('Cannot add property to nonexisting collection', () async {
connection = await connector.connect((Connection connection) async {
final initCursor = await connection.cursor();
final collection = CollectionSchema(
tableName,
properties: [
PropertySchema("name", type: PropertyType.text),
PropertySchema("age", type: PropertyType.integer),
],
);
final failing = initCursor.execute(AddProperty(
collection: collection,
property: PropertySchema("name", type: PropertyType.text)));
expectLater(failing, throwsA(isA<ProgrammingError>()));
});
});
}, skip: requireFeature(DatabaseFeature.addProperty));
group('RemoveProperty', () {
/// This test is very lenient - basically, removing a
/// property should allow to later insert an object without
/// that property (which is a very lax requirement).
test('It removes a property from the collection', () async {
connection = await connector.connect((Connection connection) async {
final initCursor = await connection.cursor();
final collectionSchema = CollectionSchema(
tableName,
properties: [
PropertySchema("name", type: PropertyType.text),
PropertySchema("age", type: PropertyType.integer),
],
);
await initCursor.execute(AddCollection(collectionSchema));
await initCursor.execute(RemoveProperty(
collection: collectionSchema, propertyName: "age"));
});
final finalSchema = CollectionSchema(
tableName,
properties: [
PropertySchema("name", type: PropertyType.text),
],
);
final cursor = await connection!.cursor();
await cursor.execute(Insert(finalSchema, [
{
"name": "Me",
}
]));
await cursor.execute(Query(from: finalSchema));
final results = await cursor.fetchall();
expect(results[0]["name"], "Me");
});
test('cannot remove property from non-existant collection', () async {
final failing = connector.connect((Connection connection) async {
final initCursor = await connection.cursor();
final collectionSchema = CollectionSchema(
tableName,
properties: [
PropertySchema("name", type: PropertyType.text),
PropertySchema("age", type: PropertyType.integer),
],
);
// collection declared, but not used
await initCursor.execute(RemoveProperty(
collection: collectionSchema, propertyName: "email"));
});
expectLater(failing, throwsA(isA<ProgrammingError>()));
});
test('cannot remove nonexistant property', () async {
final failing = connector.connect((Connection connection) async {
final initCursor = await connection.cursor();
final collectionSchema = CollectionSchema(
tableName,
properties: [
PropertySchema("name", type: PropertyType.text),
PropertySchema("age", type: PropertyType.integer),
],
);
await initCursor.execute(AddCollection(collectionSchema));
await initCursor.execute(RemoveProperty(
collection: collectionSchema, propertyName: "email"));
});
expectLater(failing, throwsA(isA<ProgrammingError>()));
});
}, skip: requireFeature(DatabaseFeature.removeProperty));
group('RenameCollection', () {
test('the new collection can be used', () async {
final initialSchema = CollectionSchema(
tableName,
properties: [
PropertySchema("name", type: PropertyType.text),
PropertySchema("age", type: PropertyType.integer),
],
);
connection = await connector.connect((Connection connection) async {
final initCursor = await connection.cursor();
await initCursor.execute(AddCollection(initialSchema));
await initCursor.execute(
RenameCollection(oldName: tableName, newName: "new_users"));
});
final finalSchema = initialSchema.copyWith(
name: "new_users",
);
final cursor = await connection!.cursor();
await cursor.execute(Insert(finalSchema, [
{
"name": "Me",
"age": 35,
}
]));
await cursor.execute(Query(from: finalSchema));
final results = await cursor.fetchall();
expect(results[0]["name"], "Me");
});
test('the old collection cannot be used', () async {
final initialCollection = CollectionSchema(
tableName,
properties: [
PropertySchema("name", type: PropertyType.text),
PropertySchema("age", type: PropertyType.integer),
],
);
connection = await connector.connect((Connection connection) async {
final initCursor = await connection.cursor();
await initCursor.execute(AddCollection(initialCollection));
await initCursor.execute(
RenameCollection(oldName: tableName, newName: "new_users"));
});
final cursor = await connection!.cursor();
final failing = cursor.execute(Insert(initialCollection, [
{
"name": "Me",
"age": 35,
}
]));
expectLater(failing, throwsA(isA<ProgrammingError>()));
});
test('Cannot rename a non-existant collection', () async {
connection = await connector.connect((Connection connection) async {
final initCursor = await connection.cursor();
final failing = initCursor.execute(RenameCollection(
oldName: "not_existant", newName: "does_not_matter"));
expectLater(failing, throwsA(isA<ProgrammingError>()));
});
});
}, skip: requireFeature(DatabaseFeature.renameCollection));
group('AlterProperty', () {
test('non-null -> null', () async {
final name = PropertySchema("name",
type: PropertyType.text, nullable: false);
final nameNew = name.copyWith(nullable: true);
final initialSchema = CollectionSchema(
tableName,
properties: [
name,
],
);
connection = await connector.connect((Connection connection) async {
final initCursor = await connection.cursor();
await initCursor.execute(AddCollection(initialSchema));
await initCursor.execute(Insert(initialSchema, [
{
"name": "Paul Sellers",
}
]));
await initCursor.execute(AlterProperty(
oldCollection: initialSchema,
property: nameNew,
));
await initCursor.execute(Insert(initialSchema, [
{
"name": null,
}
]));
});
final finalSchema = initialSchema.copyWith(properties: [
nameNew,
]);
final cursor = await connection!.cursor();
await cursor.execute(Query(from: finalSchema));
final results = await cursor.fetchall();
expect(results, hasLength(2));
});
test('null -> non-null with no null values works', () async {
final name =
PropertySchema("name", type: PropertyType.text, nullable: true);
final nameNew = name.copyWith(nullable: false);
final initialSchema = CollectionSchema(
tableName,
properties: [
name,
],
);
connection = await connector.connect((Connection connection) async {
final initCursor = await connection.cursor();
await initCursor.execute(AddCollection(initialSchema));
await initCursor.execute(Insert(initialSchema, [
{
"name": "Paul Sellers",
}
]));
await initCursor.execute(AlterProperty(
oldCollection: initialSchema,
property: nameNew,
));
});
final finalSchema = initialSchema.copyWith(properties: [
nameNew,
]);
final cursor = await connection!.cursor();
await cursor.execute(Query(from: finalSchema));
final results = await cursor.fetchall();
expect(results, hasLength(1));
final failing = cursor.execute(Insert(finalSchema, [
{
"name": null,
}
]));
expect(failing, throwsA(isA<IntegrityError>()));
});
test('unique -> non-unique', () async {
final name =
PropertySchema("name", type: PropertyType.text, unique: true);
final nameNew = name.copyWith(unique: false);
final initialSchema = CollectionSchema(
tableName,
properties: [
name,
],
);
connection = await connector.connect((Connection connection) async {
final initCursor = await connection.cursor();
await initCursor.execute(AddCollection(initialSchema));
await initCursor.execute(Insert(initialSchema, [
{
"name": "Paul Sellers",
}
]));
await initCursor.execute(AlterProperty(
oldCollection: initialSchema,
property: nameNew,
));
await initCursor.execute(Insert(initialSchema, [
{
"name": "Paul Sellers",
}
]));
});
final finalSchema = initialSchema.copyWith(properties: [
nameNew,
]);
final cursor = await connection!.cursor();
await cursor.execute(Query(from: finalSchema));
final results = await cursor.fetchall();
expect(results, hasLength(2));
}, skip: requireFeature(DatabaseFeature.uniqueProperty));
test('non-unique -> unique with no conflicts works', () async {
final name =
PropertySchema("name", type: PropertyType.text, unique: false);
final nameNew = name.copyWith(unique: true);
final initialSchema = CollectionSchema(
tableName,
properties: [
name,
],
);
connection = await connector.connect((Connection connection) async {
final initCursor = await connection.cursor();
await initCursor.execute(AddCollection(initialSchema));
await initCursor.execute(Insert(initialSchema, [
{
"name": "Paul Sellers",
}
]));
await initCursor.execute(AlterProperty(
oldCollection: initialSchema,
property: nameNew,
));
});
final finalSchema = initialSchema.copyWith(properties: [
nameNew,
]);
final cursor = await connection!.cursor();
await cursor.execute(Query(from: finalSchema));
final results = await cursor.fetchall();
expect(results, hasLength(1));
final failing = cursor.execute(Insert(finalSchema, [
{
"name": "Paul Sellers",
}
]));
expect(failing, throwsA(isA<IntegrityError>()));
}, skip: requireFeature(DatabaseFeature.uniqueProperty));
test('Cannot alter property of a non-existant collection', () async {
final p1 = PropertySchema('nopes', type: PropertyType.boolean);
final p2 = p1.copyWith(nullable: false);
connection = await connector.connect((Connection connection) async {
final initCursor = await connection.cursor();
final failing = initCursor.execute(AlterProperty(
oldCollection:
CollectionSchema('notExistant', properties: [p1]),
property: p2,
));
expectLater(failing, throwsA(isA<ProgrammingError>()));
});
});
test('Cannot alter non-existant property', () async {
final p1 = PropertySchema('nopes', type: PropertyType.boolean);
final collection = CollectionSchema(
tableName,
properties: [
PropertySchema("name", type: PropertyType.text),
],
);
connection = await connector.connect((Connection connection) async {
final initCursor = await connection.cursor();
await initCursor.execute(AddCollection(collection));
final failing = initCursor.execute(AlterProperty(
oldCollection: collection,
property: p1,
));
expectLater(failing, throwsA(isA<ProgrammingError>()));
});
});
}, skip: requireFeature(DatabaseFeature.alterProperty));
group('RenameProperty', () {
test('the new property can be used', () async {
final name = PropertySchema("name", type: PropertyType.text);
final age = PropertySchema("age", type: PropertyType.integer);
final initialSchema = CollectionSchema(
tableName,
properties: [
name,
age,
],
);
connection = await connector.connect((Connection connection) async {
final initCursor = await connection.cursor();
await initCursor.execute(AddCollection(initialSchema));
await initCursor.execute(Insert(initialSchema, [
{
"name": "Paul Sellers",
"age": 75,
}
]));
await initCursor.execute(RenameProperty(
collectionName: tableName,
oldName: "name",
newName: "full_name",
));
});
final finalSchema = initialSchema.copyWith(properties: [
name.copyWith(name: "full_name"),
age,
]);
final cursor = await connection!.cursor();
await cursor.execute(Query(from: finalSchema));
final results = await cursor.fetchall();
expect(results[0]["full_name"], "Paul Sellers");
});
test('Cannot rename property of a non-existant collection', () async {
connection = await connector.connect((Connection connection) async {
final initCursor = await connection.cursor();
final failing = initCursor.execute(RenameProperty(
collectionName: "not_existant",
oldName: "does_not_matter",
newName: "does_not_matter",
));
expectLater(failing, throwsA(isA<ProgrammingError>()));
});
});
test('Cannot rename non-existant property', () async {
connection = await connector.connect((Connection connection) async {
final initCursor = await connection.cursor();
await initCursor.execute(AddCollection(
CollectionSchema(
tableName,
properties: [
PropertySchema("name", type: PropertyType.text),
PropertySchema("age", type: PropertyType.integer),
],
),
));
final failing = initCursor.execute(RenameProperty(
collectionName: tableName,
oldName: "not_existant",
newName: "does_not_matter",
));
expectLater(failing, throwsA(isA<ProgrammingError>()));
});
});
}, skip: requireFeature(DatabaseFeature.renameProperty));
});
});
}