Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: mojom/mojom_parser/serialization/serialization_test.go

Issue 1421193003: New Mojom Parser: Serialization. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Refactors TestSingleFileSerialization. Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « mojom/mojom_parser/serialization/serialization.go ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package serialization
6
7 import (
8 "fmt"
9 "mojo/public/go/bindings"
10 "mojom/mojom_parser/generated/mojom_files"
11 "mojom/mojom_parser/generated/mojom_types"
12 "mojom/mojom_parser/mojom"
13 "mojom/mojom_parser/parser"
14 "reflect"
15 "testing"
16 myfmt "third_party/golang/src/fmt"
17 )
18
19 // singleFileTestCase stores the data for one serialization test case
20 // in which only a single file is added to the file graph.
21 type singleFileTestCase struct {
22 fileName string
23 mojomContents string
24 lineAndcolumnNumbers bool
25 expectedFile *mojom_files.MojomFile
26 expectedGraph *mojom_files.MojomFileGraph
27 }
28
29 // singleFileTest contains a series of singleFileTestCase and a current
30 // testCaseNum.
31 type singleFileTest struct {
32 cases []singleFileTestCase
33 testCaseNum int
34 }
35
36 // expectedFile() returns the expectedFile of the current test case.
37 func (t *singleFileTest) expectedFile() *mojom_files.MojomFile {
38 return t.cases[t.testCaseNum].expectedFile
39 }
40
41 // expectedGraph() returns the expectedGraph of the current test case.
42 func (t *singleFileTest) expectedGraph() *mojom_files.MojomFileGraph {
43 return t.cases[t.testCaseNum].expectedGraph
44 }
45
46 // fileName() returns the fileName of the current test case
47 func (t *singleFileTest) fileName() string {
48 return t.cases[t.testCaseNum].fileName
49 }
50
51 // addTestCase() should be invoked at the start of a case in
52 // TestSingleFileSerialization.
53 func (test *singleFileTest) addTestCase(moduleNameSpace, contents string) {
54 fileName := fmt.Sprintf("file%d", test.testCaseNum)
55 test.cases = append(test.cases, singleFileTestCase{fileName, contents, f alse,
56 new(mojom_files.MojomFile), new(mojom_files.MojomFileGraph)})
57
58 test.expectedFile().FileName = fileName
59 test.expectedFile().ModuleNamespace = newString(moduleNameSpace)
60
61 test.expectedGraph().ResolvedTypes = make(map[string]mojom_types.UserDef inedType)
62 test.expectedGraph().ResolvedValues = make(map[string]mojom_types.UserDe finedValue)
63 }
64
65 // endTestCase() should be invoked at the end of a case in
66 // TestSingleFileSerialization.
67 func (test *singleFileTest) endTestCase() {
68 test.expectedGraph().Files = make(map[string]mojom_files.MojomFile)
69 test.expectedGraph().Files[test.fileName()] = *test.expectedFile()
70 test.testCaseNum += 1
71 }
72
73 // newDeclData constructs a new DeclarationData with the given data.
74 func (test *singleFileTest) newDeclData(shortName, fullIdentifier string) *mojom _types.DeclarationData {
75 return &mojom_types.DeclarationData{
76 ShortName: newString(shortName),
77 FullIdentifier: newString(fullIdentifier),
78 DeclaredOrdinal: -1,
79 DeclarationOrder: -1,
80 SourceFileInfo: &mojom_types.SourceFileInfo{
81 FileName: test.fileName(),
82 }}
83 }
84
85 // TestSingleFileSerialization uses a series of test cases in which the text of a .mojom
86 // file is specified and the expected MojomFileGraph is specified using Go struc t literals.
87 func TestSingleFileSerialization(t *testing.T) {
88 test := singleFileTest{}
89
90 ////////////////////////////////////////////////////////////
91 // Test Case
92 ////////////////////////////////////////////////////////////
93 {
94
95 contents := `
96 [go_namespace="go.test",
97 lucky=true,
98 planet=EARTH]
99 module mojom.test;
100
101 import "another.file";
102 import "and.another.file";
103
104 const uint16 NUM_MAGI = 3;
105
106 struct Foo{
107 int32 x;
108 string y = "hello";
109 string? z;
110
111 enum Hats {
112 TOP,
113 COWBOY = NUM_MAGI
114 };
115 };`
116
117 test.addTestCase("mojom.test", contents)
118
119 // Attributes
120 test.expectedFile().Attributes = &[]mojom_types.Attribute{
121 {"go_namespace", "go.test"}, {"lucky", "true"}, {"planet ", "EARTH"},
122 }
123
124 // Imports
125 test.expectedFile().Imports = &[]string{
126 "another.file.canonical", "and.another.file.canonical",
127 }
128
129 // DeclaredMojomObjects
130 test.expectedFile().DeclaredMojomObjects.Structs = &[]string{"TY PE_KEY:mojom.test.Foo"}
131 test.expectedFile().DeclaredMojomObjects.TopLevelConstants = &[] string{"TYPE_KEY:mojom.test.NUM_MAGI"}
132
133 // Resolved Values
134
135 // NUM_MAGI
136 test.expectedGraph().ResolvedValues["TYPE_KEY:mojom.test.NUM_MAG I"] = &mojom_types.UserDefinedValueDeclaredConstant{mojom_types.DeclaredConstant {
137 DeclData: *test.newDeclData("NUM_MAGI", "mojom.test.NUM_ MAGI"),
138 Type: &mojom_types.TypeSimpleType{mojom_types.Simple Type_UinT16},
139 Value: &mojom_types.ValueLiteralValue{&mojom_types.Li teralValueInt64Value{3}},
140 }}
141
142 // Hats.TOP
143 test.expectedGraph().ResolvedValues["TYPE_KEY:mojom.test.Foo.Hat s.TOP"] = &mojom_types.UserDefinedValueEnumValue{mojom_types.EnumValue{
144 DeclData: test.newDeclData("TOP", "mojom.test.Foo.Hat s.TOP"),
145 EnumTypeKey: "TYPE_KEY:mojom.test.Foo.Hats",
146 IntValue: -1,
147 }}
148
149 // Hats.COWBOY
150 test.expectedGraph().ResolvedValues["TYPE_KEY:mojom.test.Foo.Hat s.COWBOY"] = &mojom_types.UserDefinedValueEnumValue{mojom_types.EnumValue{
151 DeclData: test.newDeclData("COWBOY", "mojom.test.Foo. Hats.COWBOY"),
152 EnumTypeKey: "TYPE_KEY:mojom.test.Foo.Hats",
153 IntValue: 3,
154 InitializerValue: &mojom_types.ValueUserValueReference{m ojom_types.UserValueReference{
155 Identifier: "NUM_MAGI",
156 ValueKey: newString("TYPE_KEY:mojom .test.NUM_MAGI"),
157 ResolvedConcreteValue: &mojom_types.ValueLiteral Value{&mojom_types.LiteralValueInt64Value{3}},
158 }},
159 }}
160
161 // ResolvedTypes
162
163 // struct Foo
164 test.expectedGraph().ResolvedTypes["TYPE_KEY:mojom.test.Foo"] = &mojom_types.UserDefinedTypeStructType{mojom_types.MojomStruct{
165 DeclData: &mojom_types.DeclarationData{
166 ShortName: newString("Foo"),
167 FullIdentifier: newString("mojom.test.Foo"),
168 DeclaredOrdinal: -1,
169 DeclarationOrder: -1,
170 SourceFileInfo: &mojom_types.SourceFileInfo{
171 FileName: test.fileName(),
172 },
173 ContainedDeclarations: &mojom_types.ContainedDec larations{
174 Enums: &[]string{"TYPE_KEY:mojom.test.Fo o.Hats"}},
175 },
176 Fields: []mojom_types.StructField{
177 // field x
178 {
179 DeclData: test.newDeclData("x", ""),
180 Type: &mojom_types.TypeSimpleType{mo jom_types.SimpleType_InT32},
181 },
182 // field y
183 {
184 DeclData: test.newDeclData("y", ""),
185 Type: &mojom_types.TypeStringTyp e{mojom_types.StringType{false}},
186 DefaultValue: &mojom_types.DefaultFieldV alueValue{&mojom_types.ValueLiteralValue{&mojom_types.LiteralValueStringValue{"h ello"}}},
187 },
188 // field z
189 {
190 DeclData: test.newDeclData("z", ""),
191 Type: &mojom_types.TypeStringType{mo jom_types.StringType{true}},
192 },
193 },
194 }}
195
196 // enum Hats
197 test.expectedGraph().ResolvedTypes["TYPE_KEY:mojom.test.Foo.Hats "] = &mojom_types.UserDefinedTypeEnumType{mojom_types.MojomEnum{
198 DeclData: test.newDeclData("Hats", "mojom.test.Foo.Hats" ),
199 Values: []mojom_types.EnumValue{
200 // Note(rudominer) It is a bug that we need to c opy the enum values here.
201 // See https://github.com/domokit/mojo/issues/51 3.
202 // value TOP
203 test.expectedGraph().ResolvedValues["TYPE_KEY:mo jom.test.Foo.Hats.TOP"].(*mojom_types.UserDefinedValueEnumValue).Value,
204 // value COWBOY
205 test.expectedGraph().ResolvedValues["TYPE_KEY:mo jom.test.Foo.Hats.COWBOY"].(*mojom_types.UserDefinedValueEnumValue).Value,
206 },
207 }}
208
209 test.endTestCase()
210 }
211
212 ////////////////////////////////////////////////////////////
213 // Execute all of the test cases.
214 ////////////////////////////////////////////////////////////
215 for _, c := range test.cases {
216 // Parse and resolve the mojom input.
217 descriptor := mojom.NewMojomDescriptor()
218 parser := parser.MakeParser(c.fileName, c.mojomContents, descrip tor)
219 parser.Parse()
220 if !parser.OK() {
221 t.Errorf("Parsing error for %s: %s", c.fileName, parser. GetError().Error())
222 continue
223 }
224 if err := descriptor.Resolve(); err != nil {
225 t.Errorf("Resolve error for %s: %s", c.fileName, err.Err or())
226 continue
227 }
228 if err := descriptor.ComputeEnumValueIntegers(); err != nil {
229 t.Errorf("ComputeEnumValueIntegers error for %s: %s", c. fileName, err.Error())
230 continue
231 }
232 if err := descriptor.ComputeDataForGenerators(); err != nil {
233 t.Errorf("ComputeDataForGenerators error for %s: %s", c. fileName, err.Error())
234 continue
235 }
236
237 // Simulate setting the canonical file name for the imported fil es. In real operation
238 // this step is done in parser_driver.go when each of the import ed files are parsed.
239 mojomFile := parser.GetMojomFile()
240 if mojomFile.Imports != nil {
241 for _, imp := range mojomFile.Imports {
242 imp.CanonicalFileName = fmt.Sprintf("%s.canonica l", imp.SpecifiedName)
243 }
244 }
245
246 // Serialize
247 EmitLineAndColumnNumbers = c.lineAndcolumnNumbers
248 bytes, err := Serialize(descriptor)
249 if err != nil {
250 t.Errorf("Serialization error for %s: %s", c.fileName, e rr.Error())
251 continue
252 }
253
254 // Deserialize
255 decoder := bindings.NewDecoder(bytes, nil)
256 fileGraph := mojom_files.MojomFileGraph{}
257 fileGraph.Decode(decoder)
258
259 // Compare
260 if err := compareFileGraphs(c.expectedGraph, &fileGraph); err != nil {
261 t.Errorf("%s:\n%s", c.fileName, err.Error())
262 continue
263 }
264 }
265 }
266
267 // compareFileGraphs compares |expected| and |actual| and returns a non-nil
268 // error if they are not deeply equal. The error message contains a human-readab le
269 // string containing a deep-print of expected and actual along with the substrin gs
270 // starting from the first character where they differ.
271 func compareFileGraphs(expected *mojom_files.MojomFileGraph, actual *mojom_files .MojomFileGraph) error {
272 if !reflect.DeepEqual(expected, actual) {
273 // Note(rudominer) The myfmt package is a local modification of the fmt package
274 // that does a deep printing that follows pointers for up to 50 levels.
275 // Thus expectedString and actualString should contain enough in formation to
276 // precisely capture the structure of expected and actual.
277 expectedString := myfmt.Sprintf("%+v", expected)
278 actualString := myfmt.Sprintf("%+v", actual)
279 if expectedString != actualString {
280 diffPos := -1
281 for i := 0; i < len(expectedString) && i < len(actualStr ing); i++ {
282 if expectedString[i] != actualString[i] {
283 diffPos = i
284 break
285 }
286 }
287 mismatchExpected := ""
288 mismatchActual := ""
289 if diffPos > -1 {
290 mismatchExpected = expectedString[diffPos:]
291 mismatchActual = actualString[diffPos:]
292 }
293 return fmt.Errorf("*****\nexpected=\n*****\n%q\n*****\na ctual=\n*****\n%q\n*****\n"+
294 "match failed at position %d: expected=\n*****\n %s\n******\nactual=\n*****\n%s\n******\n",
295 expectedString, actualString, diffPos, mismatchE xpected, mismatchActual)
296 } else {
297 return fmt.Errorf("expected != actual but the two printe d equal.")
298 }
299 }
300 return nil
301 }
OLDNEW
« no previous file with comments | « mojom/mojom_parser/serialization/serialization.go ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698