// Compile parses all of the soy files in this bundle, verifies a number of // rules about data references, and returns the completed template registry. func (b *Bundle) Compile() (*template.Registry, error) { if b.err != nil { return nil, b.err } // Compile all the soy (globals are already parsed) var registry = template.Registry{} for _, soyfile := range b.files { var tree, err = parse.SoyFile(soyfile.name, soyfile.content, b.globals) if err != nil { return nil, err } if err = registry.Add(tree); err != nil { return nil, err } } // Apply the post-parse processing var err = parsepasses.CheckDataRefs(registry) if err != nil { return nil, err } if b.watcher != nil { go b.recompiler(®istry) } return ®istry, nil }
func runCheckerTests(t *testing.T, tests []checkerTest) { for _, test := range tests { var ( reg template.Registry tree *ast.SoyFileNode err error ) for _, body := range test.body { tree, err = parse.SoyFile("", body, nil) if err != nil { t.Error(err) continue } if err := reg.Add(tree); err != nil { t.Error(err) continue } } err = CheckDataRefs(reg) if test.success && err != nil { t.Error(err) } else if !test.success && err == nil { t.Errorf("%s: expected to fail validation, but no error was raised.", reg.Templates[0].Node.Name) } } }
func TestEvalExpr(t *testing.T) { var tests = []struct { input string expected interface{} }{ {"0", 0}, {"1+1", 2}, {"'abc'", "abc"}, } for _, test := range tests { var tree, err = parse.SoyFile("", "{"+test.input+"}", nil) if err != nil { t.Error(err) return } actual, err := EvalExpr(tree) if err != nil { t.Error(err) continue } if actual != data.New(test.expected) { t.Errorf("EvalExpr(%v) => %v, expected %v", test.input, actual, test.expected) } } }
func TestGenerator(t *testing.T) { var otto = otto.New() var _, err = otto.Run(` var soy = {}; soy.$$escapeHtml = function(arg) { return arg; }; `) if err != nil { t.Error(err) return } Funcs["capitalize"] = Func{func(js JSWriter, args []ast.Node) { js.Write("(", args[0], ".charAt(0).toUpperCase() + ", args[0], ".slice(1))") }, []int{1}} defer delete(Funcs, "capitalize") soyfile, err := parse.SoyFile("name.soy", ` {namespace test} {template .funcs} {let $place: 'world'/} {capitalize('hel' + 'lo')}, {capitalize($place)} {/template}`, nil) if err != nil { t.Error(err) return } var registry = template.Registry{} if err = registry.Add(soyfile); err != nil { t.Error(err) return } var gen = NewGenerator(®istry) var buf bytes.Buffer err = gen.WriteFile(&buf, "name.soy") if err != nil { t.Error(err) return } _, err = otto.Run(buf.String()) if err != nil { t.Error(err) return } output, err := otto.Run(`test.funcs();`) if err != nil { t.Error(err) return } if output.String() != "Hello, World" { t.Errorf("Got %q, expected Hello, World", output.String()) } }
func runNsExecTests(t *testing.T, tests []nsExecTest) { var js = initJs(t) for _, test := range tests { var js = js.Copy() // Parse the templates, generate and run the compiled javascript. var source bytes.Buffer for _, input := range test.input { soyfile, err := parse.SoyFile(test.name, input, globals) if err != nil { t.Error(err) continue } var buf bytes.Buffer err = Write(&buf, soyfile, Options{}) if err != nil { t.Error(err) continue } _, err = js.Run(buf.String()) if err != nil { if test.ok { t.Errorf("compile error: %v\n%v", err, numberLines(&buf)) } continue } source.Write(buf.Bytes()) } // Convert test data to JSON and invoke the template. var jsonData, _ = json.Marshal(test.data) var ijJson, _ = json.Marshal(ij) var renderStatement = fmt.Sprintf("%s(JSON.parse(%q), undefined, JSON.parse(%q));", test.templateName, string(jsonData), string(ijJson)) switch actual, err := js.Run(renderStatement); { case err != nil && test.ok: t.Errorf("render error: %v\n%v\n%v", err, numberLines(&source), renderStatement) case err == nil && !test.ok: t.Errorf("expected error, got none:\n%v\n%v", numberLines(&source), renderStatement) case test.ok && test.output != actual.String(): t.Errorf("expected:\n%v\n\nactual:\n%v\n%v\n%v", test.output, actual.String(), numberLines(&source), renderStatement) } } }
func TestLog(t *testing.T) { var otto = otto.New() _, err := otto.Run(` var console_output = ''; var console = {}; console.log = function(arg) { console_output += arg; }; var soy = {}; soy.$$escapeHtml = function(arg) { return arg; }; `) if err != nil { t.Error(err) return } soyfile, err := parse.SoyFile("", ` {namespace test} {template .log} {log}Hello {$name}.{/log} {/template}`, nil) if err != nil { t.Error(err) return } var buf bytes.Buffer err = Write(&buf, soyfile, Options{}) if err != nil { t.Error(err) return } _, err = otto.Run(buf.String()) if err != nil { t.Error(err) return } _, err = otto.Run(`test.log({name: "Rob"});`) if err != nil { t.Error(err) return } val, _ := otto.Get("console_output") if val.String() != "Hello Rob." { t.Errorf("got %q", val.String()) } }
func runNsExecTests(t *testing.T, tests []nsExecTest) { b := new(bytes.Buffer) for _, test := range tests { var registry = template.Registry{} for _, input := range test.input { var tree, err = parse.SoyFile("", input, globals) if err != nil { t.Errorf("%s: parse error: %s", test.name, err) continue } registry.Add(tree) } b.Reset() var datamap data.Map if test.data != nil { datamap = data.New(test.data).(data.Map) } err := NewTofu(®istry).NewRenderer(test.templateName). Inject(ij). Execute(b, datamap) switch { case !test.ok && err == nil: t.Errorf("%s: expected error; got none", test.name) continue case test.ok && err != nil: t.Errorf("%s: unexpected execute error: %s", test.name, err) continue case !test.ok && err != nil: // expected error, got one } result := b.String() if result != test.output { t.Errorf("%s: expected\n\t%q\ngot\n\t%q", test.name, test.output, result) } } }