hypertemplate 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. data/LICENSE +29 -0
  2. data/README.md +134 -0
  3. data/lib/hypertemplate.rb +14 -0
  4. data/lib/hypertemplate/builder.rb +33 -0
  5. data/lib/hypertemplate/builder/base.rb +111 -0
  6. data/lib/hypertemplate/builder/json.rb +132 -0
  7. data/lib/hypertemplate/builder/values.rb +33 -0
  8. data/lib/hypertemplate/builder/xml.rb +119 -0
  9. data/lib/hypertemplate/errors.rb +3 -0
  10. data/lib/hypertemplate/hook.rb +6 -0
  11. data/lib/hypertemplate/hook/rails.rb +112 -0
  12. data/lib/hypertemplate/hook/sinatra.rb +44 -0
  13. data/lib/hypertemplate/hook/tilt.rb +68 -0
  14. data/lib/hypertemplate/recipes.rb +25 -0
  15. data/lib/hypertemplate/registry.rb +24 -0
  16. data/lib/hypertemplate/version.rb +13 -0
  17. data/script/console +7 -0
  18. data/test/hypertemplate/builder/base_test.rb +45 -0
  19. data/test/hypertemplate/builder/json_test.rb +506 -0
  20. data/test/hypertemplate/builder/values_test.rb +12 -0
  21. data/test/hypertemplate/builder/xml_test.rb +479 -0
  22. data/test/hypertemplate/helper_test.rb +116 -0
  23. data/test/hypertemplate/hook/rails_test.rb +77 -0
  24. data/test/hypertemplate/hook/sinatra_test.rb +89 -0
  25. data/test/hypertemplate/hook/tilt_test.rb +48 -0
  26. data/test/hypertemplate/recipes_test.rb +94 -0
  27. data/test/rails2_skel/Rakefile +16 -0
  28. data/test/rails2_skel/app/controllers/application_controller.rb +1 -0
  29. data/test/rails2_skel/app/controllers/test_controller.rb +18 -0
  30. data/test/rails2_skel/app/views/test/_feed_member.tokamak +9 -0
  31. data/test/rails2_skel/app/views/test/feed.tokamak +24 -0
  32. data/test/rails2_skel/app/views/test/show.hyper +31 -0
  33. data/test/rails2_skel/config/boot.rb +110 -0
  34. data/test/rails2_skel/config/environment.rb +20 -0
  35. data/test/rails2_skel/config/environments/development.rb +17 -0
  36. data/test/rails2_skel/config/environments/production.rb +28 -0
  37. data/test/rails2_skel/config/environments/test.rb +28 -0
  38. data/test/rails2_skel/config/initializers/cookie_verification_secret.rb +2 -0
  39. data/test/rails2_skel/config/initializers/mime_types.rb +3 -0
  40. data/test/rails2_skel/config/initializers/new_rails_defaults.rb +10 -0
  41. data/test/rails2_skel/config/initializers/session_store.rb +5 -0
  42. data/test/rails2_skel/config/routes.rb +43 -0
  43. data/test/rails2_skel/log/development.log +10190 -0
  44. data/test/rails2_skel/script/console +3 -0
  45. data/test/test_helper.rb +9 -0
  46. metadata +207 -0
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+ ENV["MIGRATOR_CALLER"] = "console"
5
+ libs = " -r #{File.dirname(__FILE__) + '/../lib/hypertemplate.rb'} -r ruby-debug"
6
+ puts "Loading hypertemplate development environment..."
7
+ exec "#{irb} #{libs} --simple-prompt #{ARGV.join("")}"
@@ -0,0 +1,45 @@
1
+ require 'test_helper'
2
+
3
+ class Hypertemplate::Builder::BaseTest < Test::Unit::TestCase
4
+
5
+ class SomeBuilder < Hypertemplate::Builder::Base
6
+ def self.media_types
7
+ ["valid/media_type"]
8
+ end
9
+ end
10
+
11
+ class AnotherBuilder < Hypertemplate::Builder::Base
12
+ def self.media_types
13
+ ["valid/media_type", "another_valid/media_type"]
14
+ end
15
+ end
16
+
17
+ class YetAnotherBuilder < Hypertemplate::Builder::Base
18
+ def self.media_types
19
+ ["yet_another_valid/media_type"]
20
+ end
21
+ end
22
+
23
+ def setup
24
+ @registry = Hypertemplate::Registry.new
25
+ @registry << SomeBuilder
26
+ @registry << AnotherBuilder
27
+ @registry << YetAnotherBuilder
28
+ end
29
+
30
+ def test_should_support_media_type_registering
31
+ @registry["runtime/media_type"] = AnotherBuilder
32
+ assert_equal AnotherBuilder , @registry["runtime/media_type"]
33
+ end
34
+
35
+ def test_should_lookup_valid_media_types
36
+ assert_equal AnotherBuilder , @registry["valid/media_type"]
37
+ assert_equal AnotherBuilder , @registry["another_valid/media_type"]
38
+ assert_equal YetAnotherBuilder, @registry["yet_another_valid/media_type"]
39
+ end
40
+
41
+ def test_should_lookup_invalid_media_types
42
+ assert_equal nil , @registry["invalid/media_type"]
43
+ end
44
+
45
+ end
@@ -0,0 +1,506 @@
1
+ require 'test_helper'
2
+
3
+ class Hypertemplate::Builder::JsonTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @registry = Hypertemplate::Registry.new
7
+ @registry << DummyAtom
8
+ end
9
+
10
+ def test_media_type_should_be_json
11
+ assert_equal ["application/json"], Hypertemplate::Builder::Json.media_types
12
+ end
13
+
14
+ def test_custom_values_and_iterating_over_members
15
+ obj = [{ :foo => "bar" }]
16
+ json = Hypertemplate::Builder::Json.build(obj) do |collection|
17
+ collection.values do |values|
18
+ values.id "an_id"
19
+ end
20
+
21
+ collection.members do |member, some_foos|
22
+ member.values do |values|
23
+ values.id some_foos[:foo]
24
+ end
25
+ end
26
+ end
27
+
28
+ hash = JSON.parse(json).extend(Methodize)
29
+
30
+ assert_equal "an_id", hash.id
31
+ assert_equal "bar" , hash.members.first.id
32
+ assert hash.members.kind_of?(Array)
33
+ end
34
+
35
+ def test_empty_value_as_nil
36
+ obj = {}
37
+ json = Hypertemplate::Builder::Json.build(obj) do |collection|
38
+ collection.values do |values|
39
+ values.empty_value
40
+ end
41
+ end
42
+
43
+ hash = JSON.parse(json).extend(Methodize)
44
+
45
+ assert_equal nil , hash.empty_value
46
+ end
47
+
48
+ def test_root_set_on_builder
49
+ obj = [{ :foo => "bar" }, { :foo => "zue" }]
50
+ json = Hypertemplate::Builder::Json.build(obj, :root => "foos") do |collection|
51
+ collection.values do |values|
52
+ values.id "an_id"
53
+ end
54
+
55
+ collection.members do |member, some_foos|
56
+ member.values do |values|
57
+ values.id some_foos[:foo]
58
+ end
59
+ end
60
+ end
61
+
62
+ hash = JSON.parse(json).extend(Methodize)
63
+
64
+ assert hash.has_key?("foos")
65
+ assert_equal "an_id", hash.foos.id
66
+ assert_equal "bar" , hash.foos.members.first.id
67
+ end
68
+
69
+ def test_collection_set_on_members
70
+ obj = { :foo => "bar" }
71
+ a_collection = [1,2,3,4]
72
+ json = Hypertemplate::Builder::Json.build(obj) do |collection|
73
+ collection.values do |values|
74
+ values.id "an_id"
75
+ end
76
+
77
+ collection.members(:collection => a_collection) do |member, number|
78
+ member.values do |values|
79
+ values.id number
80
+ end
81
+ end
82
+ end
83
+
84
+ hash = JSON.parse(json).extend(Methodize)
85
+
86
+ assert_equal "an_id", hash.id
87
+ assert_equal 1 , hash.members.first.id
88
+ assert_equal 4 , hash.members.size
89
+ end
90
+
91
+ def test_collection_set_on_members_only_one
92
+ obj = { :foo => "bar" }
93
+ a_collection = [1]
94
+ json = Hypertemplate::Builder::Json.build(obj) do |collection|
95
+ collection.values do |values|
96
+ values.id "an_id"
97
+ end
98
+
99
+ collection.members(:collection => a_collection) do |member, number|
100
+ member.values do |values|
101
+ values.id number
102
+ end
103
+ end
104
+ end
105
+
106
+ hash = JSON.parse(json).extend(Methodize)
107
+
108
+ assert_equal "an_id", hash.id
109
+ assert_equal 1 , hash.members.first.id
110
+ assert_equal 1 , hash.members.size
111
+ assert hash.members.kind_of?(Array)
112
+ end
113
+
114
+ def test_raise_exception_for_not_passing_a_collection_as_parameter_to_members
115
+ obj = 42
116
+
117
+ assert_raise Hypertemplate::BuilderError do
118
+ json = Hypertemplate::Builder::Json.build(obj) do |collection, number|
119
+ collection.values do |values|
120
+ values.id number
121
+ end
122
+
123
+ collection.members do |member, item|
124
+ member.values do |values|
125
+ values.id item
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
131
+
132
+ def test_root_set_on_members
133
+ obj = [{ :foo => "bar" }, { :foo => "zue" }]
134
+ json = Hypertemplate::Builder::Json.build(obj) do |collection|
135
+ collection.values do |values|
136
+ values.id "an_id"
137
+ end
138
+
139
+ collection.members(:root => "foos") do |member, some_foos|
140
+ member.values do |values|
141
+ values.id some_foos[:foo]
142
+ end
143
+ end
144
+ end
145
+
146
+ hash = JSON.parse(json).extend(Methodize)
147
+
148
+ assert_equal "an_id", hash.id
149
+ assert_equal "bar" , hash.foos.first.id
150
+ assert_equal 2 , hash.foos.size
151
+ end
152
+
153
+ def test_nesting_values_should_build_an_entire_tree
154
+ obj = [{ :foo => "bar" }, { :foo => "zue" }]
155
+ json = Hypertemplate::Builder::Json.build(obj) do |collection|
156
+ collection.values do |values|
157
+ values.body {
158
+ values.face {
159
+ values.eyes "blue"
160
+ values.mouth "large"
161
+ }
162
+ values.legs [
163
+ { :right => { :fingers_count => 5 } }, { :left => { :fingers_count => 4 } }
164
+ ]
165
+ }
166
+ end
167
+ end
168
+
169
+ hash = JSON.parse(json).extend(Methodize)
170
+
171
+ assert_equal "blue" , hash.body.face.eyes
172
+ assert_equal "large", hash.body.face.mouth
173
+ assert_equal 2 , hash.body.legs.count
174
+ assert_equal 4 , hash.body.legs.last.left.fingers_count
175
+ end
176
+
177
+ def test_build_single_link_in_collection_and_member
178
+ obj = [{ :foo => "bar" }]
179
+ json = Hypertemplate::Builder::Json.build(obj) do |collection|
180
+ collection.values do |values|
181
+ values.id "an_id"
182
+ end
183
+
184
+ collection.link 'self', "http://example.com/an_id"
185
+
186
+ collection.members do |member, some_foos|
187
+ member.values do |values|
188
+ values.id some_foos[:foo]
189
+ end
190
+
191
+ member.link 'self', "http://example.com/an_id/#{some_foos[:foo]}"
192
+ end
193
+ end
194
+
195
+ hash = JSON.parse(json).extend(Methodize)
196
+
197
+ assert_equal "an_id", hash.id
198
+ assert_equal "bar" , hash.members.first.id
199
+ assert hash.members.kind_of?(Array)
200
+ assert hash.link.kind_of?(Array)
201
+ assert hash.members.first.link.kind_of?(Array)
202
+ end
203
+
204
+ def test_build_full_collection
205
+ time = Time.now
206
+ some_articles = [
207
+ {:id => 1, :title => "a great article", :updated => time},
208
+ {:id => 2, :title => "another great article", :updated => time}
209
+ ]
210
+
211
+ json = Hypertemplate::Builder::Json.build(some_articles) do |collection|
212
+ collection.values do |values|
213
+ values.id "http://example.com/json"
214
+ values.title "Feed"
215
+ values.updated time
216
+
217
+ values.author {
218
+ values.name "John Doe"
219
+ values.email "joedoe@example.com"
220
+ }
221
+
222
+ values.author {
223
+ values.name "Foo Bar"
224
+ values.email "foobar@example.com"
225
+ }
226
+ end
227
+
228
+ collection.link("next" , "http://a.link.com/next")
229
+ collection.link("previous", "http://a.link.com/previous")
230
+
231
+ collection.members(:root => "articles") do |member, article|
232
+ member.values do |values|
233
+ values.id "uri:#{article[:id]}"
234
+ values.title article[:title]
235
+ values.updated article[:updated]
236
+ end
237
+
238
+ member.link("image", "http://example.com/image/1")
239
+ member.link("image", "http://example.com/image/2", :type => "application/json")
240
+ end
241
+ end
242
+
243
+ hash = JSON.parse(json).extend(Methodize)
244
+
245
+ assert_equal "John Doe" , hash.author.first.name
246
+ assert_equal "foobar@example.com" , hash.author.last.email
247
+ assert_equal "http://example.com/json", hash.id
248
+
249
+ assert_equal "http://a.link.com/next" , hash.link.first.href
250
+ assert_equal "next" , hash.link.first.rel
251
+ assert_equal "application/json" , hash.link.last.type
252
+
253
+ assert_equal "uri:1" , hash.articles.first.id
254
+ assert_equal "a great article" , hash.articles.first.title
255
+ assert_equal "http://example.com/image/1" , hash.articles.last.link.first.href
256
+ assert_equal "image" , hash.articles.last.link.first.rel
257
+ assert_equal "application/json" , hash.articles.last.link.last.type
258
+ end
259
+
260
+ def test_build_full_member
261
+ time = Time.now
262
+ an_article = {:id => 1, :title => "a great article", :updated => time}
263
+
264
+ json = Hypertemplate::Builder::Json.build(an_article, :root => "article") do |member, article|
265
+ member.values do |values|
266
+ values.id "uri:#{article[:id]}"
267
+ values.title article[:title]
268
+ values.updated article[:updated]
269
+
270
+ values.domain("xmlns" => "http://a.namespace.com") {
271
+ member.link("image", "http://example.com/image/1")
272
+ member.link("image", "http://example.com/image/2", :type => "application/atom+xml")
273
+ }
274
+ end
275
+
276
+ member.link("image", "http://example.com/image/1")
277
+ member.link("image", "http://example.com/image/2", :type => "application/json")
278
+ end
279
+
280
+ hash = JSON.parse(json).extend(Methodize)
281
+
282
+ assert_equal "uri:1" , hash.article.id
283
+ assert_equal "a great article" , hash.article.title
284
+ assert_equal "http://example.com/image/1" , hash.article.link.first.href
285
+ assert_equal "image" , hash.article.link.first.rel
286
+ assert_equal "application/json" , hash.article.link.first.type
287
+
288
+ assert_equal "http://example.com/image/1" , hash.article.domain.link.first.href
289
+ assert_equal "image" , hash.article.domain.link.first.rel
290
+ assert_equal "application/json" , hash.article.domain.link.first.type
291
+ assert_equal "http://a.namespace.com" , hash.article.domain.xmlns
292
+ end
293
+ end
294
+
295
+
296
+
297
+ class Hypertemplate::Builder::JsonLambdaTest < Test::Unit::TestCase
298
+
299
+ def json_build_and_parse(obj = {}, options = {}, &block)
300
+ block ||= lambda {}
301
+ json = Hypertemplate::Builder::Json.build_dsl(obj, options, &block)
302
+ JSON.parse(json).extend(Methodize)
303
+ end
304
+
305
+ def test_accepts_custom_values
306
+ json = json_build_and_parse do
307
+ name "david"
308
+ end
309
+
310
+ assert_equal "david", json["name"]
311
+ end
312
+
313
+ def test_supports_any_attribute_by_using_the_write_method
314
+ json = json_build_and_parse do
315
+ write :to_s , "22"
316
+ end
317
+
318
+ assert_equal "22", json["to_s"]
319
+ end
320
+
321
+ def test_id_method_is_also_accepted
322
+ json = json_build_and_parse do
323
+ id "22"
324
+ end
325
+
326
+ assert_equal "22", json["id"]
327
+ end
328
+
329
+ def test_allows_iterating_over_a_collection
330
+ items = [{ :name => "pencil" }]
331
+ json = json_build_and_parse do
332
+ each(items) do |item|
333
+ name item[:name]
334
+ end
335
+ end
336
+
337
+ assert_equal "pencil" , json["members"][0]["name"]
338
+ end
339
+
340
+ def test_allows_iterating_over_a_collection_of_strings
341
+ items = ["pencil", "eraser"]
342
+ json = json_build_and_parse do
343
+ items.each do |item|
344
+ name item
345
+ end
346
+ end
347
+
348
+ assert_equal "pencil" , json["name"][0]
349
+ assert_equal "eraser" , json["name"][1]
350
+ end
351
+
352
+ def test_allows_collection_custom_member_name
353
+ items = [{ :name => "pencil" }]
354
+ json = json_build_and_parse do
355
+ each(items, :root => "item") do |item|
356
+ name item[:name]
357
+ end
358
+ end
359
+
360
+ assert_equal "pencil" , json["item"][0]["name"]
361
+ end
362
+
363
+ def test_allows_typical_usage_of_a_collection
364
+ items = [{ :name => "pencil" }, { :name => "eraser"}]
365
+ json = json_build_and_parse do
366
+ items {
367
+ each(items, :root => "item") do |item|
368
+ name item[:name]
369
+ end
370
+ }
371
+ end
372
+
373
+ assert_equal "pencil" , json["items"]["item"][0]["name"]
374
+ assert_equal "eraser" , json["items"]["item"][1]["name"]
375
+ end
376
+
377
+ def test_supports_custom_root_with_collections
378
+ items = [{ :name => "pencil" }, { :name => "eraser"}]
379
+ json = json_build_and_parse({}, :root => "items") do
380
+ each(items, :root => "item") do |item|
381
+ name item[:name]
382
+ end
383
+ end
384
+
385
+ assert_equal "pencil" , json["items"]["item"][0]["name"]
386
+ assert_equal "eraser" , json["items"]["item"][1]["name"]
387
+ end
388
+
389
+ def test_uses_outside_scope_when_passing_an_arg_to_the_builder
390
+ helper = Object.new
391
+ def helper.name
392
+ "guilherme"
393
+ end
394
+ json = json_build_and_parse(helper) do |s|
395
+ name s.name
396
+ end
397
+
398
+ assert_equal "guilherme", json["name"]
399
+ end
400
+
401
+ def test_uses_externally_declared_objects_if_accessible
402
+ obj = { :category => "esporte" }
403
+ json = json_build_and_parse do |s|
404
+ categoria obj[:category]
405
+ end
406
+
407
+ assert_equal "esporte", json["categoria"]
408
+ end
409
+
410
+ def test_accepts_nested_elements
411
+ json = json_build_and_parse do
412
+ body {
413
+ face {
414
+ eyes "blue"
415
+ mouth "large"
416
+ }
417
+ }
418
+ end
419
+
420
+ assert_equal "blue" , json["body"]["face"]["eyes"]
421
+ assert_equal "large", json["body"]["face"]["mouth"]
422
+ end
423
+
424
+ def test_supports_collection_with_all_internals
425
+ time = Time.now
426
+ some_articles = [
427
+ {:id => 1, :title => "a great article", :updated => time},
428
+ {:id => 2, :title => "another great article", :updated => time}
429
+ ]
430
+
431
+ json = json_build_and_parse do
432
+ id "http://example.com/json"
433
+ title "Feed"
434
+ updated time
435
+
436
+ author {
437
+ name "John Doe"
438
+ email "joedoe@example.com"
439
+ }
440
+
441
+ author {
442
+ name "Foo Bar"
443
+ email "foobar@example.com"
444
+ }
445
+
446
+ link("next" , "http://a.link.com/next")
447
+ link("previous", "http://a.link.com/previous")
448
+
449
+ each(some_articles, :root => "articles") do |article|
450
+ id "uri:#{article[:id]}"
451
+ title article[:title]
452
+ updated article[:updated]
453
+
454
+ link("image", "http://example.com/image/1")
455
+ link("image", "http://example.com/image/2", :type => "application/json")
456
+ end
457
+ end
458
+
459
+ assert_equal "John Doe" , json.author.first.name
460
+ assert_equal "foobar@example.com" , json.author.last.email
461
+ assert_equal "http://example.com/json", json.id
462
+
463
+ assert_equal "http://a.link.com/next" , json.link.first.href
464
+ assert_equal "next" , json.link.first.rel
465
+ assert_equal "application/json" , json.link.last.type
466
+
467
+ assert_equal "uri:1" , json.articles.first["id"]
468
+ assert_equal "a great article" , json.articles.first.title
469
+ assert_equal "http://example.com/image/1" , json.articles.last.link.first.href
470
+ assert_equal "image" , json.articles.last.link.first.rel
471
+ assert_equal "application/json" , json.articles.last.link.last.type
472
+ end
473
+
474
+ def test_build_full_member
475
+ time = Time.now
476
+ an_article = {:id => 1, :title => "a great article", :updated => time}
477
+
478
+ json = json_build_and_parse(nil, :root => "article") do
479
+ id "uri:#{an_article[:id]}"
480
+ title an_article[:title]
481
+ updated an_article[:updated]
482
+
483
+ domain("xmlns" => "http://a.namespace.com") {
484
+ link("image", "http://example.com/image/1")
485
+ link("image", "http://example.com/image/2", :type => "application/atom+xml")
486
+ }
487
+
488
+ link("image", "http://example.com/image/1")
489
+ link("image", "http://example.com/image/2", :type => "application/json")
490
+ end
491
+
492
+ assert_equal "uri:1" , json.article.id
493
+ assert_equal "a great article" , json.article.title
494
+ assert_equal "http://example.com/image/1" , json.article.link.first.href
495
+ assert_equal "image" , json.article.link.first.rel
496
+ assert_equal "application/json" , json.article.link.first.type
497
+
498
+ assert_equal "http://example.com/image/1" , json.article.domain.link.first.href
499
+ assert_equal "image" , json.article.domain.link.first.rel
500
+ assert_equal "application/json" , json.article.domain.link.first.type
501
+ assert_equal "http://a.namespace.com" , json.article.domain.xmlns
502
+ end
503
+
504
+ end
505
+
506
+