blob: efc3bf71171950fd7abc24df1a6c289e675f5cb6 [file] [log] [blame]
// Copyright 2014 The Chromium 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 'dart:async';
import 'dart:isolate';
import 'dart:typed_data';
import 'dart:convert';
import 'package:mojo/bindings.dart' as bindings;
import 'package:mojo/core.dart' as core;
import 'package:mojo/mojo/bindings/types/mojom_types.mojom.dart' as mojom_types;
import 'package:mojo/mojo/bindings/types/service_describer.mojom.dart'
as service_describer;
import 'package:_mojo_for_test_only/expect.dart';
import 'package:_mojo_for_test_only/mojo/test/rect.mojom.dart' as rect;
import 'package:_mojo_for_test_only/mojo/test/serialization_test_structs.mojom.dart'
as serialization;
import 'package:_mojo_for_test_only/mojo/test/test_enums.mojom.dart'
as enums;
import 'package:_mojo_for_test_only/mojo/test/test_structs.mojom.dart'
as structs;
import 'package:_mojo_for_test_only/mojo/test/test_unions.mojom.dart'
as unions;
import 'package:_mojo_for_test_only/mojo/test/validation_test_interfaces.mojom.dart'
as validation;
import 'package:_mojo_for_test_only/regression_tests/regression_tests.mojom.dart'
as regression;
import 'package:_mojo_for_test_only/sample/sample_interfaces.mojom.dart'
as sample;
class ProviderImpl implements sample.Provider {
sample.ProviderStub _stub;
ProviderImpl(core.MojoMessagePipeEndpoint endpoint) {
_stub = new sample.ProviderStub.fromEndpoint(endpoint, this);
}
echoString(String a, Function responseFactory) =>
new Future.value(responseFactory(a));
echoStrings(String a, String b, Function responseFactory) =>
new Future.value(responseFactory(a, b));
echoMessagePipeHandle(core.MojoHandle a, Function responseFactory) =>
new Future.value(responseFactory(a));
echoEnum(sample.Enum a, Function responseFactory) =>
new Future.value(responseFactory(a));
}
void providerIsolate(core.MojoMessagePipeEndpoint endpoint) {
new ProviderImpl(endpoint);
}
Future<bool> testCallResponse() {
var pipe = new core.MojoMessagePipe();
var client = new sample.ProviderProxy.fromEndpoint(pipe.endpoints[0]);
var c = new Completer();
Isolate.spawn(providerIsolate, pipe.endpoints[1]).then((_) {
client.ptr.echoString("hello!").then((echoStringResponse) {
Expect.equals("hello!", echoStringResponse.a);
}).then((_) {
client.ptr.echoStrings("hello", "mojo!").then((echoStringsResponse) {
Expect.equals("hello", echoStringsResponse.a);
Expect.equals("mojo!", echoStringsResponse.b);
client.close().then((_) {
c.complete(true);
});
});
});
});
return c.future;
}
Future testAwaitCallResponse() async {
var pipe = new core.MojoMessagePipe();
var client = new sample.ProviderProxy.fromEndpoint(pipe.endpoints[0]);
var isolate = await Isolate.spawn(providerIsolate, pipe.endpoints[1]);
var echoStringResponse = await client.ptr.echoString("hello!");
Expect.equals("hello!", echoStringResponse.a);
var echoStringsResponse = await client.ptr.echoStrings("hello", "mojo!");
Expect.equals("hello", echoStringsResponse.a);
Expect.equals("mojo!", echoStringsResponse.b);
await client.close();
}
bindings.ServiceMessage messageOfStruct(bindings.Struct s) =>
s.serializeWithHeader(new bindings.MessageHeader(0));
testSerializeNamedRegion() {
var r = new rect.Rect()
..x = 1
..y = 2
..width = 3
..height = 4;
var namedRegion = new structs.NamedRegion()
..name = "name"
..rects = [r];
var message = messageOfStruct(namedRegion);
var namedRegion2 = structs.NamedRegion.deserialize(message.payload);
Expect.equals(namedRegion.name, namedRegion2.name);
}
testSerializeArrayValueTypes() {
var arrayValues = new structs.ArrayValueTypes()
..f0 = [0, 1, -1, 0x7f, -0x10]
..f1 = [0, 1, -1, 0x7fff, -0x1000]
..f2 = [0, 1, -1, 0x7fffffff, -0x10000000]
..f3 = [0, 1, -1, 0x7fffffffffffffff, -0x1000000000000000]
..f4 = [0.0, 1.0, -1.0, 4.0e9, -4.0e9]
..f5 = [0.0, 1.0, -1.0, 4.0e9, -4.0e9];
var message = messageOfStruct(arrayValues);
var arrayValues2 = structs.ArrayValueTypes.deserialize(message.payload);
Expect.listEquals(arrayValues.f0, arrayValues2.f0);
Expect.listEquals(arrayValues.f1, arrayValues2.f1);
Expect.listEquals(arrayValues.f2, arrayValues2.f2);
Expect.listEquals(arrayValues.f3, arrayValues2.f3);
Expect.listEquals(arrayValues.f4, arrayValues2.f4);
Expect.listEquals(arrayValues.f5, arrayValues2.f5);
}
testSerializeToJSON() {
var r = new rect.Rect()
..x = 1
..y = 2
..width = 3
..height = 4;
var encodedRect = JSON.encode(r);
var goldenEncoding = "{\"x\":1,\"y\":2,\"width\":3,\"height\":4}";
Expect.equals(goldenEncoding, encodedRect);
}
testSerializeHandleToJSON() {
var s = new serialization.Struct2();
Expect.throws(
() => JSON.encode(s), (e) => e.cause is bindings.MojoCodecError);
}
testSerializeKeywordStruct() {
var keywordStruct = new structs.DartKeywordStruct()
..await_ = structs.DartKeywordStructKeywords.await_
..is_ = structs.DartKeywordStructKeywords.is_
..rethrow_ = structs.DartKeywordStructKeywords.rethrow_;
var message = messageOfStruct(keywordStruct);
var decodedStruct = structs.DartKeywordStruct.deserialize(message.payload);
Expect.equals(keywordStruct.await_, decodedStruct.await_);
Expect.equals(keywordStruct.is_, decodedStruct.is_);
Expect.equals(keywordStruct.rethrow_, decodedStruct.rethrow_);
}
testSerializeStructs() {
testSerializeNamedRegion();
testSerializeArrayValueTypes();
testSerializeToJSON();
testSerializeHandleToJSON();
testSerializeKeywordStruct();
}
testSerializePodUnions() {
var s = new unions.WrapperStruct()..podUnion = new unions.PodUnion();
s.podUnion.fUint32 = 32;
Expect.equals(unions.PodUnionTag.fUint32, s.podUnion.tag);
Expect.equals(32, s.podUnion.fUint32);
var message = messageOfStruct(s);
var s2 = unions.WrapperStruct.deserialize(message.payload);
Expect.equals(s.podUnion.fUint32, s2.podUnion.fUint32);
}
testSerializeStructInUnion() {
var s = new unions.WrapperStruct()..objectUnion = new unions.ObjectUnion();
s.objectUnion.fDummy = new unions.DummyStruct()..fInt8 = 8;
var message = messageOfStruct(s);
var s2 = unions.WrapperStruct.deserialize(message.payload);
Expect.equals(s.objectUnion.fDummy.fInt8, s2.objectUnion.fDummy.fInt8);
}
testSerializeArrayInUnion() {
var s = new unions.WrapperStruct()..objectUnion = new unions.ObjectUnion();
s.objectUnion.fArrayInt8 = [1, 2, 3];
var message = messageOfStruct(s);
var s2 = unions.WrapperStruct.deserialize(message.payload);
Expect.listEquals(s.objectUnion.fArrayInt8, s2.objectUnion.fArrayInt8);
}
testSerializeMapInUnion() {
var s = new unions.WrapperStruct()..objectUnion = new unions.ObjectUnion();
s.objectUnion.fMapInt8 = {"one": 1, "two": 2,};
var message = messageOfStruct(s);
var s2 = unions.WrapperStruct.deserialize(message.payload);
Expect.equals(1, s.objectUnion.fMapInt8["one"]);
Expect.equals(2, s.objectUnion.fMapInt8["two"]);
}
testSerializeUnionInArray() {
var s = new unions.SmallStruct()
..podUnionArray = [
new unions.PodUnion()..fUint16 = 16,
new unions.PodUnion()..fUint32 = 32,
];
var message = messageOfStruct(s);
var s2 = unions.SmallStruct.deserialize(message.payload);
Expect.equals(16, s2.podUnionArray[0].fUint16);
Expect.equals(32, s2.podUnionArray[1].fUint32);
}
testSerializeUnionInMap() {
var s = new unions.SmallStruct()
..podUnionMap = {
'one': new unions.PodUnion()..fUint16 = 16,
'two': new unions.PodUnion()..fUint32 = 32,
};
var message = messageOfStruct(s);
var s2 = unions.SmallStruct.deserialize(message.payload);
Expect.equals(16, s2.podUnionMap['one'].fUint16);
Expect.equals(32, s2.podUnionMap['two'].fUint32);
}
testSerializeUnionInUnion() {
var s = new unions.WrapperStruct()..objectUnion = new unions.ObjectUnion();
s.objectUnion.fPodUnion = new unions.PodUnion()..fUint32 = 32;
var message = messageOfStruct(s);
var s2 = unions.WrapperStruct.deserialize(message.payload);
Expect.equals(32, s2.objectUnion.fPodUnion.fUint32);
}
testUnionsToString() {
var podUnion = new unions.PodUnion();
podUnion.fUint32 = 32;
Expect.equals("PodUnion(fUint32: 32)", podUnion.toString());
}
testUnions() {
testSerializePodUnions();
testSerializeStructInUnion();
testSerializeArrayInUnion();
testSerializeMapInUnion();
testSerializeUnionInArray();
testSerializeUnionInMap();
testSerializeUnionInUnion();
testUnionsToString();
}
class CheckEnumCapsImpl implements regression.CheckEnumCaps {
regression.CheckEnumCapsStub _stub;
CheckEnumCapsImpl(core.MojoMessagePipeEndpoint endpoint) {
_stub = new regression.CheckEnumCapsStub.fromEndpoint(endpoint, this);
}
setEnumWithInternalAllCaps(regression.EnumWithInternalAllCaps e) {}
}
checkEnumCapsIsolate(core.MojoMessagePipeEndpoint endpoint) {
new CheckEnumCapsImpl(endpoint);
}
testCheckEnumCapsImpl() {
var pipe = new core.MojoMessagePipe();
var client =
new regression.CheckEnumCapsProxy.fromEndpoint(pipe.endpoints[0]);
var c = new Completer();
Isolate.spawn(checkEnumCapsIsolate, pipe.endpoints[1]).then((_) {
client.ptr.setEnumWithInternalAllCaps(
regression.EnumWithInternalAllCaps.standard);
client.close().then((_) {
c.complete(null);
});
});
return c.future;
}
testSerializeEnum() {
var constants = new structs.ScopedConstants();
constants.f4 = structs.ScopedConstantsEType.e0;
var message = messageOfStruct(constants);
var constants2 = structs.ScopedConstants.deserialize(message.payload);
Expect.equals(constants.f4, constants2.f4);
}
void testEnumShadowing() {
var v = new enums.TestEnum(1);
Expect.equals(enums.TestEnum.v, v);
}
testEnums() async {
testSerializeEnum();
await testCheckEnumCapsImpl();
testEnumShadowing();
}
void closingProviderIsolate(core.MojoMessagePipeEndpoint endpoint) {
var provider = new ProviderImpl(endpoint);
provider._stub.close();
}
Future<bool> runOnClosedTest() {
var testCompleter = new Completer();
var pipe = new core.MojoMessagePipe();
var proxy = new sample.ProviderProxy.fromEndpoint(pipe.endpoints[0]);
proxy.impl.onError = (_) => testCompleter.complete(true);
Isolate.spawn(closingProviderIsolate, pipe.endpoints[1]);
return testCompleter.future.then((b) {
Expect.isTrue(b);
});
}
class Regression551Impl implements regression.Regression551 {
regression.Regression551Stub _stub;
Regression551Impl(core.MojoMessagePipeEndpoint endpoint) {
_stub = new regression.Regression551Stub.fromEndpoint(endpoint, this);
}
dynamic get(List<String> keyPrefixes, Function responseFactory) =>
responseFactory(0);
}
void regression551Isolate(core.MojoMessagePipeEndpoint endpoint) {
new Regression551Impl(endpoint);
}
Future<bool> testRegression551() {
var pipe = new core.MojoMessagePipe();
var client = new regression.Regression551Proxy.fromEndpoint(pipe.endpoints[0]);
var c = new Completer();
Isolate.spawn(regression551Isolate, pipe.endpoints[1]).then((_) {
client.ptr.get(["hello!"]).then((response) {
Expect.equals(0, response.result);
client.close().then((_) {
c.complete(true);
});
});
});
return c.future;
}
class ServiceNameImpl implements regression.ServiceName {
regression.ServiceNameStub _stub;
ServiceNameImpl(core.MojoMessagePipeEndpoint endpoint) {
_stub = new regression.ServiceNameStub.fromEndpoint(endpoint, this);
}
dynamic serviceName_(Function responseFactory) =>
responseFactory(regression.ServiceName.serviceName);
}
void serviceNameIsolate(core.MojoMessagePipeEndpoint endpoint) {
new ServiceNameImpl(endpoint);
}
Future<bool> testServiceName() {
var pipe = new core.MojoMessagePipe();
var client = new regression.ServiceNameProxy.fromEndpoint(pipe.endpoints[0]);
var c = new Completer();
Isolate.spawn(serviceNameIsolate, pipe.endpoints[1]).then((_) {
client.ptr.serviceName_().then((response) {
Expect.equals(ServiceName.serviceName, response.serviceName_);
client.close().then((_) {
c.complete(true);
});
});
});
return c.future;
}
testCamelCase() {
var e = regression.CamelCaseTestEnum.boolThing;
e = regression.CamelCaseTestEnum.doubleThing;
e = regression.CamelCaseTestEnum.floatThing;
e = regression.CamelCaseTestEnum.int8Thing;
e = regression.CamelCaseTestEnum.int16Thing;
e = regression.CamelCaseTestEnum.int32Th1Ng;
e = regression.CamelCaseTestEnum.int64Th1ng;
e = regression.CamelCaseTestEnum.uint8TH1ng;
e = regression.CamelCaseTestEnum.uint16tH1Ng;
e = regression.CamelCaseTestEnum.uint32Th1ng;
e = regression.CamelCaseTestEnum.uint64Th1Ng;
}
testValidateMojomTypes() {
testValidateEnumType();
testValidateStructType();
testValidateUnionType();
testValidateTestStructWithImportType();
testValidateInterfaceType();
}
// computeTypeKey encapsulates the algorithm for computing the type key
// of a type given its fully-qualified name.
//
// TODO(rudominer) Delete this when we add accessors for Mojom types
// in the Dart bindings.
String computeTypeKey(String fullyQualifiedName) {
return "TYPE_KEY:" + fullyQualifiedName;
}
// Test that mojom type descriptors were generated correctly for validation's
// BasicEnum.
testValidateEnumType() {
var testValidationDescriptor = validation.getAllMojomTypeDefinitions();
String shortName = "BasicEnum";
String fullIdentifier = "mojo.test.BasicEnum";
String enumID = computeTypeKey(fullIdentifier);
Map<String, int> labelMap = <String, int>{
"A": 0,
"B": 1,
"C": 0,
"D": -3,
"E": 0xA,
};
// Extract the UserDefinedType from the descriptor using enumID.
mojom_types.UserDefinedType udt = testValidationDescriptor[enumID];
Expect.isNotNull(udt);
// The enumType must be present and declared properly.
mojom_types.MojomEnum me = udt.enumType;
Expect.isNotNull(me);
Expect.isNotNull(me.declData);
Expect.equals(me.declData.shortName, shortName);
Expect.equals(me.declData.fullIdentifier, fullIdentifier);
// Now compare the labels to verify that the enum labels match the expected
// ones.
Expect.equals(me.values.length, labelMap.length);
me.values.forEach((mojom_types.EnumValue ev) {
// Check that the declData is correct...
Expect.isNotNull(ev.declData);
Expect.isNotNull(labelMap[ev.declData.shortName]);
// Check that the enum value's intValue is as expected.
Expect.equals(ev.intValue, labelMap[ev.declData.shortName]);
});
}
// Test that mojom type descriptors were generated correctly for validation's
// StructE.
testValidateStructType() {
var testValidationDescriptor = validation.getAllMojomTypeDefinitions();
String shortName = "StructE";
String fullIdentifier = "mojo.test.StructE";
String structID = computeTypeKey(fullIdentifier);
Map<int, String> expectedFields = <int, String>{
0: "struct_d",
1: "data_pipe_consumer",
};
// Extract the UserDefinedType from the descriptor using structID.
mojom_types.UserDefinedType udt = testValidationDescriptor[structID];
Expect.isNotNull(udt);
// The structType must be present and declared properly.
mojom_types.MojomStruct ms = udt.structType;
Expect.isNotNull(ms);
Expect.isNotNull(ms.declData);
Expect.equals(ms.declData.shortName, shortName);
Expect.equals(ms.declData.fullIdentifier, fullIdentifier);
// Now compare the fields to verify that the struct fields match the expected
// ones.
Expect.equals(ms.fields.length, expectedFields.length);
int i = 0;
ms.fields.forEach((mojom_types.StructField field) {
// Check that the declData is correct...
Expect.isNotNull(field.declData);
Expect.equals(expectedFields[i], field.declData.shortName);
// Special case each field since we already know what should be inside.
switch (i) {
case 0: // This is a TypeReference to StructD.
mojom_types.Type t = field.type;
Expect.isNotNull(t.typeReference);
// Type key, identifier, and expected reference id should match up.
mojom_types.TypeReference tr = t.typeReference;
String expectedRefID = computeTypeKey("mojo.test.StructD");
Expect.equals("StructD", tr.identifier);
Expect.equals(expectedRefID, tr.typeKey);
break;
case 1: // This is a non-nullable DataPipeConsumer HandleType.
mojom_types.Type t = field.type;
Expect.isNotNull(t.handleType);
mojom_types.HandleType ht = t.handleType;
Expect.isFalse(ht.nullable);
Expect.equals(mojom_types.HandleTypeKind.dataPipeConsumer, ht.kind);
break;
default:
assert(false);
}
i++;
});
}
// Test that mojom type descriptors were generated correctly for validation's
// UnionB.
testValidateUnionType() {
var testValidationDescriptor = validation.getAllMojomTypeDefinitions();
String shortName = "UnionB";
String fullIdentifier = "mojo.test.UnionB";
String unionID = computeTypeKey(fullIdentifier);
Map<int, String> expectedFields = <int, String>{
0: "a",
1: "b",
2: "c",
3: "d",
};
// Extract the UserDefinedType from the descriptor using unionID.
mojom_types.UserDefinedType udt = testValidationDescriptor[unionID];
Expect.isNotNull(udt);
// The unionType must be present and declared properly.
mojom_types.MojomUnion mu = udt.unionType;
Expect.isNotNull(mu);
Expect.isNotNull(mu.declData);
Expect.equals(mu.declData.shortName, shortName);
Expect.equals(mu.declData.fullIdentifier, fullIdentifier);
// Now compare the fields to verify that the union fields match the expected
// ones.
Expect.equals(mu.fields.length, expectedFields.length);
// TODO(rudominer) Currently ordinal tags in enums are not being populated by
// the Mojom parser in mojom_types.mojom so for now we must assume that
// the ordinals are in sequential order (which they are in the .mojom
// file being used for this test.)
int nextOrdinal = 0;
mu.fields.forEach((mojom_types.UnionField field) {
int ordinal = nextOrdinal;
nextOrdinal++;
// Check that the declData is correct...
Expect.isNotNull(field.declData);
Expect.equals(expectedFields[ordinal], field.declData.shortName);
// Special: It turns out that all types are simple types.
mojom_types.Type t = field.type;
Expect.isNotNull(t.simpleType);
mojom_types.SimpleType st = t.simpleType;
// Special case each field since we already know what should be inside.
switch (ordinal) {
case 0: // Uint16
Expect.equals(st, mojom_types.SimpleType.uint16);
break;
case 1: // Uint32
case 3:
Expect.equals(st, mojom_types.SimpleType.uint32);
break;
case 2: // Uint64
Expect.equals(st, mojom_types.SimpleType.uint64);
break;
default:
assert(false);
}
});
}
// Test that mojom type descriptors were generated correctly for validation's
// IncludingStruct, which contains a union imported from test_included_unions.
testValidateTestStructWithImportType() {
var testUnionsDescriptor = unions.getAllMojomTypeDefinitions();
String shortName = "IncludingStruct";
String fullIdentifier = "mojo.test.IncludingStruct";
String structID = computeTypeKey(fullIdentifier);
Map<int, String> expectedFields = <int, String>{0: "a",};
// Extract the UserDefinedType from the descriptor using structID.
mojom_types.UserDefinedType udt = testUnionsDescriptor[structID];
Expect.isNotNull(udt);
// The structType must be present and declared properly.
mojom_types.MojomStruct ms = udt.structType;
Expect.isNotNull(ms);
Expect.isNotNull(ms.declData);
Expect.equals(ms.declData.shortName, shortName);
Expect.equals(ms.declData.fullIdentifier, fullIdentifier);
// Now compare the fields to verify that the struct fields match the expected
// ones.
Expect.equals(ms.fields.length, expectedFields.length);
int i = 0;
ms.fields.forEach((mojom_types.StructField field) {
// Check that the declData is correct...
Expect.isNotNull(field.declData);
Expect.equals(expectedFields[i], field.declData.shortName);
// Special case each field since we already know what should be inside.
switch (i) {
case 0: // This is a TypeReference to a Union.
mojom_types.Type t = field.type;
Expect.isNotNull(t.typeReference);
// Type key, identifier, and expected reference id should match up.
mojom_types.TypeReference tr = t.typeReference;
String expectedRefID = computeTypeKey("mojo.test.IncludedUnion");
Expect.equals("IncludedUnion", tr.identifier);
Expect.equals(expectedRefID, tr.typeKey);
break;
default:
assert(false);
}
i++;
});
}
// Test that mojom type descriptors were generated correctly for validation's
// BoundsCheckTestInterface.
testValidateInterfaceType() {
// interface BoundsCheckTestInterface {
// Method0(uint8 param0) => (uint8 param0);
// Method1(uint8 param0);
// };
var testValidationDescriptor = validation.getAllMojomTypeDefinitions();
String shortName = "BoundsCheckTestInterface";
String fullIdentifier = "mojo.test.BoundsCheckTestInterface";
String interfaceID = computeTypeKey(fullIdentifier);
Map<int, String> methodMap = <int, String>{0: "Method0", 1: "Method1",};
mojom_types.UserDefinedType udt = testValidationDescriptor[interfaceID];
Expect.isNotNull(udt);
mojom_types.MojomInterface mi = udt.interfaceType;
Expect.isNotNull(mi);
_checkMojomInterface(mi, shortName, fullIdentifier, methodMap);
// The proxy and stub need to have a valid serviceDescription.
var boundsCheckProxyImpl =
new validation.BoundsCheckTestInterfaceProxy.unbound().impl;
var boundsCheckStubDescription =
validation.BoundsCheckTestInterfaceStub.serviceDescription;
_checkServiceDescription(
boundsCheckProxyImpl.serviceDescription, interfaceID, shortName,
fullIdentifier, methodMap);
_checkServiceDescription(
boundsCheckStubDescription, interfaceID, shortName, fullIdentifier,
methodMap);
}
_checkServiceDescription(service_describer.ServiceDescription sd,
String interfaceID, String shortName, String fullIdentifier,
Map<int, String> methodMap) {
// Check the top level interface, which must pass _checkMojomInterface.
Function identity = (v) => v;
mojom_types.MojomInterface mi = sd.getTopLevelInterface(identity);
_checkMojomInterface(mi, shortName, fullIdentifier, methodMap);
// Try out sd.GetTypeDefinition with the given interfaceID.
mojom_types.UserDefinedType udt = sd.getTypeDefinition(interfaceID, identity);
Expect.isNotNull(udt.interfaceType);
_checkMojomInterface(udt.interfaceType, shortName, fullIdentifier, methodMap);
// Check all type definitions. Reflect-wise, all data inside should match the
// imported Descriptor.
var actualDescriptions = sd.getAllTypeDefinitions(identity);
var expectedDescriptions = validation.getAllMojomTypeDefinitions();
Expect.mapEquals(actualDescriptions, expectedDescriptions);
}
_checkMojomInterface(mojom_types.MojomInterface mi, String shortName,
String fullIdentifier, Map<int, String> methodMap) {
// check the generated short name.
Expect.isNotNull(mi.declData);
Expect.equals(mi.declData.shortName, shortName);
Expect.equals(mi.declData.fullIdentifier, fullIdentifier);
// Verify that the number of methods matches the expected ones.
Expect.equals(mi.methods.length, methodMap.length);
// Each MojomMethod must be named, typed, and "ordinal"ed correctly.
mi.methods.forEach((int ordinal, mojom_types.MojomMethod method) {
Expect.isNotNull(method.declData);
Expect.equals(methodMap[ordinal], method.declData.shortName);
// Special case each method since we know what's inside.
switch (ordinal) {
case 0: // Has request and response params.
// Request is a single uint8 input.
mojom_types.MojomStruct params = method.parameters;
Expect.equals(params.fields.length, 1);
Expect.equals(
params.fields[0].type.simpleType, mojom_types.SimpleType.uint8);
// Response is a single uint8 output.
mojom_types.MojomStruct response = method.responseParams;
Expect.isNotNull(response);
Expect.equals(response.fields.length, 1);
Expect.equals(
response.fields[0].type.simpleType, mojom_types.SimpleType.uint8);
break;
case 1: // Only has request params.
// Request is a single uint8 input.
mojom_types.MojomStruct params = method.parameters;
Expect.equals(params.fields.length, 1);
Expect.equals(
params.fields[0].type.simpleType, mojom_types.SimpleType.uint8);
// Response is a single uint8 output.
mojom_types.MojomStruct response = method.responseParams;
Expect.isNull(response);
break;
default:
assert(false);
}
});
}
void testSerializeErrorMessage() {
var s6 = new serialization.Struct6();
s6.str = null;
try {
var message = messageOfStruct(s6);
Expect.fail("Should throw");
} on bindings.MojoCodecError catch(e) {
// str isn't nullable, so encoding the struct should throw, and the message
// should contain the offending struct and field.
Expect.isTrue(e.message.contains("str") &&
e.message.contains("Struct6"));
}
}
main() async {
testSerializeStructs();
testUnions();
testValidateMojomTypes();
testCamelCase();
testSerializeErrorMessage();
await testEnums();
await testCallResponse();
await testAwaitCallResponse();
await runOnClosedTest();
await testRegression551();
await testServiceName();
}