blob: 96d1fc787aea785082951b3c3179b65a6c4eb5cf [file] [log] [blame]
#!/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);
});
}