spec/lib/hotcell/lexer_spec.rb in hotcell-0.2.0 vs spec/lib/hotcell/lexer_spec.rb in hotcell-0.3.0

- old
+ new

@@ -103,17 +103,17 @@ specify { expression('!foo').should == [[:NOT, '!'], [:IDENTIFER, 'foo']] } specify { expression('-foo').should == [[:MINUS, '-'], [:IDENTIFER, 'foo']] } context 'constants' do specify { expression('nil').should == [[:NIL, nil]] } - specify { expression('"nil"').should == [[:STRING, 'nil']] } + specify { expression('"nil"').should == [[:DOPEN, '"'], [:STRING, 'nil'], [:DCLOSE, '"']] } specify { expression('null').should == [[:NIL, nil]] } - specify { expression('"null"').should == [[:STRING, 'null']] } + specify { expression('"null"').should == [[:DOPEN, '"'], [:STRING, 'null'], [:DCLOSE, '"']] } specify { expression('false').should == [[:FALSE, false]] } - specify { expression('"false"').should == [[:STRING, 'false']] } + specify { expression('"false"').should == [[:DOPEN, '"'], [:STRING, 'false'], [:DCLOSE, '"']] } specify { expression('true').should == [[:TRUE, true]] } - specify { expression('"true"').should == [[:STRING, 'true']] } + specify { expression('"true"').should == [[:DOPEN, '"'], [:STRING, 'true'], [:DCLOSE, '"']] } end end context 'string' do context 'single quoted' do @@ -128,43 +128,79 @@ specify { expression(%q{'foo42'}).should == [[:STRING, 'foo42']] } specify { expression(%q{'привет'}).should == [[:STRING, 'привет']] } specify { expression(%q{'при\вет'}).should == [[:STRING, 'при\вет']] } context do - let(:strings) { data 'sstrings' } + let(:strings) { data 'strings' } specify { expression(strings).delete_if { |token| token.first == :NEWLINE }.should == [ [:STRING, 'fo\'o'], [:STRING, 'fo\o'], [:STRING, 'fo\\o'], [:STRING, 'fo\no'], [:STRING, "foo\nbar"] ] } end end context 'double quoted' do specify { expression(%q{""}).should == [[:STRING, ""]] } - specify { expression(%q{"foo"}).should == [[:STRING, "foo"]] } - specify { expression(%q{"fo'o"}).should == [[:STRING, "fo'o"]] } - specify { expression(%q{"fo\o"}).should == [[:STRING, "fo\o"]] } - specify { expression(%q{"fo\"o"}).should == [[:STRING, "fo\"o"]] } - specify { expression(%q{"fo\'o"}).should == [[:STRING, "fo\'o"]] } - specify { expression(%q{"fo\no"}).should == [[:STRING, "fo\no"]] } - specify { expression(%q{"fo\mo"}).should == [[:STRING, "fo\mo"]] } - specify { expression(%q{"foo42"}).should == [[:STRING, "foo42"]] } - specify { expression(%q{"привет"}).should == [[:STRING, "привет"]] } + specify { expression(%q{"foo"}).should == [[:DOPEN, '"'], [:STRING, "foo"], [:DCLOSE, '"']] } + specify { expression(%q{"fo'o"}).should == [[:DOPEN, '"'], [:STRING, "fo'o"], [:DCLOSE, '"']] } + specify { expression(%q{"fo\o"}).should == [[:DOPEN, '"'], [:STRING, "fo\o"], [:DCLOSE, '"']] } + specify { expression(%q{"fo\"o"}).should == [[:DOPEN, '"'], [:STRING, "fo\"o"], [:DCLOSE, '"']] } + specify { expression(%q{"fo\'o"}).should == [[:DOPEN, '"'], [:STRING, "fo\'o"], [:DCLOSE, '"']] } + specify { expression(%q{"fo\no"}).should == [[:DOPEN, '"'], [:STRING, "fo\no"], [:DCLOSE, '"']] } + specify { expression(%q{"fo\mo"}).should == [[:DOPEN, '"'], [:STRING, "fo\mo"], [:DCLOSE, '"']] } + specify { expression(%q{"foo42"}).should == [[:DOPEN, '"'], [:STRING, "foo42"], [:DCLOSE, '"']] } + specify { expression(%q{"привет"}).should == [[:DOPEN, '"'], [:STRING, "привет"], [:DCLOSE, '"']] } # RBX can not handle this # specify { expression(%q{"при\вет"}).should == [[:STRING, "при\вет"]] } context do let(:strings) { data 'dstrings' } - specify { expression(strings).delete_if { |token| token.first == :NEWLINE }.should == [ + specify { expression(strings).delete_if { |token| + [:NEWLINE, :DOPEN, :DCLOSE].include?(token.first) + }.should == [ [:STRING, "fo\"o"], [:STRING, "fo\o"], [:STRING, "fo\\o"], [:STRING, "fo\no"], [:STRING, "fo\mo"], [:STRING, "fo\to"], [:STRING, "foo\nbar"] ] } end end + + context 'interpolation' do + specify { expression('"{ }"').should == [[:DOPEN, '"'], [:STRING, '{ }'], [:DCLOSE, '"']] } + specify { expression('"#"').should == [[:DOPEN, '"'], [:STRING, '#'], [:DCLOSE, '"']] } + specify { expression('"# "').should == [[:DOPEN, '"'], [:STRING, '# '], [:DCLOSE, '"']] } + specify { expression('" #"').should == [[:DOPEN, '"'], [:STRING, ' #'], [:DCLOSE, '"']] } + specify { expression('"#{ var }"').should == [[:DOPEN, '"'], [:IOPEN, "\#{"], [:IDENTIFER, "var"], + [:ICLOSE, "}"], [:DCLOSE, '"']] } + specify { expression('"#{ } world"').should == [[:DOPEN, '"'], [:IOPEN, "\#{"], [:ICLOSE, "}"], + [:STRING, " world"], [:DCLOSE, '"']] } + specify { expression('"hello #{ }"').should == [[:DOPEN, '"'], [:STRING, "hello "], [:IOPEN, "\#{"], + [:ICLOSE, "}"], [:DCLOSE, '"']] } + specify { expression('"hello#{ } world"').should == [[:DOPEN, '"'], [:STRING, "hello"], [:IOPEN, "\#{"], + [:ICLOSE, "}"], [:STRING, " world"], [:DCLOSE, '"']] } + specify { expression('"hello #{ 2 + 3 }world"').should == [[:DOPEN, '"'], [:STRING, "hello "], + [:IOPEN, "\#{"], [:INTEGER, 2], [:PLUS, "+"], [:INTEGER, 3], + [:ICLOSE, "}"], [:STRING, "world"], [:DCLOSE, '"']] } + specify { expression('"\#{ var }"').should == [[:DOPEN, '"'], [:STRING, '#{ var }'], [:DCLOSE, '"']] } + specify { expression('"#{ } }"').should == [[:DOPEN, '"'], [:IOPEN, "\#{"], [:ICLOSE, "}"], + [:STRING, ' }'], [:DCLOSE, '"']] } + specify { expression('"#{ { } }"').should == [[:DOPEN, '"'], [:IOPEN, "\#{"], [:HOPEN, "{"], + [:HCLOSE, "}"], [:ICLOSE, "}"], [:DCLOSE, '"']] } + specify { expression('"#{ [ ] }"').should == [[:DOPEN, '"'], [:IOPEN, "\#{"], [:AOPEN, "["], + [:ACLOSE, "]"], [:ICLOSE, "}"], [:DCLOSE, '"']] } + specify { expression('"#\{ }"').should == [[:DOPEN, '"'], [:STRING, '#{ }'], [:DCLOSE, '"']] } + specify { expression('"##{ }"').should == [[:DOPEN, '"'], [:STRING, '#'], [:IOPEN, "\#{"], [:ICLOSE, "}"], [:DCLOSE, '"']] } + specify { expression('"###{ } #{ }"').should == [[:DOPEN, '"'], [:STRING, '##'], [:IOPEN, "\#{"], + [:ICLOSE, "}"], [:STRING, ' '], [:IOPEN, "\#{"], [:ICLOSE, "}"], [:DCLOSE, '"']] } + + context 'exceptions' do + specify { expect { expression('"#{"') }.to raise_error Hotcell::UnterminatedString, /`" }}`.*1:7/ } + specify { expect { expression('"#{ { }"') }.to raise_error Hotcell::UnterminatedString, /`" }}`.*1:11/ } + end + end end context 'regexp' do specify { expression('//').should == [[:REGEXP, //]] } specify { expression('/regexp/').should == [[:REGEXP, /regexp/]] } @@ -202,11 +238,12 @@ ] } specify { expression('42; /regexp/').should == [ [:INTEGER, 42], [:SEMICOLON, ";"], [:REGEXP, /regexp/] ] } specify { expression('"hello" /regexp/').should == [ - [:STRING, "hello"], [:DIVIDE, "/"], [:IDENTIFER, "regexp"], [:DIVIDE, "/"] + [:DOPEN, '"'], [:STRING, "hello"], [:DCLOSE, '"'], + [:DIVIDE, "/"], [:IDENTIFER, "regexp"], [:DIVIDE, "/"] ] } end end context 'expression comments' do @@ -272,14 +309,16 @@ [:PCLOSE, ")"] ] } specify { expression("foo(36.6);\n a = \"привет\"").should == [ [:IDENTIFER, "foo"], [:POPEN, "("], [:FLOAT, 36.6], [:PCLOSE, ")"], [:SEMICOLON, ";"], [:NEWLINE, "\n"], - [:IDENTIFER, "a"], [:ASSIGN, "="], [:STRING, "привет"] + [:IDENTIFER, "a"], [:ASSIGN, "="], [:DOPEN, '"'], + [:STRING, "привет"], [:DCLOSE, '"'] ] } specify { expression("'foo'.match(\"^foo$\")").should == [ [:STRING, "foo"], [:PERIOD, "."], [:IDENTIFER, "match"], - [:POPEN, "("], [:STRING, "^foo$"], [:PCLOSE, ")"] + [:POPEN, "("], [:DOPEN, '"'], [:STRING, "^foo$"], + [:DCLOSE, '"'], [:PCLOSE, ")"] ] } end context 'templates' do specify { scan(' ').should == [[:TEMPLATE, " "]] }