File: test_compiler.rb

package info (click to toggle)
ruby-rabl-rails 0.4.0-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 268 kB
  • ctags: 179
  • sloc: ruby: 1,480; makefile: 2
file content (283 lines) | stat: -rw-r--r-- 9,014 bytes parent folder | download | duplicates (3)
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