diff --git a/lib/hamlit/syntax_checker.rb b/lib/hamlit/syntax_checker.rb index ab342139..83d8f50e 100644 --- a/lib/hamlit/syntax_checker.rb +++ b/lib/hamlit/syntax_checker.rb @@ -11,6 +11,17 @@ module Hamlit true end + def self.string_literal?(code) + return false if syntax_error?(code) + + type, instructions = Ripper.sexp(code) + return false if type != :program + return false if instructions.size > 1 + + type, _ = instructions.first + type == :string_literal + end + private def on_parse_error(*) diff --git a/test/hamlit/syntax_checker_test.rb b/test/hamlit/syntax_checker_test.rb new file mode 100644 index 00000000..77638d70 --- /dev/null +++ b/test/hamlit/syntax_checker_test.rb @@ -0,0 +1,44 @@ +describe Hamlit::SyntaxChecker do + describe '.syntax_error?' do + it { assert_equal(true, Hamlit::SyntaxChecker.syntax_error?('{ hash }')) } + it { assert_equal(false, Hamlit::SyntaxChecker.syntax_error?('{ a: b }')) } + end + + describe '.string_literal?' do + def assert_literal(expected, code) + actual = Hamlit::SyntaxChecker.string_literal?(code) + assert_equal expected, actual + end + + describe 'invalid expressions' do + it { assert_literal(false, %q|{ hash }|) } + it { assert_literal(false, %q|"hello".|) } + end + + describe 'string literal' do + it { assert_literal(true, %q|''|) } + it { assert_literal(true, %q|""|) } + it { assert_literal(true, %Q|'\n'|) } + it { assert_literal(true, %q|''; |) } + it { assert_literal(true, %q| "" |) } + it { assert_literal(true, %q|'hello world'|) } + it { assert_literal(true, %q|"hello world"|) } + it { assert_literal(true, %q|"h#{ %Q[e#{ "llo wor" }l] }d"|) } + it { assert_literal(true, %q|%Q[nya]|) } + it { assert_literal(true, %q|%Q[#{123}]|) } + end + + describe 'not string literal' do + it { assert_literal(false, %q|123|) } + it { assert_literal(false, %q|'hello' + ''|) } + it { assert_literal(false, %q|'hello'.to_s|) } + it { assert_literal(false, %Q|'' \\ \n ''|) } + it { assert_literal(false, %q|['']|) } + it { assert_literal(false, %q|return ''|) } + end + + describe 'multiple instructions' do + it { assert_literal(false, %Q|''\n''|) } + end + end +end