| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import 'package:engine_tool/src/typed_json.dart'; |
| import 'package:litetest/litetest.dart'; |
| |
| void main() { |
| group('JsonObject.string', () { |
| test('returns string value', () { |
| const JsonObject jsonObject = JsonObject(<String, Object?>{'key': 'value'}); |
| expect(jsonObject.string('key'), 'value'); |
| }); |
| |
| test('throws due to missing key', () { |
| const JsonObject jsonObject = JsonObject(<String, Object?>{'key': 'value'}); |
| expect(() => jsonObject.string('missing'), throwsA(isInstanceOf<MissingKeyJsonReadException>())); |
| }); |
| |
| test('throws due to wrong type', () { |
| const JsonObject jsonObject = JsonObject(<String, Object?>{'key': 42}); |
| expect(() => jsonObject.string('key'), throwsA(isInstanceOf<InvalidTypeJsonReadException>())); |
| }); |
| }); |
| |
| group('JsonObject.integer', () { |
| test('returns integer value', () { |
| const JsonObject jsonObject = JsonObject(<String, Object?>{'key': 42}); |
| expect(jsonObject.integer('key'), 42); |
| }); |
| |
| test('throws due to missing key', () { |
| const JsonObject jsonObject = JsonObject(<String, Object?>{'key': 42}); |
| expect(() => jsonObject.integer('missing'), throwsA(isInstanceOf<MissingKeyJsonReadException>())); |
| }); |
| |
| test('throws due to wrong type', () { |
| const JsonObject jsonObject = JsonObject(<String, Object?>{'key': 'value'}); |
| expect(() => jsonObject.integer('key'), throwsA(isInstanceOf<InvalidTypeJsonReadException>())); |
| }); |
| }); |
| |
| group('JsonObject.boolean', () { |
| test('returns boolean value', () { |
| const JsonObject jsonObject = JsonObject(<String, Object?>{'key': true}); |
| expect(jsonObject.boolean('key'), true); |
| }); |
| |
| test('throws due to missing key', () { |
| const JsonObject jsonObject = JsonObject(<String, Object?>{'key': true}); |
| expect(() => jsonObject.boolean('missing'), throwsA(isInstanceOf<MissingKeyJsonReadException>())); |
| }); |
| |
| test('throws due to wrong type', () { |
| const JsonObject jsonObject = JsonObject(<String, Object?>{'key': 'value'}); |
| expect(() => jsonObject.boolean('key'), throwsA(isInstanceOf<InvalidTypeJsonReadException>())); |
| }); |
| }); |
| |
| group('JsonObject.stringList', () { |
| test('returns string list value', () { |
| const JsonObject jsonObject = JsonObject(<String, Object?>{'key': <Object?>['value1', 'value2']}); |
| expect(jsonObject.stringList('key'), <String>['value1', 'value2']); |
| }); |
| |
| test('throws due to missing key', () { |
| const JsonObject jsonObject = JsonObject(<String, Object?>{'key': <Object?>['value1', 'value2']}); |
| expect(() => jsonObject.stringList('missing'), throwsA(isInstanceOf<MissingKeyJsonReadException>())); |
| }); |
| |
| test('throws due to wrong type', () { |
| const JsonObject jsonObject = JsonObject(<String, Object?>{'key': 'value'}); |
| expect(() => jsonObject.stringList('key'), throwsA(isInstanceOf<InvalidTypeJsonReadException>())); |
| }); |
| |
| test('throws due to wrong element type', () { |
| const JsonObject jsonObject = JsonObject(<String, Object?>{'key': <Object?>['value1', 42]}); |
| expect(() => jsonObject.stringList('key'), throwsA(isInstanceOf<InvalidTypeJsonReadException>())); |
| }); |
| }); |
| |
| group('JsonObject.stringOrNull', () { |
| test('returns string value', () { |
| const JsonObject jsonObject = JsonObject(<String, Object?>{'key': 'value'}); |
| expect(jsonObject.stringOrNull('key'), 'value'); |
| }); |
| |
| test('returns null due to missing key', () { |
| const JsonObject jsonObject = JsonObject(<String, Object?>{'key': 'value'}); |
| expect(jsonObject.stringOrNull('missing'), isNull); |
| }); |
| |
| test('throws due to wrong type', () { |
| const JsonObject jsonObject = JsonObject(<String, Object?>{'key': 42}); |
| expect(() => jsonObject.stringOrNull('key'), throwsA(isInstanceOf<InvalidTypeJsonReadException>())); |
| }); |
| }); |
| |
| group('JsonObject.integerOrNull', () { |
| test('returns integer value', () { |
| const JsonObject jsonObject = JsonObject(<String, Object?>{'key': 42}); |
| expect(jsonObject.integerOrNull('key'), 42); |
| }); |
| |
| test('returns null due to missing key', () { |
| const JsonObject jsonObject = JsonObject(<String, Object?>{'key': 42}); |
| expect(jsonObject.integerOrNull('missing'), isNull); |
| }); |
| |
| test('throws due to wrong type', () { |
| const JsonObject jsonObject = JsonObject(<String, Object?>{'key': 'value'}); |
| expect(() => jsonObject.integerOrNull('key'), throwsA(isInstanceOf<InvalidTypeJsonReadException>())); |
| }); |
| }); |
| |
| group('JsonObject.booleanOrNull', () { |
| test('returns boolean value', () { |
| const JsonObject jsonObject = JsonObject(<String, Object?>{'key': true}); |
| expect(jsonObject.booleanOrNull('key'), true); |
| }); |
| |
| test('returns null due to missing key', () { |
| const JsonObject jsonObject = JsonObject(<String, Object?>{'key': true}); |
| expect(jsonObject.booleanOrNull('missing'), isNull); |
| }); |
| |
| test('throws due to wrong type', () { |
| const JsonObject jsonObject = JsonObject(<String, Object?>{'key': 'value'}); |
| expect(() => jsonObject.booleanOrNull('key'), throwsA(isInstanceOf<InvalidTypeJsonReadException>())); |
| }); |
| }); |
| |
| group('JsonObject.stringListOrNull', () { |
| test('returns string list value', () { |
| const JsonObject jsonObject = JsonObject(<String, Object?>{'key': <Object?>['value1', 'value2']}); |
| expect(jsonObject.stringListOrNull('key'), <String>['value1', 'value2']); |
| }); |
| |
| test('returns null due to missing key', () { |
| const JsonObject jsonObject = JsonObject(<String, Object?>{'key': <Object?>['value1', 'value2']}); |
| expect(jsonObject.stringListOrNull('missing'), isNull); |
| }); |
| |
| test('throws due to wrong type', () { |
| const JsonObject jsonObject = JsonObject(<String, Object?>{'key': 'value'}); |
| expect(() => jsonObject.stringListOrNull('key'), throwsA(isInstanceOf<InvalidTypeJsonReadException>())); |
| }); |
| |
| test('throws due to wrong element type', () { |
| const JsonObject jsonObject = JsonObject(<String, Object?>{'key': <Object?>['value1', 42]}); |
| expect(() => jsonObject.stringListOrNull('key'), throwsA(isInstanceOf<InvalidTypeJsonReadException>())); |
| }); |
| }); |
| |
| group('JsonObject.map', () { |
| test('returns multiple fields', () { |
| final (String name, int age, bool isStudent) = const JsonObject(<String, Object?>{ |
| 'name': 'Alice', |
| 'age': 42, |
| 'isStudent': true, |
| }).map((JsonObject json) { |
| return ( |
| json.string('name'), |
| json.integer('age'), |
| json.boolean('isStudent'), |
| ); |
| }); |
| |
| expect(name, 'Alice'); |
| expect(age, 42); |
| expect(isStudent, true); |
| }); |
| |
| test('throws due to missing keys', () { |
| try { |
| const JsonObject(<String, Object?>{ |
| 'age': 42, |
| }).map((JsonObject json) { |
| return ( |
| json.string('name'), |
| json.integer('age'), |
| json.boolean('isStudent'), |
| ); |
| }); |
| fail('Expected JsonMapException'); |
| } on JsonMapException catch (e) { |
| expect( |
| e.exceptions.map((JsonReadException e) => (e as MissingKeyJsonReadException).key).toList(), |
| containsStringsInOrder(<String>['name', 'isStudent'], |
| )); |
| } |
| }); |
| |
| test('throws due to wrong types', () { |
| try { |
| const JsonObject(<String, Object?>{ |
| 'name': 42, |
| 'age': '42', |
| 'isStudent': false, |
| }).map((JsonObject json) { |
| return ( |
| json.string('name'), |
| json.integer('age'), |
| json.boolean('isStudent'), |
| ); |
| }); |
| fail('Expected JsonMapException'); |
| } on JsonMapException catch (e) { |
| expect( |
| e.exceptions.map((JsonReadException e) => switch (e) { |
| final InvalidTypeJsonReadException e => e.key, |
| final MissingKeyJsonReadException e => e.key, |
| _ => throw StateError('Unexpected exception type: $e'), |
| }).toList(), |
| containsStringsInOrder(<String>['name', 'age'], |
| )); |
| } |
| }); |
| |
| test('allows a default with onError', () { |
| final (String name, int age, bool isStudent) = const JsonObject(<String, Object?>{ |
| 'name': 'Alice', |
| 'age': 42, |
| 'isStudent': 'true', |
| }).map((JsonObject json) { |
| return ( |
| json.string('name'), |
| json.integer('age'), |
| json.boolean('isStudent'), |
| ); |
| }, onError: expectAsync2((_, JsonMapException e) { |
| expect( |
| e.exceptions.map((JsonReadException e) => switch (e) { |
| final InvalidTypeJsonReadException e => e.key, |
| final MissingKeyJsonReadException e => e.key, |
| _ => throw StateError('Unexpected exception type: $e'), |
| }).toList(), |
| <String>['isStudent'], |
| ); |
| return ('Bob', 0, false); |
| })); |
| |
| expect(name, 'Bob'); |
| expect(age, 0); |
| expect(isStudent, false); |
| }); |
| |
| test('disallows a return type of Future<*>', () { |
| expect(() { |
| const JsonObject(<String, Object?>{ |
| 'name': 'Alice', |
| 'age': 42, |
| 'isStudent': true, |
| }).map((JsonObject json) async { |
| return ( |
| json.string('name'), |
| json.integer('age'), |
| json.boolean('isStudent'), |
| ); |
| }); |
| }, throwsA(isInstanceOf<ArgumentError>())); |
| }); |
| }); |
| } |