bldr 0.2.0 → 0.3.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.
@@ -1,6 +1,5 @@
1
1
  rvm:
2
2
  - 1.8.7
3
- - 1.9.1
4
3
  - 1.9.2
5
4
  - ree
6
5
  - ruby-head
data/README.md CHANGED
@@ -290,6 +290,24 @@ get '/posts' do
290
290
  end
291
291
  ```
292
292
 
293
+ ### Custom Handlers
294
+
295
+ Bldr supports the definition of custom handlers, based on the class of specific
296
+ values in the result. You would make use of this to define how specific classes
297
+ are rendered by Bldr at a global level.
298
+
299
+ For example, the `BSON::ObjectId` class defines `to_json` and `as_json` methods
300
+ that produce a result like the following: `{"$oid": "4e77a682364141ecf5000002"}`.
301
+ If you wanted to over-ride this default format, you could do so by defining a
302
+ custom handler:
303
+
304
+ ```ruby
305
+ # place in a file that get's loaded before your application code
306
+ Bldr.handler BSON::ObjectId do |val|
307
+ val.to_s # => "4e77a682364141ecf5000002"
308
+ end
309
+ ```
310
+
293
311
  ## Editor Syntax Support
294
312
 
295
313
  To get proper syntax highlighting in vim, add this line to your .vimrc:
@@ -8,8 +8,29 @@ require 'bldr/node'
8
8
 
9
9
  module Bldr
10
10
  class << self
11
+
11
12
  def json_encoder=(encoder)
12
13
  MultiJson.engine = encoder
13
14
  end
15
+
16
+ # Define a custom handler.
17
+ #
18
+ # @example Over-riding BSON::ObjectId
19
+ # Bldr.handler BSON::ObjectId do |value|
20
+ # val.to_s # => "4e77a682364141ecf5000002"
21
+ # end
22
+ #
23
+ # @param [Class] klass The klass name of the class to match
24
+ # @param [Proc] block The code to execute to properly format the data
25
+ def handler(klass,&block)
26
+ raise(ArgumentError, "You must pass a Proc") if block.nil?
27
+ raise(ArgumentError, "You must pass only one argument to the Proc") unless block.arity == 1
28
+
29
+ handlers[klass] = block
30
+ end
31
+
32
+ def handlers
33
+ @handlers ||= {}
34
+ end
14
35
  end
15
36
  end
@@ -7,6 +7,7 @@ module Bldr
7
7
  def initialize(template, options = {})
8
8
  @template, @options = template, options
9
9
  @result = {}
10
+ @handlers = {}
10
11
  end
11
12
 
12
13
  end
@@ -177,14 +177,24 @@ module Bldr
177
177
  # Merges values into the "local" result hash.
178
178
  def merge_result!(key, val)
179
179
  if key
180
- result[key] = val
180
+ result[key] = massage_value(val)
181
181
  else
182
- result.merge!(val)
182
+ result.merge!(massage_value(val))
183
183
  end
184
184
  end
185
185
 
186
186
  def append_result!(key, val)
187
- result[key] << val
187
+ result[key] << massage_value(val)
188
+ end
189
+
190
+ # put any specializations in here
191
+ # @todo: add config handlers to specify your own overridable Class->lambda methods of serialization
192
+ def massage_value(val)
193
+ if block = Bldr.handlers[val.class]
194
+ return block.call(val)
195
+ else
196
+ val
197
+ end
188
198
  end
189
199
 
190
200
  end
@@ -1,4 +1,4 @@
1
1
 
2
2
  module Bldr
3
- VERSION = '0.2.0'
3
+ VERSION = '0.3.0'
4
4
  end
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ output = `ruby -r bench_press ./benchmark.rb`
4
+
5
+ results = File.open(File.expand_path(File.dirname(__FILE__)) + "/results.txt", "a") do |f|
6
+ f.puts "\n"
7
+ f.puts "=" * 80
8
+ f.puts "Spec run time: #{Time.now}"
9
+ f.puts "Git SHA: #{`cat ../.git/\`cat ../.git/HEAD | awk '{print $2}'\``.chomp}"
10
+ f.puts "Latest Tag: #{`git tag | tail -n 1`}"
11
+ f.puts output
12
+ end
@@ -0,0 +1,30 @@
1
+ require 'benchmark'
2
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/bldr')
3
+
4
+ class Person
5
+ attr_reader :name
6
+ def initialize(name)
7
+ @name = name
8
+ end
9
+ end
10
+
11
+ Benchmark.bm(20) do |bm|
12
+ i = 1000
13
+ $guy = Person.new "john"
14
+ $friends = [Person.new("jim"), Person.new("bob")]
15
+ puts "i = #{i}"
16
+
17
+ bm.report "node with collection" do
18
+ i.times do
19
+ Bldr::Node.new do
20
+ object :dude => $guy do
21
+ attributes :name
22
+
23
+ collection :friends => $friends do
24
+ attributes :name
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,16 @@
1
+
2
+ ================================================================================
3
+ Spec run time: 2011-09-09 11:57:07 -0700
4
+ Git SHA: e74a003d8653a4b6cfe0f14e043c554e636f55b5
5
+ Latest Tag: v0.2.0
6
+ user system total real
7
+ i = 1000
8
+ node with collection 0.080000 0.000000 0.080000 ( 0.076949)
9
+
10
+ ================================================================================
11
+ Spec run time: 2011-09-19 13:48:53 -0700
12
+ Git SHA: 09214bfe2c38107ba68dd4c14f17e81d4f5bef72
13
+ Latest Tag: v0.2.0
14
+ user system total real
15
+ i = 1000
16
+ node with collection 0.070000 0.010000 0.080000 ( 0.076655)
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Defining different types of handlers" do
4
+
5
+ describe "Time" do
6
+ it "uses the handler for Time when rendering" do
7
+ Bldr.handler Time do |time|
8
+ "bar"
9
+ end
10
+
11
+ output = "{\"foo\":\"bar\"}"
12
+ node = Bldr::Node.new do
13
+ object { attribute(:foo) { Time.now } }
14
+ end
15
+
16
+ node.to_json.should == output
17
+ end
18
+ end
19
+
20
+ end
@@ -31,6 +31,17 @@ describe "evaluating a tilt template" do
31
31
  })
