From ad4afc0a5933813ea5487a0714da2003e84c18da Mon Sep 17 00:00:00 2001 From: Steven Nguyen Date: Tue, 20 Jun 2023 13:11:42 -0700 Subject: [PATCH] Add tests for helpers and moels to Flutter and Dart SDKs --- src/SDK/Language/Dart.php | 30 +++ src/SDK/Language/Flutter.php | 40 ++++ templates/dart/test/id_test.dart.twig | 16 ++ templates/dart/test/permission_test.dart.twig | 34 ++++ templates/dart/test/query_test.dart.twig | 192 ++++++++++++++++++ templates/dart/test/role_test.dart.twig | 52 +++++ templates/dart/test/src/enums_test.dart.twig | 12 ++ .../dart/test/src/models/model_test.dart.twig | 26 +++ .../dart/test/src/response_test.dart.twig | 18 ++ .../test/src/cookie_manager_test.dart.twig | 99 +++++++++ 10 files changed, 519 insertions(+) create mode 100644 templates/dart/test/id_test.dart.twig create mode 100644 templates/dart/test/permission_test.dart.twig create mode 100644 templates/dart/test/query_test.dart.twig create mode 100644 templates/dart/test/role_test.dart.twig create mode 100644 templates/dart/test/src/enums_test.dart.twig create mode 100644 templates/dart/test/src/models/model_test.dart.twig create mode 100644 templates/dart/test/src/response_test.dart.twig create mode 100644 templates/flutter/test/src/cookie_manager_test.dart.twig diff --git a/src/SDK/Language/Dart.php b/src/SDK/Language/Dart.php index 16c704092..51f46c301 100644 --- a/src/SDK/Language/Dart.php +++ b/src/SDK/Language/Dart.php @@ -401,6 +401,36 @@ public function getFiles(): array 'destination' => 'docs/examples/{{service.name | caseLower}}/{{method.name | caseDash}}.md', 'template' => 'dart/docs/example.md.twig', ], + [ + 'scope' => 'default', + 'destination' => '/test/id_test.dart', + 'template' => 'dart/test/id_test.dart.twig', + ], + [ + 'scope' => 'default', + 'destination' => '/test/permission_test.dart', + 'template' => 'dart/test/permission_test.dart.twig', + ], + [ + 'scope' => 'default', + 'destination' => '/test/query_test.dart', + 'template' => 'dart/test/query_test.dart.twig', + ], + [ + 'scope' => 'default', + 'destination' => '/test/role_test.dart', + 'template' => 'dart/test/role_test.dart.twig', + ], + [ + 'scope' => 'default', + 'destination' => '/test/src/enums_test.dart', + 'template' => 'dart/test/src/enums_test.dart.twig', + ], + [ + 'scope' => 'default', + 'destination' => '/test/src/response_test.dart', + 'template' => 'dart/test/src/response_test.dart.twig', + ], [ 'scope' => 'default', 'destination' => '.travis.yml', diff --git a/src/SDK/Language/Flutter.php b/src/SDK/Language/Flutter.php index a76ffb377..6dc3add15 100644 --- a/src/SDK/Language/Flutter.php +++ b/src/SDK/Language/Flutter.php @@ -245,6 +245,46 @@ public function getFiles(): array 'destination' => '/test/services/{{service.name | caseDash}}_test.dart', 'template' => 'flutter/test/services/service_test.dart.twig', ], + [ + 'scope' => 'definition', + 'destination' => '/test/src/models/{{definition.name | caseSnake }}_test.dart', + 'template' => 'dart/test/src/models/model_test.dart.twig', + ], + [ + 'scope' => 'default', + 'destination' => '/test/id_test.dart', + 'template' => 'dart/test/id_test.dart.twig', + ], + [ + 'scope' => 'default', + 'destination' => '/test/permission_test.dart', + 'template' => 'dart/test/permission_test.dart.twig', + ], + [ + 'scope' => 'default', + 'destination' => '/test/query_test.dart', + 'template' => 'dart/test/query_test.dart.twig', + ], + [ + 'scope' => 'default', + 'destination' => '/test/role_test.dart', + 'template' => 'dart/test/role_test.dart.twig', + ], + [ + 'scope' => 'default', + 'destination' => '/test/src/cookie_manager_test.dart', + 'template' => 'flutter/test/src/cookie_manager_test.dart.twig', + ], + [ + 'scope' => 'default', + 'destination' => '/test/src/enums_test.dart', + 'template' => 'dart/test/src/enums_test.dart.twig', + ], + [ + 'scope' => 'default', + 'destination' => '/test/src/response_test.dart', + 'template' => 'dart/test/src/response_test.dart.twig', + ], [ 'scope' => 'method', 'destination' => 'docs/examples/{{service.name | caseLower}}/{{method.name | caseDash}}.md', diff --git a/templates/dart/test/id_test.dart.twig b/templates/dart/test/id_test.dart.twig new file mode 100644 index 000000000..8a5434ab0 --- /dev/null +++ b/templates/dart/test/id_test.dart.twig @@ -0,0 +1,16 @@ +import 'package:{{ language.params.packageName }}/{{ language.params.packageName }}.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group('unique()', () { + test('returns unique()', () { + expect(ID.unique(), 'unique()'); + }); + }); + + group('custom()', () { + test('returns the custom string', () { + expect(ID.custom('custom'), 'custom'); + }); + }); +} diff --git a/templates/dart/test/permission_test.dart.twig b/templates/dart/test/permission_test.dart.twig new file mode 100644 index 000000000..4e784b879 --- /dev/null +++ b/templates/dart/test/permission_test.dart.twig @@ -0,0 +1,34 @@ +import 'package:{{ language.params.packageName }}/{{ language.params.packageName }}.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group('read()', () { + test('returns read', () { + expect(Permission.read(Role.any()), 'read("any")'); + }); + }); + + group('write()', () { + test('returns write', () { + expect(Permission.write(Role.any()), 'write("any")'); + }); + }); + + group('create()', () { + test('returns create', () { + expect(Permission.create(Role.any()), 'create("any")'); + }); + }); + + group('update()', () { + test('returns update', () { + expect(Permission.update(Role.any()), 'update("any")'); + }); + }); + + group('delete()', () { + test('returns delete', () { + expect(Permission.delete(Role.any()), 'delete("any")'); + }); + }); +} diff --git a/templates/dart/test/query_test.dart.twig b/templates/dart/test/query_test.dart.twig new file mode 100644 index 000000000..f74be35bc --- /dev/null +++ b/templates/dart/test/query_test.dart.twig @@ -0,0 +1,192 @@ +import 'package:{{ language.params.packageName }}/{{ language.params.packageName }}.dart'; +import 'package:flutter_test/flutter_test.dart'; + +class BasicFilterQueryTest { + final String description; + final dynamic value; + final String expectedValues; + + BasicFilterQueryTest({ + required this.description, + required this.value, + required this.expectedValues, + }); +} + +void main() { + group('basic filter tests', () { + final tests = [ + BasicFilterQueryTest( + description: 'with a string', + value: 's', + expectedValues: '["s"]', + ), + BasicFilterQueryTest( + description: 'with an integer', + value: 1, + expectedValues: '[1]', + ), + BasicFilterQueryTest( + description: 'with a double', + value: 1.2, + expectedValues: '[1.2]', + ), + BasicFilterQueryTest( + description: 'with a whole number double', + value: 1.0, + expectedValues: '[1.0]', + ), + BasicFilterQueryTest( + description: 'with a bool', + value: false, + expectedValues: '[false]', + ), + BasicFilterQueryTest( + description: 'with a list', + value: ['a', 'b', 'c'], + expectedValues: '["a","b","c"]', + ), + ]; + + group('equal()', () { + for (var t in tests) { + test(t.description, () { + expect( + Query.equal('attr', t.value), + 'equal("attr", ${t.expectedValues})', + ); + }); + } + }); + + group('notEqual()', () { + for (var t in tests) { + test(t.description, () { + expect( + Query.notEqual('attr', t.value), + 'notEqual("attr", ${t.expectedValues})', + ); + }); + } + }); + + group('lessThan()', () { + for (var t in tests) { + test(t.description, () { + expect( + Query.lessThan('attr', t.value), + 'lessThan("attr", ${t.expectedValues})', + ); + }); + } + }); + + group('lessThanEqual()', () { + for (var t in tests) { + test(t.description, () { + expect( + Query.lessThanEqual('attr', t.value), + 'lessThanEqual("attr", ${t.expectedValues})', + ); + }); + } + }); + + group('greaterThan()', () { + for (var t in tests) { + test(t.description, () { + expect( + Query.greaterThan('attr', t.value), + 'greaterThan("attr", ${t.expectedValues})', + ); + }); + } + }); + + group('greaterThanEqual()', () { + for (var t in tests) { + test(t.description, () { + expect( + Query.greaterThanEqual('attr', t.value), + 'greaterThanEqual("attr", ${t.expectedValues})', + ); + }); + } + }); + }); + + group('search()', () { + test('returns search', () { + expect(Query.search('attr', 'keyword1 keyword2'), 'search("attr", ["keyword1 keyword2"])'); + }); + }); + + group('isNull()', () { + test('returns isNull', () { + expect(Query.isNull('attr'), 'isNull("attr")'); + }); + }); + + group('isNotNull()', () { + test('returns isNotNull', () { + expect(Query.isNotNull('attr'), 'isNotNull("attr")'); + }); + }); + + group('between()', () { + test('with integers', () { + expect(Query.between('attr', 1, 2), 'between("attr", [1,2])'); + }); + + test('with doubles', () { + expect(Query.between('attr', 1.0, 2.0), 'between("attr", [1.0,2.0])'); + }); + + test('with strings', () { + expect(Query.between('attr', "a", "z"), 'between("attr", ["a","z"])'); + }); + }); + + group('select()', () { + test('returns select', () { + expect(Query.select(['attr1', 'attr2']), 'select(["attr1","attr2"])'); + }); + }); + + group('orderAsc()', () { + test('returns orderAsc', () { + expect(Query.orderAsc('attr'), 'orderAsc("attr")'); + }); + }); + + group('orderDesc()', () { + test('returns orderDesc', () { + expect(Query.orderDesc('attr'), 'orderDesc("attr")'); + }); + }); + + group('cursorBefore()', () { + test('returns cursorBefore', () { + expect(Query.cursorBefore(ID.custom('custom')), 'cursorBefore("custom")'); + }); + }); + + group('cursorAfter()', () { + test('returns cursorAfter', () { + expect(Query.cursorAfter(ID.custom('custom')), 'cursorAfter("custom")'); + }); + }); + + group('limit()', () { + test('returns limit', () { + expect(Query.limit(1), 'limit(1)'); + }); + }); + + group('offset()', () { + test('returns offset', () { + expect(Query.offset(1), 'offset(1)'); + }); + }); +} + diff --git a/templates/dart/test/role_test.dart.twig b/templates/dart/test/role_test.dart.twig new file mode 100644 index 000000000..302d5e7d0 --- /dev/null +++ b/templates/dart/test/role_test.dart.twig @@ -0,0 +1,52 @@ +import 'package:{{ language.params.packageName }}/{{ language.params.packageName }}.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group('any()', () { + test('returns any', () { + expect(Role.any(), 'any'); + }); + }); + + group('user()', () { + test('without status', () { + expect(Role.user('custom'), 'user:custom'); + }); + + test('with status', () { + expect(Role.user('custom', 'verified'), 'user:custom/verified'); + }); + }); + + group('users()', () { + test('without status', () { + expect(Role.users(), 'users'); + }); + + test('with status', () { + expect(Role.users('verified'), 'users/verified'); + }); + }); + + group('guests()', () { + test('returns guests', () { + expect(Role.guests(), 'guests'); + }); + }); + + group('team()', () { + test('without role', () { + expect(Role.team('custom'), 'team:custom'); + }); + + test('with role', () { + expect(Role.team('custom', 'owner'), 'team:custom/owner'); + }); + }); + + group('member()', () { + test('returns member', () { + expect(Role.member('custom'), 'member:custom'); + }); + }); +} diff --git a/templates/dart/test/src/enums_test.dart.twig b/templates/dart/test/src/enums_test.dart.twig new file mode 100644 index 000000000..91d1dd6b3 --- /dev/null +++ b/templates/dart/test/src/enums_test.dart.twig @@ -0,0 +1,12 @@ +import 'package:{{ language.params.packageName }}/src/enums.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group('name()', () { + for (final method in HttpMethod.values) { + test('returns ${method.toString().split('.').last.toUpperCase()} for $method', () { + expect(method.name(), method.toString().split('.').last.toUpperCase()); + }); + } + }); +} \ No newline at end of file diff --git a/templates/dart/test/src/models/model_test.dart.twig b/templates/dart/test/src/models/model_test.dart.twig new file mode 100644 index 000000000..485d26a7f --- /dev/null +++ b/templates/dart/test/src/models/model_test.dart.twig @@ -0,0 +1,26 @@ +{% macro sub_schema(property) %}{% if property.sub_schema %}{% if property.type == 'array' %}List<{{property.sub_schema | caseUcfirst | overrideIdentifier}}>{% else %}{{property.sub_schema | caseUcfirst | overrideIdentifier }}{% endif %}{% else %}{% if property.type == 'object' and property.additionalProperties %}Map{% else %}{{property | typeName}}{% endif %}{% endif %}{% endmacro %} +import 'package:{{ language.params.packageName }}/models.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group('{{ definition.name | caseUcfirst | overrideIdentifier }}', () { + + test('model', () { + final model = {{ definition.name | caseUcfirst | overrideIdentifier }}( +{% for property in definition.properties | filter(p => p.required) %} + {{ property.name | escapeKeyword }}: {% if property.type == 'array' %}[]{% elseif property.type == 'object' and (property.sub_schema == 'prefs' or property.sub_schema == 'preferences') %}Preferences(data: {}){% elseif property.type == 'object' %}{}{% elseif property.type == 'string' %}'{{property['x-example'] | escapeDollarSign}}'{% elseif property.type == 'boolean' %}true{% else %}{{property['x-example']}}{% endif %}, +{% endfor %} +{% if definition.additionalProperties %} + data: {}, +{% endif %} + ); + + final map = model.toMap(); + final result = {{ definition.name | caseUcfirst | overrideIdentifier }}.fromMap(map); + +{% for property in definition.properties | filter(p => p.required) %} + expect(result.{{ property.name | escapeKeyword }}{% if property.type == 'object' and (property.sub_schema == 'prefs' or property.sub_schema == 'preferences') %}.data{% endif %}, {% if property.type == 'array' %}[]{% elseif property.type == 'object' and (property.sub_schema == 'prefs' or property.sub_schema == 'preferences') %}{"data": {}}{% elseif property.type == 'object' %}{}{% elseif property.type == 'string' %}'{{property['x-example'] | escapeDollarSign}}'{% elseif property.type == 'boolean' %}true{% else %}{{property['x-example']}}{% endif %}); +{% endfor %} + }); + }); +} diff --git a/templates/dart/test/src/response_test.dart.twig b/templates/dart/test/src/response_test.dart.twig new file mode 100644 index 000000000..fb7ebfef4 --- /dev/null +++ b/templates/dart/test/src/response_test.dart.twig @@ -0,0 +1,18 @@ +import 'package:{{ language.params.packageName }}/src/response.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group('toString()', () { + test('with a string', () { + final response = Response(data: 'string'); + + expect(response.toString(), 'string'); + }); + + test('with a map', () { + final response = Response(data: {'x': 1}); + + expect(response.toString(), '{"x":1}'); + }); + }); +} \ No newline at end of file diff --git a/templates/flutter/test/src/cookie_manager_test.dart.twig b/templates/flutter/test/src/cookie_manager_test.dart.twig new file mode 100644 index 000000000..78df8709d --- /dev/null +++ b/templates/flutter/test/src/cookie_manager_test.dart.twig @@ -0,0 +1,99 @@ +import 'package:{{ language.params.packageName }}/src/cookie_manager.dart'; +import 'package:cookie_jar/cookie_jar.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:http/http.dart'; + +void main() { + group('getCookies()', () { + test('conversion', () { + List cookies = [ + Cookie('name', 'value'), + Cookie('name2', 'value2'), + ]; + + expect( + CookieManager.getCookies(cookies), + "name=value; name2=value2", + ); + }); + }); + + group('onRequest()', () { + late CookieJar cookieJar; + late CookieManager cookieManager; + + setUp(() { + cookieJar = CookieJar(); + cookieManager = CookieManager(cookieJar); + }); + + test('without cookie', () async { + final request = Request('GET', Uri.parse('{{sdk.url}}')); + await cookieManager.onRequest(request); + expect(request.headers, {}); + }); + + test('with cookie', () async { + final uri = Uri.parse('{{sdk.url}}'); + final cookies = [ + Cookie('name', 'value'), + Cookie('name2', 'value2'), + ]; + cookieJar.saveFromResponse(uri, cookies); + + final request = Request('GET', uri); + await cookieManager.onRequest(request); + expect(request.headers, { + 'cookie': 'name=value; name2=value2' + }); + }); + }); + + group('onResponse()', () { + late CookieJar cookieJar; + late CookieManager cookieManager; + + setUp(() { + cookieJar = CookieJar(); + cookieManager = CookieManager(cookieJar); + }); + + test('without cookie', () async { + final uri = Uri.parse('{{sdk.url}}'); + final request = Request('POST', uri); + final response = Response( + 'body', + 200, + headers: {}, + request: request, + ); + + await cookieManager.onResponse(response); + + final cookies = await cookieJar.loadForRequest(uri); + + expect(cookies, []); + }); + + test('with cookie', () async { + final uri = Uri.parse('{{sdk.url}}'); + final request = Request('POST', uri); + final response = Response( + 'body', + 200, + headers: { + 'set-cookie': 'name=value' + }, + request: request, + ); + + await cookieManager.onResponse(response); + + final cookies = await cookieJar.loadForRequest(uri); + + expect(cookies.length, 1); + expect(cookies.first.name, 'name'); + expect(cookies.first.value, 'value'); + }); + }); +} \ No newline at end of file