package assetloader import ( "os" "path/filepath" "strings" "testing" ) func TestBuildQuerySQLContexts(t *testing.T) { call := `SELECT ':unknown', ":unknown", $$:unknown$$, E'it\':unknown', :bytes::bytea, :filename, :bytes /* :unknown /* :unknown */ */ -- :unknown ` got, args, err := BuildQuery(call, []byte("$1"), "File.txt", nil) if err != nil { t.Fatal(err) } if len(args) != 2 || !strings.Contains(got, "$1::bytea, $2, $1") || !strings.Contains(got, "$$:unknown$$") { t.Fatalf("%s %#v", got, args) } } func TestEmbedLiteralOnePassAndSQLContexts(t *testing.T) { dir := t.TempDir() data := "price $1 ${2} $HOME $$ :b 'quote' \\path" for file, text := range map[string]string{"a.txt": data, "b.txt": "Second"} { if err := os.WriteFile(filepath.Join(dir, file), []byte(text), 0o600); err != nil { t.Fatal(err) } } sql := `-- @embed: path=a.txt var=:a mode=text -- @embed: path=b.txt var=:b mode=text SELECT :a,:a,:b, ':a', ":a", $$:a$$, 1::integer; -- :a /* :a */` got, err := ProcessEmbedDirectives(filepath.Join(dir, "script.sql"), sql) if err != nil { t.Fatal(err) } literal, err := sqlStringLiteral(data) if err != nil { t.Fatal(err) } if strings.Count(got, literal) != 2 || !strings.Contains(got, "'Second'") || !strings.Contains(got, "':a'") || !strings.Contains(got, "$$:a$$") { t.Fatalf("%s", got) } for _, sql := range []string{"SELECT $body$\n-- @embed: path=missing var=:x mode=text\n$body$", "SELECT '\n-- @embed: path=missing var=:x mode=text\n'", "/*\n-- @embed: path=missing var=:x mode=text\n*/", "SELECT 1; -- @embed: path=missing var=:x mode=text"} { if HasEmbedDirectives(sql) { t.Fatalf("false directive: %s", sql) } got, err := ProcessEmbedDirectives("", sql) if err != nil || got != sql { t.Fatalf("%q: %v", got, err) } } for _, sql := range []string{"-- @embed: path=a.txt var=:a mode=text\nSELECT ':a'", "-- @embed: path=a.txt var=:a mode=text\n-- @embed: path=b.txt var=:a mode=text\nSELECT :a"} { if _, err := ProcessEmbedDirectives(filepath.Join(dir, "script.sql"), sql); err == nil { t.Fatal("expected invalid directive use") } } }