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),