32
32
  end
33
33
 
34
+ it "renders nil -> null correctly" do
35
+ alex = Person.new('alex')
36
+ tpl = Bldr::Template.new {
37
+ <<-RUBY
38
+ object(:person_1 => alex) { attributes(:age) }
39
+ RUBY
40
+ }
41
+ result = tpl.render(Bldr::Node.new, :alex => alex)
42
+ result.should == %%{"person_1":{"age":null}}%
43
+ end
44
+
34
45
  describe "root Object nodes" do
35
46
 
36
47
  let(:alex) { Person.new('alex', 25) }
@@ -66,6 +77,19 @@ describe "evaluating a tilt template" do
66
77
  }
67
78
  end
68
79
 
80
+ it "renders nil -> null correctly" do
81
+ alex = Person.new('alex')
82
+ tpl = Bldr::Template.new {
83
+ <<-RUBY
84
+ object :person_1 => alex do
85
+ attributes(:age)
86
+ end
87
+ RUBY
88
+ }
89
+ result = tpl.render(Bldr::Node.new, :alex => alex)
90
+ result.should == %%{"person_1":{"age":null}}%
91
+ end
92
+
69
93
  end
70
94
 
71
95
  describe "root Collection nodes" do
@@ -32,4 +32,9 @@ RSpec.configure do |c|
32
32
  result.should == jsonify(hash)
33
33
  end
34
34
 
35
+ c.after do
36
+ Bldr.handlers.clear
37
+ end
38
+
39
+
35
40
  end
@@ -14,4 +14,54 @@ describe "the json encoding library" do
14
14
  Bldr.json_encoder = :json_gem
15
15
  MultiJson.engine.should == MultiJson::Engines::JsonGem
16
16
  end
