1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283
|
require 'helper'
class TestCompiler < MINITEST_TEST_CLASS
describe 'compiler' do
def extract_attributes(nodes)
nodes.map(&:hash)
end
before do
@view = Context.new
@compiler = RablRails::Compiler.new(@view)
end
it "returns a compiled template instance" do
assert_instance_of RablRails::CompiledTemplate, @compiler.compile_source("")
end
describe '#object' do
it "sets data for the template" do
t = @compiler.compile_source(%{ object :@user })
assert_equal :@user, t.data
assert_equal([], t.nodes)
end
it "can define root name" do
t = @compiler.compile_source(%{ object :@user => :author })
assert_equal :@user, t.data
assert_equal :author, t.root_name
assert_equal([], t.nodes)
end
end
describe '#root' do
it "defines root via keyword" do
t = @compiler.compile_source(%{ root :author })
assert_equal :author, t.root_name
end
it "overrides object root" do
t = @compiler.compile_source(%{ object :@user ; root :author })
assert_equal :author, t.root_name
end
it "can set root to false via options" do
t = @compiler.compile_source(%( object :@user, root: false))
assert_equal false, t.root_name
end
end
describe '#collection' do
it "sets the data for the template" do
t = @compiler.compile_source(%{ collection :@user })
assert_equal :@user, t.data
assert_equal([], t.nodes)
end
it "can define root name" do
t = @compiler.compile_source(%{ collection :@user => :users })
assert_equal :@user, t.data
assert_equal :users, t.root_name
assert_equal([], t.nodes)
end
it "can define root name via options" do
t = @compiler.compile_source(%{ collection :@user, :root => :users })
assert_equal :@user, t.data
assert_equal :users, t.root_name
end
end
it "should not have a cache key if cache is not enable" do
t = @compiler.compile_source('')
assert_equal false, t.cache_key
end
describe '#cache' do
it "can take no argument" do
t = @compiler.compile_source(%{ cache })
assert_nil t.cache_key
end
it "sets the given block as cache key" do
t = @compiler.compile_source(%( cache { 'foo' }))
assert_instance_of Proc, t.cache_key
end
end
# Compilation
it "compiles single attributes" do
t = @compiler.compile_source(%{ attributes :id, :name })
assert_equal([{ :id => :id, :name => :name }], extract_attributes(t.nodes))
end
it "compiles attributes with the same name once" do
skip('Failing')
t = @compiler.compile_source(%{ attribute :id ; attribute :id })
assert_equal([{ :id => :id }], extract_attributes(t.nodes))
end
it "aliases attributes through :as option" do
t = @compiler.compile_source(%{ attribute :foo, :as => :bar })
assert_equal([{ :bar => :foo }], extract_attributes(t.nodes))
end
it "aliases attributes through a hash" do
t = @compiler.compile_source(%{ attribute :foo => :bar })
assert_equal([{ :bar => :foo }], extract_attributes(t.nodes))
end
it "aliases multiple attributes" do
t = @compiler.compile_source(%{ attributes :foo => :bar, :id => :uid })
assert_equal([{ :bar => :foo, :uid => :id }], extract_attributes(t.nodes))
end
it "compiles child with record association" do
t = @compiler.compile_source(%{ child :address do attributes :foo end})
assert_equal(1, t.nodes.size)
child_node = t.nodes.first
assert_equal(:address, child_node.name)
assert_equal(:address, child_node.data)
assert_equal([{ foo: :foo }], extract_attributes(child_node.nodes))
end
it "compiles child with association aliased" do
t = @compiler.compile_source(%{ child :address => :bar do attributes :foo end})
child_node = t.nodes.first
assert_equal(:bar, child_node.name)
assert_equal(:address, child_node.data)
end
it "compiles child with root name defined as option" do
t = @compiler.compile_source(%{ child(:user, :root => :author) do attributes :foo end })
child_node = t.nodes.first
assert_equal(:author, child_node.name)
assert_equal(:user, child_node.data)
end
it "compiles child with arbitrary source" do
t = @compiler.compile_source(%{ child :@user => :author do attribute :name end })
child_node = t.nodes.first
assert_equal(:author, child_node.name)
assert_equal(:@user, child_node.data)
end
it "compiles child with inline partial notation" do
mock_template = RablRails::CompiledTemplate.new
mock_template.add_node(RablRails::Nodes::Attribute.new(id: :id))
t = RablRails::Library.instance.stub :compile_template_from_path, mock_template do
@compiler.compile_source(%{child(:user, :partial => 'users/base') })
end
child_node = t.nodes.first
assert_equal(:user, child_node.name)
assert_equal(:user, child_node.data)
assert_equal([{ id: :id }], extract_attributes(child_node.nodes))
end
it "compiles glue as a child but without a name" do
t = @compiler.compile_source(%{ glue(:@user) do attribute :name end })
assert_equal(1, t.nodes.size)
glue_node = t.nodes.first
assert_equal(:@user, glue_node.data)
assert_equal([{ name: :name }], extract_attributes(glue_node.nodes))
end
it "allows multiple glue within same template" do
t = @compiler.compile_source(%{
glue :@user do attribute :name end
glue :@user do attribute :foo end
})
assert_equal(2, t.nodes.size)
end
it "compiles glue with RablRails DSL in its body" do
t = @compiler.compile_source(%{
glue :@user do node(:foo) { |u| u.name } end
})
glue_node = t.nodes.first
assert_equal(1, glue_node.nodes.size)
code_node = glue_node.nodes.first
assert_instance_of(RablRails::Nodes::Code, code_node)
assert_equal(:foo, code_node.name)
end
it "extends other template" do
template = RablRails::CompiledTemplate.new
template.add_node RablRails::Nodes::Attribute.new(id: :id)
library = MiniTest::Mock.new
library.expect :compile_template_from_path, template, ['users/base', @view]
t = RablRails::Library.stub :instance, library do
@compiler.compile_source(%{ extends 'users/base' })
end
assert_equal([{ :id => :id }], extract_attributes(t.nodes))
library.verify
end
it "compiles extend without overwriting nodes previously defined" do
template = RablRails::CompiledTemplate.new
template.add_node(RablRails::Nodes::Condition.new(->{ true }, ->{ 'foo' }))
t = RablRails::Library.instance.stub :compile_template_from_path, template do
@compiler.compile_source(%{
condition(-> { false }) { 'bar' }
extends('users/xtnd')
})
end
assert_equal(2, t.nodes.size)
end
it "compiles node" do
t = @compiler.compile_source(%{ node(:foo) { bar } })
assert_equal(1, t.nodes.size)
code_node = t.nodes.first
assert_equal(:foo, code_node.name)
assert_instance_of Proc, code_node.block
end
it "compiles node with condition option" do
t = @compiler.compile_source(%{ node(:foo, :if => lambda { |m| m.foo.present? }) do |m| m.foo end })
code_node = t.nodes.first
assert_instance_of Proc, code_node.condition
end
it "compiles node with no argument" do
t = @compiler.compile_source(%{ node do |m| m.foo end })
node = t.nodes.first
assert_nil node.name
end
it "compiles merge like a node but with a reserved keyword as name" do
t = @compiler.compile_source(%{ merge do |m| m.foo end })
node = t.nodes.first
assert_instance_of RablRails::Nodes::Code, node
assert_nil node.name
end
it "compiles condition" do
t = @compiler.compile_source(%{ condition(->(u) {}) do attributes :secret end })
assert_equal(1, t.nodes.size)
node = t.nodes.first
assert_instance_of RablRails::Nodes::Condition, node
assert_equal([{ secret: :secret }], extract_attributes(node.nodes))
end
it "compiles with no object" do
t = @compiler.compile_source(%{
object false
child(:@user => :user) do
attribute :id
end
})
assert_equal false, t.data
end
describe '#extract_data_and_name' do
it "extracts name from argument" do
assert_equal [:@users, 'users'], @compiler.send(:extract_data_and_name, :@users)
assert_equal [:users, :users], @compiler.send(:extract_data_and_name, :users)
assert_equal [:@users, :authors], @compiler.send(:extract_data_and_name, :@users => :authors)
end
end
end
end
|