Skip to content

Commit

Permalink
Add backticks support for string blocks (#65)
Browse files Browse the repository at this point in the history
  • Loading branch information
stanislas-m authored and markbates committed Jul 24, 2018
1 parent d4510ca commit 726a3d7
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 6 deletions.
50 changes: 50 additions & 0 deletions functions_test.go
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
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
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
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
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

0 comments on commit 726a3d7

Please sign in to comment.