17
+
18
+ end
19
+
20
+ describe "defining custom handlers" do
21
+
22
+ describe "erroneously" do
23
+
24
+ it "errors when you don't pass a class arg" do
25
+ expect {
26
+ Bldr.handler {|foo| 'foo' }
27
+ }.to raise_error(ArgumentError)
28
+ end
29
+
30
+ it "errors when you don't pass a block" do
31
+ expect {
32
+ Bldr.handler(Object)
33
+ }.to raise_error(ArgumentError, "You must pass a Proc")
34
+ end
35
+
36
+ it "errors when no args are passed to the block" do
37
+ expect {
38
+ Bldr.handler(Object) do
39
+ end
40
+ }.to raise_error(ArgumentError, "You must pass only one argument to the Proc")
41
+ end
42
+
43
+ it "errors when 2 args are passed to the block" do
44
+ expect {
45
+ Bldr.handler(Object) do |one,two|
46
+ end
47
+ }.to raise_error(ArgumentError, "You must pass only one argument to the Proc")
48
+ end
49
+
50
+ end
51
+
52
+ describe "successfully" do
53
+
54
+ it "adds the handler to the collection for the specific Class" do
55
+ Bldr.handler(Object) {|o|}
56
+ Bldr.handlers[Object].should respond_to(:call)
57
+ end
58
+
59
+ it "assigns the lambda passed in" do
60
+ code = lambda {|foo| "foo" }
61
+ Bldr.handler(Time,&code)
62
+ Bldr.handlers[Time].should == code
63
+ end
64
+
65
+ end
66
+
17
67
  end
@@ -71,6 +71,10 @@ describe "Node#object" do
71
71
  }
72
72
  }.to raise_error(ArgumentError, ERROR_MESSAGES[:attribute_inferred_missing_arity_too_large])
73
73
  end
74
+ it "should render null attributes to null, not 'null'" do
75
+ node = wrap { attribute(:name, nil) }
76
+ node.render!.should == {:name => nil}
77
+ end
74
78
 
75
79
  end
76
80
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bldr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-09-09 00:00:00.000000000Z
12
+ date: 2011-09-19 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: multi_json
16
- requirement: &2152503360 !ruby/object:Gem::Requirement
16
+ requirement: &2153229880 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 1.0.3
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2152503360
24
+ version_requirements: *2153229880
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: json_pure
27
- requirement: &2152533900 !ruby/object:Gem::Requirement
27
+ requirement: &2153229460 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *2152533900
35
+ version_requirements: *2153229460
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: sinatra
38
- requirement: &2152533360 !ruby/object:Gem::Requirement
38
+ requirement: &2153228920 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 1.2.6
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *2152533360
46
+ version_requirements: *2153228920
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: tilt
49
- requirement: &2152532860 !ruby/object:Gem::Requirement
49
+ requirement: &2153228420 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 1.3.2
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *2152532860
57
+ version_requirements: *2153228420
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: yajl-ruby
60
- requirement: &2152532480 !ruby/object:Gem::Requirement
60
+ requirement: &2153228040 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,7 +65,7 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *2152532480
68
+ version_requirements: *2153228040
69
69
  description: Provides a simple and intuitive templating DSL for serializing objects
70
70
  to JSON.
71
71
  email:
@@ -89,8 +89,12 @@ files:
89
89
  - lib/bldr/template.rb
90
90
  - lib/bldr/version.rb
91
91
  - lib/sinatra/bldr.rb
92
+ - perf/bench
93
+ - perf/benchmark.rb
94
+ - perf/results.txt
92
95
  - spec/fixtures/nested_objects.json.bldr
93
96
  - spec/fixtures/root_template.json.bldr
97
+ - spec/functional/handlers_spec.rb
94
98
  - spec/functional/tilt_template_spec.rb
95
99
  - spec/integration/sinatra_spec.rb
96
100
  - spec/models/comment.rb
@@ -126,6 +130,7 @@ summary: Templating library with a simple, minimalist DSL.
126
130
  test_files:
127
131
  - spec/fixtures/nested_objects.json.bldr
128
132
  - spec/fixtures/root_template.json.bldr
133
+ - spec/functional/handlers_spec.rb
129
134
  - spec/functional/tilt_template_spec.rb
130
135
  - spec/integration/sinatra_spec.rb
131
136
  - spec/models/comment.rb