Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add backticks support for string blocks #65

Merged
merged 1 commit into from
Jul 24, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions functions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package plush
import (
"errors"
"fmt"
"html/template"
"testing"

"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -127,3 +128,52 @@ func Test_Render_Function_Optional_Map(t *testing.T) {
r.NoError(err)
r.Equal("foo|A", s)
}

func Test_Render_Function_With_Backticks_And_Quotes(t *testing.T) {
// From https://github.com/gobuffalo/pop/issues/168
r := require.New(t)
input := "<%= raw(`" + `CREATE MATERIALIZED VIEW view_papers AS
SELECT papers.created_at,
papers.updated_at,
papers.id,
papers.name,
( setweight(to_tsvector(papers.name::text), 'A'::"char") ||
setweight(to_tsvector(papers.author_name), 'B'::"char")
) || setweight(to_tsvector(papers.description), 'C'::"char")
AS paper_vector
FROM
( SELECT papers.id, string_agg(categories.code, ',') as categories
FROM papers
LEFT JOIN paper_categories ON paper_categories.paper_id=papers.id LEFT JOIN (select * from categories order by weight asc) categories ON categories.id=paper_categories.category_id
GROUP BY papers.id
) a
LEFT JOIN papers on a.id=papers.id
WHERE (papers.doc_status = ANY (ARRAY[1, 3])) AND papers.status = 1
WITH DATA` + "`) %>"

output := `CREATE MATERIALIZED VIEW view_papers AS
SELECT papers.created_at,
papers.updated_at,
papers.id,
papers.name,
( setweight(to_tsvector(papers.name::text), 'A'::"char") ||
setweight(to_tsvector(papers.author_name), 'B'::"char")
) || setweight(to_tsvector(papers.description), 'C'::"char")
AS paper_vector
FROM
( SELECT papers.id, string_agg(categories.code, ',') as categories
FROM papers
LEFT JOIN paper_categories ON paper_categories.paper_id=papers.id LEFT JOIN (select * from categories order by weight asc) categories ON categories.id=paper_categories.category_id
GROUP BY papers.id
) a
LEFT JOIN papers on a.id=papers.id
WHERE (papers.doc_status = ANY (ARRAY[1, 3])) AND papers.status = 1
WITH DATA`
s, err := Render(input, NewContextWith(map[string]interface{}{
"raw": func(arg string) template.HTML {
return template.HTML(arg)
},
}))
r.NoError(err)
r.Equal(output, s)
}
15 changes: 15 additions & 0 deletions lexer/lexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,9 @@ func (l *Lexer) nextInsideToken() token.Token {
case '"':
tok.Type = token.STRING
tok.Literal = l.readString()
case '`':
tok.Type = token.B_STRING
tok.Literal = l.readBString()
case '[':
tok = l.newToken(token.LBRACKET)
case ']':
Expand Down Expand Up @@ -275,6 +278,18 @@ func (l *Lexer) readString() string {
return strings.Replace(s, "\\\"", "\"", -1)
}

func (l *Lexer) readBString() string {
position := l.position + 1
for l.ch != 0 {
l.readChar()
if l.ch == '`' {
break
}
}
s := l.input[position:l.position]
return s
}

func (l *Lexer) readHTML() string {
position := l.position

Expand Down
1 change: 1 addition & 0 deletions parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ func newParser(l *lexer.Lexer) *parser {
p.registerPrefix(token.INT, p.parseIntegerLiteral)
p.registerPrefix(token.FLOAT, p.parseFloatLiteral)
p.registerPrefix(token.STRING, p.parseStringLiteral)
p.registerPrefix(token.B_STRING, p.parseStringLiteral)
p.registerPrefix(token.BANG, p.parsePrefixExpression)
p.registerPrefix(token.MINUS, p.parsePrefixExpression)
p.registerPrefix(token.TRUE, p.parseBoolean)
Expand Down
13 changes: 13 additions & 0 deletions parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,19 @@ func Test_StringLiteralExpression(t *testing.T) {
r.Equal("hello world", literal.Value)
}

func Test_StringBlockExpression(t *testing.T) {
r := require.New(t)
input := "<% `hello world`; %>"

program, err := Parse(input)
r.NoError(err)

stmt := program.Statements[0].(*ast.ExpressionStatement)
literal := stmt.Expression.(*ast.StringLiteral)

r.Equal("hello world", literal.Value)
}

func Test_EmptyArrayLiterals(t *testing.T) {
r := require.New(t)
input := "<% [] %>"
Expand Down
13 changes: 7 additions & 6 deletions token/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ const (
EOF = "EOF"

// Identifiers + literals
IDENT = "IDENT" // add, foobar, x, y, ...
INT = "INT" // 1343456
FLOAT = "FLOAT" // 12.34
STRING = "STRING" // "foobar"
HTML = "HTML" // <p>adf</p>
DOT = "DOT" // .23
IDENT = "IDENT" // add, foobar, x, y, ...
INT = "INT" // 1343456
FLOAT = "FLOAT" // 12.34
STRING = "STRING" // "foobar"
B_STRING = "B_STRING" // `foobar`
HTML = "HTML" // <p>adf</p>
DOT = "DOT" // .23

// Operators
ASSIGN = "="
Expand Down