1// Copyright 2014 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package blueprint
16
17import (
18	"bytes"
19	"testing"
20)
21
22type Walker interface {
23	Walk() bool
24}
25
26type fooModule struct {
27	properties struct {
28		Foo string
29	}
30}
31
32func newFooModule() (Module, []interface{}) {
33	m := &fooModule{}
34	return m, []interface{}{&m.properties}
35}
36
37func (f *fooModule) GenerateBuildActions(ModuleContext) {
38}
39
40func (f *fooModule) Foo() string {
41	return f.properties.Foo
42}
43
44func (f *fooModule) Walk() bool {
45	return true
46}
47
48type barModule struct {
49	properties struct {
50		Bar bool
51	}
52}
53
54func newBarModule() (Module, []interface{}) {
55	m := &barModule{}
56	return m, []interface{}{&m.properties}
57}
58
59func (b *barModule) GenerateBuildActions(ModuleContext) {
60}
61
62func (b *barModule) Bar() bool {
63	return b.properties.Bar
64}
65
66func (b *barModule) Walk() bool {
67	return false
68}
69
70func TestContextParse(t *testing.T) {
71	ctx := NewContext()
72	ctx.RegisterModuleType("foo_module", newFooModule)
73	ctx.RegisterModuleType("bar_module", newBarModule)
74
75	r := bytes.NewBufferString(`
76		foo_module {
77			name: "MyFooModule",
78			deps: ["MyBarModule"],
79		}
80
81		bar_module {
82			name: "MyBarModule",
83		}
84	`)
85
86	_, _, _, errs := ctx.parse(".", "Blueprint", r, nil)
87	if len(errs) > 0 {
88		t.Errorf("unexpected parse errors:")
89		for _, err := range errs {
90			t.Errorf("  %s", err)
91		}
92		t.FailNow()
93	}
94
95	errs = ctx.ResolveDependencies(nil)
96	if len(errs) > 0 {
97		t.Errorf("unexpected dep errors:")
98		for _, err := range errs {
99			t.Errorf("  %s", err)
100		}
101		t.FailNow()
102	}
103}
104
105// |---B===D       - represents a non-walkable edge
106// A               = represents a walkable edge
107// |===C---E===G
108//     |       |   A should not be visited because it's the root node.
109//     |===F===|   B, D and E should not be walked.
110func TestWalkDeps(t *testing.T) {
111	ctx := NewContext()
112	ctx.RegisterModuleType("foo_module", newFooModule)
113	ctx.RegisterModuleType("bar_module", newBarModule)
114	ctx.ParseBlueprintsFiles("context_test_Blueprints")
115	ctx.ResolveDependencies(nil)
116
117	var output string
118	topModule := ctx.moduleGroups["A"].modules[0]
119	ctx.walkDeps(topModule,
120		func(module, parent Module) bool {
121			if module.(Walker).Walk() {
122				output += ctx.ModuleName(module)
123				return true
124			}
125			return false
126		})
127	if output != "CFG" {
128		t.Fatalf("unexpected walkDeps behaviour: %s\nshould be: CFG", output)
129	}
130}
131