platform/drivers/rethinkdb/test/toplevelqueries_test.dart

683 lines
21 KiB
Dart
Raw Normal View History

import 'package:platform_driver_rethinkdb/platform_driver_rethinkdb.dart';
import 'package:test/test.dart';
main() {
var r = RethinkDb() as dynamic;
String? databaseName;
String? tableName;
String? testDbName;
bool shouldDropTable = false;
Connection? connection;
setUp(() async {
connection = await r.connect();
if (testDbName == null) {
String useDb = await r.uuid().run(connection);
testDbName = 'unit_test_db${useDb.replaceAll("-", "")}';
await r.dbCreate(testDbName).run(connection);
}
if (databaseName == null) {
String dbName = await r.uuid().run(connection);
databaseName = "test_database_${dbName.replaceAll("-", "")}";
}
if (tableName == null) {
String tblName = await r.uuid().run(connection);
tableName = "test_table_${tblName.replaceAll("-", "")}";
}
connection!.use(testDbName!);
});
tearDown(() async {
if (shouldDropTable) {
shouldDropTable = false;
await r.tableDrop(tableName).run(connection);
}
connection!.close();
});
test("r.db throws an error if a bad database name is given", () async {
try {
await r.db('fake2834723895').tableList().run(connection);
} catch (err) {
expect(err is Exception, equals(true));
expect(err.toString().split("\n")[2],
equals('Database `fake2834723895` does not exist.'));
}
});
group("dbCreate command -> ", () {
test("r.dbCreate will create a new database", () async {
Map response = await r.dbCreate(databaseName).run(connection);
expect(response.keys.length, equals(2));
expect(response.containsKey('config_changes'), equals(true));
expect(response['dbs_created'], equals(1));
Map configChanges = response['config_changes'][0];
expect(configChanges.keys.length, equals(2));
expect(configChanges['old_val'], equals(null));
Map newVal = configChanges['new_val'];
expect(newVal.containsKey('id'), equals(true));
expect(newVal.containsKey('name'), equals(true));
expect(newVal['name'], equals(databaseName));
});
test("r.dbCreate will throw an error if the database exists", () async {
try {
await r.dbCreate(databaseName).run(connection);
} catch (err) {
expect(err is Exception, equals(true));
expect(
err.toString().split("\n")[2],
// ignore: unnecessary_brace_in_string_interps
equals('Database `${databaseName}` already exists.'));
}
});
});
group("dbDrop command -> ", () {
test("r.dbDrop should drop a database", () async {
Map response = await r.dbDrop(databaseName).run(connection);
expect(response.keys.length, equals(3));
expect(response.containsKey('config_changes'), equals(true));
expect(response['dbs_dropped'], equals(1));
expect(response['tables_dropped'], equals(0));
Map configChanges = response['config_changes'][0];
expect(configChanges.keys.length, equals(2));
expect(configChanges['new_val'], equals(null));
Map oldVal = configChanges['old_val'];
expect(oldVal.containsKey('id'), equals(true));
expect(oldVal.containsKey('name'), equals(true));
expect(oldVal['name'], equals(databaseName));
});
test("r.dbDrop should error if the database does not exist", () async {
try {
await r.dbDrop(databaseName).run(connection);
} catch (err) {
expect(err.toString().split("\n")[2],
equals('Database `$databaseName` does not exist.'));
}
});
});
test("r.dbList should list all databases", () async {
List response = await r.dbList().run(connection);
expect(response.indexOf('rethinkdb'), greaterThan(-1));
});
group("range command -> ", () {
test("r.range() with no arguments should return a stream", () async {
Cursor cur = await r.range().run(connection);
List item = await cur.take(17).toList();
expect(item,
equals([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]));
});
test("r.range() should accept a single end arguement", () async {
Cursor cur = await r.range(10).run(connection);
List l = await cur.toList();
expect(l, equals([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]));
});
test("r.range() should accept a start and end arguement", () async {
Cursor cur = await r.range(7, 10).run(connection);
List l = await cur.toList();
expect(l, equals([7, 8, 9]));
});
});
group("table command -> ", () {
test("table should return a cursor containing all records for a table",
() async {
Cursor cur = await r.db('rethinkdb').table('stats').run(connection);
await for (Map item in cur) {
expect(item.containsKey('id'), equals(true));
expect(item.containsKey('query_engine'), equals(true));
}
});
test("table should allow for `read_mode: single` option", () async {
Cursor cur = await r
.db('rethinkdb')
.table('stats', {'read_mode': 'single'}).run(connection);
await for (Map item in cur) {
expect(item.containsKey('id'), equals(true));
expect(item.containsKey('query_engine'), equals(true));
}
});
test("table should allow for `read_mode: majority` option", () async {
Cursor cur = await r
.db('rethinkdb')
.table('stats', {'read_mode': 'majority'}).run(connection);
await for (Map item in cur) {
expect(item.containsKey('id'), equals(true));
expect(item.containsKey('query_engine'), equals(true));
}
});
test("table should allow for `read_mode: outdated` option", () async {
Cursor cur = await r
.db('rethinkdb')
.table('stats', {'read_mode': 'outdated'}).run(connection);
await for (Map item in cur) {
expect(item.containsKey('id'), equals(true));
expect(item.containsKey('query_engine'), equals(true));
}
});
test("table should catch invalid read_mode option", () async {
try {
await r
.db('rethinkdb')
.table('stats', {'read_mode': 'badReadMode'}).run(connection);
} catch (err) {
expect(
err.toString().split("\n")[2],
equals(
'Read mode `badReadMode` unrecognized (options are "majority", "single", and "outdated").'));
}
});
test("table should allow for `identifier_format: name` option", () async {
Cursor cur = await r
.db('rethinkdb')
.table('stats', {'identifier_format': 'name'}).run(connection);
await for (Map item in cur) {
expect(item.containsKey('id'), equals(true));
expect(item.containsKey('query_engine'), equals(true));
}
});
test("table should allow for `identifier_format: uuid` option", () async {
Cursor cur = await r
.db('rethinkdb')
.table('stats', {'identifier_format': 'uuid'}).run(connection);
await for (Map item in cur) {
expect(item.containsKey('id'), equals(true));
expect(item.containsKey('query_engine'), equals(true));
}
});
test("table should catch invalid identifier_format option", () async {
try {
await r
.db('rethinkdb')
.table('stats', {'identifier_format': 'badFormat'}).run(connection);
} catch (err) {
expect(
err.toString().split("\n")[2],
equals(
'Identifier format `badFormat` unrecognized (options are "name" and "uuid").'));
}
});
test("table should catch bad options", () async {
try {
await r
.db('rethinkdb')
.table('stats', {'fake_option': 'bad_value'}).run(connection);
} catch (err) {
expect(err.toString().split("\n")[2],
equals('Unrecognized optional argument `fake_option`.'));
}
});
});
group("time command -> ", () {
test(
"should return a time object if given a year, month, day, and timezone",
() async {
DateTime obj = await r.time(2010, 12, 29, timezone: 'Z').run(connection);
expect(obj.runtimeType, equals(DateTime));
expect(obj.isBefore(DateTime.now()), equals(true));
expect(obj.minute, equals(0));
expect(obj.second, equals(0));
});
test(
"should return a time object if given a year, month, day, hour, minute, second, and timezone",
() async {
DateTime obj = await r
.time(2010, 12, 29, hour: 7, minute: 33, second: 45, timezone: 'Z')
.run(connection);
expect(obj.runtimeType, equals(DateTime));
expect(obj.isBefore(DateTime.now()), equals(true));
expect(obj.minute, equals(33));
expect(obj.second, equals(45));
});
});
test(
"nativeTime command -> should turn a native dart DateTime to a reql time",
() async {
DateTime dt = DateTime.now();
DateTime rqlDt = await r.nativeTime(dt).run(connection);
expect(dt.year, equals(rqlDt.year));
expect(dt.month, equals(rqlDt.month));
expect(dt.day, equals(rqlDt.day));
expect(dt.hour, equals(rqlDt.hour));
expect(dt.minute, equals(rqlDt.minute));
expect(dt.second, equals(rqlDt.second));
});
group("ISO8601 command -> ", () {
test("should take an ISO8601 string and convert it to a DateTime object",
() async {
DateTime dt =
await r.ISO8601('1986-11-03T08:30:00-07:00').run(connection);
expect(dt.year, equals(1986));
expect(dt.month, equals(11));
expect(dt.day, equals(3));
expect(dt.minute, equals(30));
});
test("should accept a timezone argument as well", () async {
DateTime dt =
await r.ISO8601('1986-11-03T08:30:00-07:00', 'MST').run(connection);
expect(dt.year, equals(1986));
expect(dt.month, equals(11));
expect(dt.day, equals(3));
expect(dt.minute, equals(30));
});
});
test("epochTime command -> should take a timestamp and return a time object",
() async {
DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(531360000000);
DateTime dt = await r.epochTime(531360000).run(connection);
expect(dt.month, equals(dateTime.month));
expect(dt.day, equals(dateTime.day));
expect(dt.hour, equals(dateTime.hour));
expect(dt.minute, equals(dateTime.minute));
expect(dt.second, equals(dateTime.second));
});
test("now command -> should return current DateTime object", () async {
DateTime dt = await r.now().run(connection);
await Future.delayed(Duration(milliseconds: 1));
//expect(dt is DateTime, equals(true));
expect(DateTime.now().difference(dt).inSeconds == 0, equals(true));
});
group("rqlDo command -> ", () {
test("should accept a single argument and function", () async {
bool i = await r.rqlDo(3, (item) => item > 4).run(connection);
expect(i, equals(false));
});
test("should accept a many arguments and a function", () async {
num i = await r
.rqlDo(
3,
4,
5,
6,
7,
(item1, item2, item3, item4, item5) =>
item1 + item2 + item3 + item4 + item5)
.run(connection);
expect(i, equals(25));
});
test("should accept many args and an expression", () async {
Cursor cur = await r.rqlDo(3, 7, r.range).run(connection);
List list = await cur.toList();
expect(list, equals([3, 4, 5, 6]));
});
});
group("branch command -> ", () {
test("should accept a true test and return the true branch value",
() async {
String val = await r.branch(3 < 4, 'isTrue', 'isFalse').run(connection);
expect(val, equals('isTrue'));
});
test("should accept a false test and return the false branch value",
() async {
String val = await r.branch(3 > 4, 'isTrue', 'isFalse').run(connection);
expect(val, equals('isFalse'));
});
test("should accept multiple tests and actions", () async {
String val = await r
.branch(1 > 4, 'isTrue', 0 < 1, 'elseTrue', 'isFalse')
.run(connection);
expect(val, equals('elseTrue'));
});
});
test("error command -> should create a custom error", () async {
try {
await r.error('This is my Error').run(connection);
} catch (err) {
expect(err.runtimeType, equals(ReqlUserError));
expect(err.toString().split("\n")[2], equals('This is my Error'));
}
});
group("js command -> ", () {
test("should run custom javascript", () async {
String jsString = """
function concatStrs(){
return 'firstHalf' + '_' + 'secondHalf';
}
concatStrs();
""";
String str = await r.js(jsString).run(connection);
expect(str, equals('firstHalf_secondHalf'));
});
//TODO: fix test
// test("should accept a timeout option", () async {
// String jsString = """
// function concatStrs(){
// return 'firstHalf' + '_' + 'secondHalf';
// }
// while(true){
// concatStrs();
// }
// """;
// int timeout = 3;
// try {
// await r.js(jsString, {'timeout': timeout}).run(connection);
// } catch (err) {
// expect(
// err.toString(),
// equals(
// 'JavaScript query `$jsString` timed out after $timeout.000 seconds.'));
// }
// });
});
group("json command -> ", () {
test("should parse a json string", () async {
String jsonString = "[1,2,3,4]";
List obj = await r.json(jsonString).run(connection);
expect([1, 2, 3, 4], equals(obj));
});
test("should throw error if jsonString is invalid", () async {
String jsonString = "1,2,3,4]";
try {
await r.json(jsonString).run(connection);
} catch (err) {
expect(
err.toString().split("\n")[2],
equals(
'Failed to parse "$jsonString" as JSON: The document root must not follow by other values.'));
}
});
});
group("object command -> ", () {
test("should create an object from an array of values", () async {
Map obj = await r
.object('key', 'val', 'listKey', [1, 2, 3, 4], 'objKey', {'a': 'b'})
.run(connection);
//expect(obj is Map, equals(true));
expect(obj['key'], equals('val'));
expect(obj['listKey'], equals([1, 2, 3, 4]));
expect(obj['objKey']['a'], equals('b'));
});
test("should throw an error if params cannot be parsed into a map",
() async {
try {
await r
.object('key', 'val', 'listKey', [1, 2, 3, 4], 'objKey', {'a': 'b'},
'odd')
.run(connection);
} catch (err) {
expect(
err.toString().split("\n")[2],
equals(
'OBJECT expects an even number of arguments (but found 7).'));
}
});
});
test("args command -> should accept an array", () async {
List l = await r.args([1, 2]).run(connection);
expect(l, equals([1, 2]));
});
group("random command -> ", () {
test("should generate a random number if no parameters are provided",
() async {
double number = await r.random().run(connection);
expect(number, lessThanOrEqualTo(1));
expect(number, greaterThanOrEqualTo(0));
});
test(
"should generate a positive random int no greater than the single argument",
() async {
int number = await r.random(50).run(connection);
expect(number, lessThanOrEqualTo(50));
expect(number, greaterThanOrEqualTo(0));
});
test("should generate a random int between the two arguments", () async {
int number = await r.random(50, 55).run(connection);
expect(number, lessThanOrEqualTo(55));
expect(number, greaterThanOrEqualTo(50));
});
test("should generate a random float between the two arguments", () async {
double number = await r.random(50, 55, {'float': true}).run(connection);
expect(number, lessThanOrEqualTo(55));
expect(number, greaterThanOrEqualTo(50));
});
});
group("not command -> ", () {
test("should return false if given no arguements", () async {
bool val = await r.not().run(connection);
expect(val, equals(false));
});
test("should return the inverse of the argument provided", () async {
bool val = await r.not(false).run(connection);
expect(val, equals(true));
});
});
group("map command -> ", () {
test("should map over an array", () async {
List arr =
await r.map([1, 2, 3, 4, 5], (item) => item * 2).run(connection);
expect(arr, equals([2, 4, 6, 8, 10]));
});
test("should map over multiple arrays", () async {
List arr = await r.map([1, 2, 3, 4, 5], [10, 9, 8, 7],
(item, item2) => item + item2).run(connection);
//notice that the first array is longer but we
//only map the length of the shortest array
expect(arr, equals([11, 11, 11, 11]));
});
test("should map a sequence", () async {
List arr = await r
.map(
r.expr({
'key': [1, 2, 3, 4, 5]
}).getField('key'),
(item) => item + 1)
.run(connection);
expect(arr, equals([2, 3, 4, 5, 6]));
});
test("should map over multiple sequences", () async {
List arr = await r
.map(
r.expr({
'key': [1, 2, 3, 4, 5]
}).getField('key'),
r.expr({
'key': [1, 2, 3, 4, 5]
}).getField('key'),
(item, item2) => item + item2)
.run(connection);
expect(arr, equals([2, 4, 6, 8, 10]));
});
});
group("and command -> ", () {
test("should and two values together", () async {
bool val = await r.and(true, true).run(connection);
expect(val, equals(true));
});
test("should and more than two values together", () async {
bool val = await r.and(true, true, false).run(connection);
expect(val, equals(false));
});
});
group("or command -> ", () {
test("should or two values together", () async {
bool val = await r.or(true, false).run(connection);
expect(val, equals(true));
});
test("should and more than two values together", () async {
bool val = await r.or(false, false, false).run(connection);
expect(val, equals(false));
});
});
group("binary command -> ", () {
test("should convert string to binary", () async {
List data = await r.binary('billysometimes').run(connection);
expect(
data,
equals([
98,
105,
108,
108,
121,
115,
111,
109,
101,
116,
105,
109,
101,
115
]));
});
});
group("uuid command -> ", () {
test("should create a unique uuid", () async {
String val = await r.uuid().run(connection);
expect(val, isNotNull);
});
test("should create a uuid based on a string key", () async {
String key = "billysometimes";
String val = await r.uuid(key).run(connection);
expect(val, equals('b3f5029e-f777-572f-a85d-5529b74fd99b'));
});
});
group("expr command -> ", () {
test("expr should convert native string to rql string", () async {
String str = await r.expr('string').run(connection);
expect(str, equals('string'));
});
test("expr should convert native int to rql int", () async {
int str = await r.expr(3).run(connection);
expect(str, equals(3));
});
test("expr should convert native double to rql float", () async {
double str = await r.expr(3.14).run(connection);
expect(str, equals(3.14));
});
test("expr should convert native bool to rql bool", () async {
bool str = await r.expr(true).run(connection);
expect(str, equals(true));
});
test("expr should convert native list to rql array", () async {
List str = await r.expr([1, 2, 3]).run(connection);
expect(str, equals([1, 2, 3]));
});
test("expr should convert native object to rql object", () async {
Map str = await r.expr({'a': 'b'}).run(connection);
expect(str, equals({'a': 'b'}));
});
});
test("remove the test database", () async {
Map response = await r.dbDrop(testDbName).run(connection);
expect(response.containsKey('config_changes'), equals(true));
expect(response['dbs_dropped'], equals(1));
expect(response['tables_dropped'], equals(0));
});
/// TO TEST:
/// test with orderby: r.asc(attr)
/// test with orderby: r.desc(attr)
/// r.http(url)
///
/// test with filter or something: r.row;
/// test with time: r.monday ... r.sunday;
/// test with time: r.january .. r.december;
}