spec/lib/hotcell/parser_spec.rb in hotcell-0.1.0 vs spec/lib/hotcell/parser_spec.rb in hotcell-0.2.0

- old
+ new

@@ -1,12 +1,12 @@ # encoding: UTF-8 require 'spec_helper' describe Hotcell::Parser do def method_missing method, *args, &block - klass = Hotcell::Calculator::HANDLERS[method] ? - Hotcell::Calculator : Hotcell::Node + klass = Hotcell::Expression::HANDLERS[method] ? + Hotcell::Expression : Hotcell::Node instance = Hotcell::Assigner.new *args if method == :ASSIGN instance = Hotcell::Summoner.new *args if method == :METHOD klass = Hotcell::Arrayer if [:ARRAY, :PAIR].include?(method) klass = Hotcell::Hasher if method == :HASH @@ -155,10 +155,16 @@ specify { parse('{{ (nil) }}').should be_equal_node_to JOINER(TAG(nil, mode: :normal)) } specify { parse('{{ (3) }}').should be_equal_node_to JOINER(TAG(3, mode: :normal)) } specify { parse('{{ (\'hello\') }}').should be_equal_node_to JOINER(TAG('hello', mode: :normal)) } specify { parse('{{ () }}').should be_equal_node_to JOINER(TAG(nil, mode: :normal)) } + specify { parse('{{ \'a\'..\'z\' }}').should be_equal_node_to JOINER(TAG('a'..'z', mode: :normal)) } + specify { parse('{{ 0..10 }}').should be_equal_node_to JOINER(TAG(0..10, mode: :normal)) } + specify { parse('{{ 0...10 }}').should be_equal_node_to JOINER(TAG(0...10, mode: :normal)) } + specify { parse('{{ 3 + 0..10 + 5 }}').should be_equal_node_to JOINER(TAG(3..15, mode: :normal)) } + specify { parse('{{ 3 + (0..var) + 5 }}').should be_equal_node_to JOINER(TAG(PLUS(PLUS(3, RANGE(0, METHOD('var'))), 5), mode: :normal)) } + specify { parse('{{ bar > 2 }}').should be_equal_node_to JOINER(TAG(GT(METHOD('bar'), 2), mode: :normal)) } specify { parse('{{ 2 < bar }}').should be_equal_node_to JOINER(TAG(LT(2, METHOD('bar')), mode: :normal)) } specify { parse('{{ 2 >= tru }}').should be_equal_node_to JOINER(TAG(GTE(2, METHOD('tru')), mode: :normal)) } specify { parse('{{ some <= 2 }}').should be_equal_node_to JOINER(TAG(LTE(METHOD('some'), 2), mode: :normal)) } specify { parse('{{ 2 && false }}').should be_equal_node_to JOINER(TAG(false, mode: :normal)) } @@ -200,11 +206,11 @@ specify { parse('{{ -42.42.baz }}').should be_equal_node_to JOINER(TAG( METHOD('baz', -42.42), mode: :normal)) } specify { parse('{{ foo(\'hello\').bar[2].baz(-42) }}').should be_equal_node_to JOINER(TAG( METHOD('baz', - METHOD('manipulator_brackets', + METHOD('[]', METHOD('bar', METHOD('foo', nil, 'hello') ), 2 ), -42 ), @@ -214,37 +220,37 @@ context 'arrays' do specify { parse('{{ [] }}').should be_equal_node_to JOINER(TAG(ARRAY(), mode: :normal)) } specify { parse('{{ [ 2 ] }}').should be_equal_node_to JOINER(TAG(ARRAY(2), mode: :normal)) } specify { parse('{{ [ 2, 3 ] }}').should be_equal_node_to JOINER(TAG(ARRAY(2, 3), mode: :normal)) } - specify { parse('{{ [2, 3][42] }}').should be_equal_node_to JOINER(TAG(METHOD('manipulator_brackets', ARRAY(2, 3), 42), mode: :normal)) } + specify { parse('{{ [2, 3][42] }}').should be_equal_node_to JOINER(TAG(METHOD('[]', ARRAY(2, 3), 42), mode: :normal)) } specify { parse('{{ [2 + foo, (2 * bar)] }}').should be_equal_node_to JOINER(TAG(ARRAY(PLUS(2, METHOD('foo')), MULTIPLY(2, METHOD('bar'))), mode: :normal)) } specify { parse('{{ [[2, 3], 42] }}').should be_equal_node_to JOINER(TAG(ARRAY(ARRAY(2, 3), 42), mode: :normal)) } end context 'hashes' do specify { parse('{{ {} }}').should be_equal_node_to JOINER(TAG(HASH(), mode: :normal)) } specify { parse('{{ { hello: \'world\' } }}').should be_equal_node_to( JOINER(TAG(HASH(PAIR('hello', 'world')), mode: :normal)) ) } specify { parse('{{ {hello: \'world\'}[\'hello\'] }}').should be_equal_node_to( - JOINER(TAG(METHOD('manipulator_brackets', HASH(PAIR('hello', 'world')), 'hello'), mode: :normal)) + JOINER(TAG(METHOD('[]', HASH(PAIR('hello', 'world')), 'hello'), mode: :normal)) ) } specify { parse('{{ { hello: 3, world: 6 * foo } }}').should be_equal_node_to( JOINER(TAG(HASH( PAIR('hello', 3), PAIR('world', MULTIPLY(6, METHOD('foo'))) ), mode: :normal)) ) } end context '[]' do - specify { parse('{{ hello[3] }}').should be_equal_node_to JOINER(TAG(METHOD('manipulator_brackets', METHOD('hello'), 3), mode: :normal)) } - specify { parse('{{ \'boom\'[3] }}').should be_equal_node_to JOINER(TAG(METHOD('manipulator_brackets', 'boom', 3), mode: :normal)) } - specify { parse('{{ 7[3] }}').should be_equal_node_to JOINER(TAG(METHOD('manipulator_brackets', 7, 3), mode: :normal)) } - specify { parse('{{ 3 + 5[7] }}').should be_equal_node_to JOINER(TAG(PLUS(3, METHOD('manipulator_brackets', 5, 7)), mode: :normal)) } - specify { parse('{{ (3 + 5)[7] }}').should be_equal_node_to JOINER(TAG(METHOD('manipulator_brackets', 8, 7), mode: :normal)) } + specify { parse('{{ hello[3] }}').should be_equal_node_to JOINER(TAG(METHOD('[]', METHOD('hello'), 3), mode: :normal)) } + specify { parse('{{ \'boom\'[3] }}').should be_equal_node_to JOINER(TAG(METHOD('[]', 'boom', 3), mode: :normal)) } + specify { parse('{{ 7[3] }}').should be_equal_node_to JOINER(TAG(METHOD('[]', 7, 3), mode: :normal)) } + specify { parse('{{ 3 + 5[7] }}').should be_equal_node_to JOINER(TAG(PLUS(3, METHOD('[]', 5, 7)), mode: :normal)) } + specify { parse('{{ (3 + 5)[7] }}').should be_equal_node_to JOINER(TAG(METHOD('[]', 8, 7), mode: :normal)) } end context 'function arguments' do specify { parse('{{ hello() }}').should be_equal_node_to JOINER(TAG(METHOD('hello'), mode: :normal)) } specify { parse('{{ hello(2 * foo) }}').should be_equal_node_to( @@ -304,66 +310,143 @@ specify { parse('hello {{ # world; foo}}').should be_equal_node_to JOINER('hello ', TAG(mode: :normal)) } specify { parse("hello {{ # world\n foo}}").should be_equal_node_to JOINER('hello ', TAG(METHOD('foo'), mode: :normal)) } specify { parse("hello {{ world# foo}}").should be_equal_node_to JOINER('hello ', TAG(METHOD('world'), mode: :normal)) } end + context 'tag modes' do + specify { parse('{{ }}').should be_equal_node_to JOINER(TAG(mode: :normal)) } + specify { parse('{{! }}').should be_equal_node_to JOINER(TAG(mode: :silence)) } + specify { parse('{{^ }}').should be_equal_node_to JOINER(TAG(mode: :escape)) } + specify { parse('{{e }}').should be_equal_node_to JOINER(TAG(mode: :escape)) } + specify { parse('{{~ }}').should be_equal_node_to JOINER(TAG(mode: :normal)) } + specify { parse('{{r }}').should be_equal_node_to JOINER(TAG(mode: :normal)) } + + context 'escape_tags' do + specify { parse('{{ }}', escape_tags: true).should be_equal_node_to JOINER(TAG(mode: :escape)) } + end + + context 'commands' do + let(:snippet_command) { Class.new(Hotcell::Command) } + let(:commands) { { snippet: snippet_command }.stringify_keys } + + specify { parse('{{ snippet }}', commands: commands).should be_equal_node_to JOINER( + TAG(snippet_command.build('snippet'), mode: :normal) + ) } + specify { parse('{{! snippet }}', commands: commands).should be_equal_node_to JOINER( + TAG(snippet_command.build('snippet'), mode: :silence) + ) } + specify { parse('{{^ snippet }}', commands: commands).should be_equal_node_to JOINER( + TAG(snippet_command.build('snippet'), mode: :escape) + ) } + specify { parse('{{e snippet }}', commands: commands).should be_equal_node_to JOINER( + TAG(snippet_command.build('snippet'), mode: :escape) + ) } + specify { parse('{{~ snippet }}', commands: commands).should be_equal_node_to JOINER( + TAG(snippet_command.build('snippet'), mode: :normal) + ) } + specify { parse('{{r snippet }}', commands: commands).should be_equal_node_to JOINER( + TAG(snippet_command.build('snippet'), mode: :normal) + ) } + + context 'escape_tags' do + specify { parse('{{ snippet }}', + commands: commands, escape_tags: true + ).should be_equal_node_to JOINER( + TAG(snippet_command.build('snippet'), mode: :normal) + ) } + end + end + + context 'blocks' do + let(:cycle_block) { Class.new(Hotcell::Block) } + let(:blocks) { { cycle: cycle_block }.stringify_keys } + + specify { parse('{{ cycle }}{{ end }}', blocks: blocks).should be_equal_node_to JOINER( + TAG(cycle_block.build('cycle'), mode: :normal) + ) } + specify { parse('{{! cycle }}{{ end }}', blocks: blocks).should be_equal_node_to JOINER( + TAG(cycle_block.build('cycle'), mode: :silence) + ) } + specify { parse('{{^ cycle }}{{ end }}', blocks: blocks).should be_equal_node_to JOINER( + TAG(cycle_block.build('cycle'), mode: :escape) + ) } + specify { parse('{{e cycle }}{{ end }}', blocks: blocks).should be_equal_node_to JOINER( + TAG(cycle_block.build('cycle'), mode: :escape) + ) } + specify { parse('{{~ cycle }}{{ end }}', blocks: blocks).should be_equal_node_to JOINER( + TAG(cycle_block.build('cycle'), mode: :normal) + ) } + specify { parse('{{r cycle }}{{ end }}', blocks: blocks).should be_equal_node_to JOINER( + TAG(cycle_block.build('cycle'), mode: :normal) + ) } + + context 'escape_tags' do + specify { parse('{{ cycle }}{{ end }}', + blocks: blocks, escape_tags: true + ).should be_equal_node_to JOINER( + TAG(cycle_block.build('cycle'), mode: :normal) + ) } + end + end + end + context 'commands' do - let(:include_tag) { Class.new(Hotcell::Command) } - let(:snippet_tag) { Class.new(Hotcell::Command) } + let(:include_command) { Class.new(Hotcell::Command) } + let(:snippet_command) { Class.new(Hotcell::Command) } let(:commands) do { - include: include_tag, - snippet: snippet_tag + include: include_command, + snippet: snippet_command }.stringify_keys end specify { parse("{{ include 'some/partial' }}", commands: commands).should be_equal_node_to JOINER( - TAG(include_tag.build('include', 'some/partial'), mode: :normal) + TAG(include_command.build('include', 'some/partial'), mode: :normal) ) } specify { parse("{{ include }}", commands: commands).should be_equal_node_to JOINER( - TAG(include_tag.build('include'), mode: :normal) + TAG(include_command.build('include'), mode: :normal) ) } specify { parse("{{! include 'some/partial' }}\n{{ snippet 'sidebar' }}", commands: commands).should be_equal_node_to JOINER( - TAG(include_tag.build('include', 'some/partial'), mode: :silence), + TAG(include_command.build('include', 'some/partial'), mode: :silence), "\n", - TAG(snippet_tag.build('snippet', 'sidebar'), mode: :normal), + TAG(snippet_command.build('snippet', 'sidebar'), mode: :normal), ) } specify { parse("{{! variable = include }}", commands: commands).should be_equal_node_to JOINER( - TAG(ASSIGN('variable', include_tag.build('include')), mode: :silence) + TAG(ASSIGN('variable', include_command.build('include')), mode: :silence) ) } specify { parse("{{ variable = include 'some/partial' }}", commands: commands).should be_equal_node_to JOINER( - TAG(ASSIGN('variable', include_tag.build('include', 'some/partial')), mode: :normal) + TAG(ASSIGN('variable', include_command.build('include', 'some/partial')), mode: :normal) ) } end context 'blocks' do - let(:scoped_tag) { Class.new(Hotcell::Block) } - let(:each_tag) { Class.new(Hotcell::Block) } + let(:scoped_block) { Class.new(Hotcell::Block) } + let(:each_block) { Class.new(Hotcell::Block) } let(:blocks) do { - scoped: scoped_tag, - each: each_tag + scoped: scoped_block, + each: each_block }.stringify_keys end specify { parse("{{ scoped }}{{ end scoped }}", blocks: blocks).should be_equal_node_to JOINER( - TAG(scoped_tag.build('scoped'), mode: :normal) + TAG(scoped_block.build('scoped'), mode: :normal) ) } specify { parse("{{ scoped var: 'hello' }}{{ endscoped }}", blocks: blocks).should be_equal_node_to JOINER( - TAG(scoped_tag.build('scoped', HASH(PAIR('var', 'hello'))), mode: :normal) + TAG(scoped_block.build('scoped', HASH(PAIR('var', 'hello'))), mode: :normal) ) } specify { parse("<article>\n{{ each post, in: posts }}\n<h1>{{ post.title }}</h1>\n{{ end each }}\n</article>", blocks: blocks).should be_equal_node_to JOINER( "<article>\n", - TAG(each_tag.build('each', + TAG(each_block.build('each', METHOD('post'), HASH(PAIR('in', METHOD('posts'))), subnodes: [JOINER( "\n<h1>", TAG(METHOD('title', METHOD('post')), mode: :normal), @@ -372,11 +455,11 @@ ), mode: :normal), "\n</article>" ) } specify { parse("{{! iter = each post, in: posts }}\n<h1>{{ post.title }}</h1>\n{{ end each }}", blocks: blocks).should be_equal_node_to JOINER( - TAG(ASSIGN('iter', each_tag.build('each', + TAG(ASSIGN('iter', each_block.build('each', METHOD('post'), HASH(PAIR('in', METHOD('posts'))), subnodes: [JOINER( "\n<h1>", TAG(METHOD('title', METHOD('post')), mode: :normal), @@ -384,13 +467,13 @@ )] )), mode: :silence), ) } specify { parse("{{ capture = scoped }} hello {{ each post, in: posts }} {{ loop }} {{ end each }}{{ endscoped }}", blocks: blocks).should be_equal_node_to JOINER( - TAG(ASSIGN('capture', scoped_tag.build('scoped', + TAG(ASSIGN('capture', scoped_block.build('scoped', subnodes: [JOINER( ' hello ', - TAG(each_tag.build('each', + TAG(each_block.build('each', METHOD('post'), HASH(PAIR('in', METHOD('posts'))), subnodes: [JOINER( ' ', TAG(METHOD('loop'), mode: :normal),