| #!/usr/bin/env dart |
| // Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| library map_test; |
| |
| import 'package:test/test.dart' |
| show test, expect, predicate, same, throwsA, throwsArgumentError; |
| |
| import '../out/protos/map_api.pb.dart' as pb; |
| import '../out/protos/map_api2.pb.dart' as pb2; |
| |
| throwsError(Type expectedType, String expectedMessage) => |
| throwsA(predicate((x) { |
| expect(x.runtimeType, expectedType); |
| expect(x.message, expectedMessage); |
| return true; |
| })); |
| |
| void main() { |
| test("message doesn't implement Map when turned off", () { |
| expect(pb.NonMap(), predicate((x) => x is! Map)); |
| expect(pb2.NonMap2(), predicate((x) => x is! Map)); |
| }); |
| |
| test("message implements Map when turned on", () { |
| expect(pb.Rec(), predicate((x) => x is Map)); |
| expect(pb2.Rec2(), predicate((x) => x is Map)); |
| }); |
| |
| test('operator [] returns null for unrecognized keys', () { |
| var rec = pb.Rec(); |
| expect(rec["noSuchField"], null); |
| expect(rec[1234], null); |
| expect(rec[null], null); |
| }); |
| |
| test('operator [] returns default value when not set', () { |
| var rec = pb.Rec(); |
| expect(rec["num"], 0); |
| expect(rec["nums"], []); |
| expect(rec["str"], ""); |
| expect(rec["msg"], predicate((x) => x is pb.NonMap)); |
| }); |
| |
| test('operator [] returns new value when set', () { |
| var rec = pb.Rec(); |
| rec.num = 42; |
| expect(rec["num"], 42); |
| rec.nums.add(123); |
| expect(rec["nums"], [123]); |
| rec.str = "hello"; |
| expect(rec["str"], "hello"); |
| var msg = pb.NonMap(); |
| rec.msg = msg; |
| expect(rec["msg"], same(msg)); |
| }); |
| |
| test('operator []= throws exception for invalid key', () { |
| var rec = pb.Rec(); |
| expect(() { |
| rec["unknown"] = 123; |
| }, |
| throwsError(ArgumentError, |
| "field 'unknown' not found in protobuf_unittest.Rec")); |
| }); |
| |
| test('operator []= throws exception for repeated field', () { |
| // Copying the values would be confusing. |
| var rec = pb.Rec(); |
| expect(() { |
| rec["nums"] = [1, 2]; |
| }, throwsArgumentError); |
| }); |
| |
| test('operator []= throws exception for invalid value type', () { |
| var rec = pb.Rec(); |
| expect(() { |
| rec["num"] = "hello"; |
| }, throwsArgumentError); |
| expect(() { |
| rec["str"] = 123; |
| }, throwsArgumentError); |
| }); |
| |
| test('operator []= sets the field', () { |
| var rec = pb.Rec(); |
| rec["num"] = 123; |
| expect(rec.num, 123); |
| rec["str"] = "hello"; |
| expect(rec.str, "hello"); |
| }); |
| |
| test('keys returns each field name (even when unset)', () { |
| var rec = pb.Rec(); |
| expect(Set.from(rec.keys), Set.from(["msg", "num", "nums", "str"])); |
| }); |
| |
| test('containsKey returns true for fields that exist (even when unset)', () { |
| var rec = pb.Rec(); |
| expect(rec.containsKey("unknown"), false); |
| expect(rec.containsKey("str"), true); |
| expect(rec.containsKey("num"), true); |
| expect(rec.containsKey("nums"), true); |
| expect(rec.containsKey("msg"), true); |
| }); |
| |
| test('length is constant', () { |
| var rec = pb.Rec(); |
| expect(rec.length, 4); |
| rec.str = "hello"; |
| expect(rec.length, 4); |
| }); |
| |
| test("remove isn't supported", () { |
| var rec = pb.Rec(); |
| rec.str = "hello"; |
| expect(() { |
| rec.remove("str"); |
| }, |
| throwsError(UnsupportedError, |
| "remove() not supported by protobuf_unittest.Rec")); |
| expect(rec.str, "hello"); |
| }); |
| |
| test("clear sets each field to its default value (unlike a regular Map)", () { |
| // We have little choice here since the clear() method already existed. |
| var rec = pb.Rec(); |
| rec.str = "hello"; |
| rec.num = 123; |
| rec.nums.add(456); |
| rec.clear(); |
| expect(rec.length, 4); |
| expect(rec["str"], ""); |
| expect(rec["num"], 0); |
| expect(rec["nums"], []); |
| }); |
| |
| test("addAll sets each field to a new value", () { |
| var rec = pb.Rec(); |
| rec.addAll({"str": "hello", "num": 123}); |
| expect(rec["str"], "hello"); |
| expect(rec["num"], 123); |
| }); |
| |
| test("addAll doesn't work for repeated fields", () { |
| // It would be confusing to copy the values. |
| var rec = pb.Rec(); |
| expect(() { |
| rec.addAll({ |
| "nums": [1, 2, 3] |
| }); |
| }, throwsArgumentError); |
| }); |
| } |