birkirb-jsonbuilder 0.0.6

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.
data/ChangeLog ADDED
File without changes
data/README ADDED
@@ -0,0 +1,65 @@
1
+ = jsonbuilder
2
+
3
+ by nov http://github.com/nov <nov@cerego.com> and
4
+ birkirb http://github.com/birkirb
5
+
6
+ == Description
7
+
8
+ == Installation
9
+
10
+ git clone http://github.com/nov/jsonbuilder.git
11
+ cd jsonbuilder
12
+ rake install
13
+
14
+ === Archive Installation
15
+
16
+ rake install
17
+
18
+ === Gem Installation
19
+
20
+ gem install jsonbuilder --source http://gems.rubyforge.org
21
+
22
+ OR for the lastest development version
23
+
24
+ gem install nov-jsonbuilder --source http://gems.github.com
25
+
26
+ == Features/Problems
27
+
28
+ The Hash builder will return a hash structured in a similar way as the corresponding xml
29
+ built by XmlMarkup. The Json builder will return the same kind of hash as a JSON string
30
+
31
+ USAGE:
32
+ def serialize(builder, options = {})
33
+ builder.user(
34
+ :id => id,
35
+ :url => url
36
+ )
37
+ builder.array_mode do
38
+ builder.images do
39
+ package.images.each do |image|
40
+ builder << image.builder(builder.class.new, :only_url => true)
41
+ end
42
+ end
43
+ end
44
+ builder.target!
45
+ end
46
+
47
+ def to_xml(options = {})
48
+ self.serialize(Builder::XMmlMarkup.new, options)
49
+ end
50
+
51
+ def to_hash(options = {})
52
+ self.serialize(Builder::Hash.new, options)
53
+ end
54
+
55
+ def to_json(options = {})
56
+ self.serialize(Builder::Json.new, options)
57
+ end
58
+
59
+ == Synopsis
60
+
61
+ == Copyright
62
+
63
+ Author:: nov <nov@matake.jp> and birkirb
64
+ Copyright:: Copyright (c) 2009 nov
65
+ License:: MIT License
data/Rakefile ADDED
@@ -0,0 +1,134 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/clean'
4
+ require 'rake/testtask'
5
+ require 'rake/packagetask'
6
+ require 'rake/gempackagetask'
7
+ require 'rake/rdoctask'
8
+ require 'rake/contrib/rubyforgepublisher'
9
+ require 'rake/contrib/sshpublisher'
10
+ require 'fileutils'
11
+ include FileUtils
12
+
13
+ NAME = "jsonbuilder"
14
+ AUTHOR = "nov"
15
+ EMAIL = "nov@matake.jp"
16
+ DESCRIPTION = "Builder::XmlMarkup like JsonBuilder (Builder::JsonMarkup)"
17
+ RUBYFORGE_PROJECT = NAME
18
+ HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
19
+ BIN_FILES = %w( )
20
+
21
+ $LOAD_PATH.unshift "#{File.dirname(__FILE__)}/lib"
22
+ require 'lib/jsonbuilder'
23
+ VERS = JsonBuilder::Version.to_version
24
+ CLEAN.include ['*.gem', '.config']
25
+ RDOC_OPTS = [
26
+ "--title", "#{NAME} documentation",
27
+ "--charset", "utf-8",
28
+ "--opname", "index.html",
29
+ "--line-numbers",
30
+ "--main", "README",
31
+ "--inline-source",
32
+ ]
33
+
34
+ task :default => [:spec]
35
+ task :package => [:clean]
36
+
37
+ Rake::TestTask.new("spec") do |t|
38
+ t.libs << "spec"
39
+ t.pattern = "spec/**/*_spec.rb"
40
+ t.verbose = true
41
+ end
42
+
43
+ spec = Gem::Specification.new do |s|
44
+ s.name = NAME
45
+ s.version = VERS
46
+ s.platform = Gem::Platform::RUBY
47
+ s.has_rdoc = true
48
+ s.extra_rdoc_files = ["README", "ChangeLog"]
49
+ s.rdoc_options += RDOC_OPTS + ['--exclude', '^(examples)/']
50
+ s.summary = DESCRIPTION
51
+ s.description = DESCRIPTION
52
+ s.author = AUTHOR
53
+ s.email = EMAIL
54
+ s.homepage = HOMEPATH
55
+ s.executables = BIN_FILES
56
+ s.rubyforge_project = RUBYFORGE_PROJECT
57
+ s.require_path = "lib"
58
+ #s.autorequire = ""
59
+ s.test_files = Dir["spec/*_spec.rb"]
60
+ s.files = %w(README ChangeLog Rakefile) +
61
+ Dir.glob("{spec,lib}/**/*") +
62
+ Dir.glob("examples/**/*.rb")
63
+ s.add_dependency('builder')
64
+ end
65
+
66
+ Rake::GemPackageTask.new(spec) do |p|
67
+ p.need_tar = true
68
+ p.gem_spec = spec
69
+ end
70
+
71
+ desc "Install"
72
+ task :install do
73
+ name = "#{NAME}-#{VERS}.gem"
74
+ sh %{rake package}
75
+ sh %{sudo gem install pkg/#{name}}
76
+ end
77
+
78
+ desc "Uninstall"
79
+ task :uninstall => [:clean] do
80
+ sh %{sudo gem uninstall #{NAME}}
81
+ end
82
+
83
+ Rake::RDocTask.new do |rdoc|
84
+ rdoc.rdoc_dir = 'html'
85
+ rdoc.options += RDOC_OPTS
86
+ rdoc.template = "resh"
87
+ #rdoc.template = "#{ENV['template']}.rb" if ENV['template']
88
+ if ENV['DOC_FILES']
89
+ rdoc.rdoc_files.include(ENV['DOC_FILES'].split(/,\s*/))
90
+ else
91
+ rdoc.rdoc_files.include('README', 'ChangeLog')
92
+ rdoc.rdoc_files.include('lib/**/*.rb')
93
+ end
94
+ end
95
+
96
+ desc "Publish to RubyForge"
97
+ task :rubyforge => [:rdoc, :package] do
98
+ require 'rubyforge'
99
+ Rake::RubyForgePublisher.new(RUBYFORGE_PROJECT, 'nov').upload
100
+ end
101
+
102
+ # rake release VERSION=x.y.z
103
+ desc 'Package and upload the release to rubyforge.'
104
+ task :release => [:clean, :package] do |t|
105
+ v = ENV["VERSION"] or abort "Must supply VERSION=x.y.z"
106
+ abort "Versions don't match #{v} vs #{VERS}" unless v == VERS
107
+ pkg = "pkg/#{NAME}-#{VERS}"
108
+
109
+ require 'rubyforge'
110
+ rf = RubyForge.new.configure
111
+ puts "Logging in"
112
+ rf.login
113
+
114
+ c = rf.userconfig
115
+ c["preformatted"] = true
116
+
117
+ files = [
118
+ "#{pkg}.tgz",
119
+ "#{pkg}.gem"
120
+ ].compact
121
+
122
+ puts "Releasing #{NAME} v. #{VERS}"
123
+ rf.add_release RUBYFORGE_PROJECT, NAME, VERS, *files
124
+ end
125
+
126
+ desc 'Show information about the gem.'
127
+ task :debug_gem do
128
+ puts spec.to_ruby
129
+ end
130
+
131
+ desc 'Update gem spec'
132
+ task :gemspec do
133
+ open("#{NAME}.gemspec", 'w').write spec.to_ruby
134
+ end
@@ -0,0 +1,23 @@
1
+ module Builder
2
+
3
+ class Abstract
4
+ def nil?
5
+ false
6
+ end
7
+
8
+ def target!
9
+ end
10
+
11
+ def comment!
12
+ end
13
+
14
+ def declare!
15
+ end
16
+
17
+ def instruct!
18
+ end
19
+
20
+ def comment!
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,106 @@
1
+ module Builder
2
+ class Hash < Abstract
3
+
4
+ def initialize(options = {})
5
+ # @default_content_key is used in such case: markup.key(value, :attr_key => attr_value)
6
+ # in this case, we need some key for value.
7
+ @default_content_key = (options[:default_content_key] || :content).to_sym
8
+ @include_root = options[:include_root]
9
+ @target = {}
10
+ @array_mode = false
11
+ end
12
+
13
+ # NOTICE: you have to call this method to use array in json
14
+ def array_mode(key = nil, &block)
15
+ raise RuntimeError.new("cannot call inside array_mode block") if @array_mode
16
+ @array_mode = true
17
+ if eval("#{_current}").is_a?(::Hash)
18
+ key ||= :entry
19
+ eval("#{_current}.merge!(key => [])")
20
+ @path.push(key.to_sym)
21
+ yield(self)
22
+ @path.pop
23
+ else
24
+ eval("#{_current} = []")
25
+ yield(self)
26
+ end
27
+ @array_mode = false
28
+ end
29
+
30
+ def target!
31
+ if @include_root
32
+ @target
33
+ else
34
+ @target[@root]
35
+ end
36
+ end
37
+
38
+ def <<(_target)
39
+ if @array_mode
40
+ eval("#{_current} << _target")
41
+ else
42
+ eval("#{_current} ||= {}")
43
+ eval("#{_current}.merge!(_target)")
44
+ end
45
+ end
46
+
47
+ def text!(text)
48
+ raise RuntimeError.new("cannot call inside array_mode block") if @array_mode
49
+ if eval("#{_current}").is_a?(::Hash)
50
+ eval("#{_current}.merge!({@default_content_key => text})")
51
+ else
52
+ eval("#{_current} = text")
53
+ end
54
+ end
55
+ alias_method :cdata!, :text!
56
+
57
+ def tag!(key, *attrs, &block)
58
+ method_missing(key, *args, &block)
59
+ end
60
+
61
+ def method_missing(key, *args, &block)
62
+ key = args.first.is_a?(Symbol) ? "#{key}:#{args.shift}".to_sym : key.to_sym
63
+ args[0] = {@default_content_key => args[0]} if args.size > 1 && !args[0].is_a?(::Hash)
64
+ unless @root
65
+ _root(key, args, &block)
66
+ else
67
+ _child(key, args, &block)
68
+ end
69
+ target!
70
+ end
71
+
72
+ private
73
+
74
+ def _root(root, args, &block)
75
+ @root = root
76
+ @target[root] = {}
77
+ @path = [root]
78
+ _set_args(args, &block)
79
+ yield(self) if block_given?
80
+ end
81
+
82
+ def _child(key, args, &block)
83
+ eval("#{_current} ||= {}")
84
+ @path.push(key)
85
+ _set_args(args, &block)
86
+ @path.pop
87
+ end
88
+
89
+ def _set_args(args, &block)
90
+ args.each do |arg|
91
+ case arg
92
+ when ::Hash
93
+ self << arg
94
+ else
95
+ eval("#{_current} = arg")
96
+ end
97
+ end
98
+ yield(self) if block_given?
99
+ end
100
+
101
+ def _current
102
+ "@target[:\"#{@path.join('"][:"')}\"]"
103
+ end
104
+
105
+ end
106
+ end
@@ -0,0 +1,25 @@
1
+ require 'json'
2
+
3
+ module Builder
4
+
5
+ class Json < Hash
6
+
7
+ def initialize(options = {})
8
+ # @default_content_key is used in such case: markup.key(value, :attr_key => attr_value)
9
+ # in this case, we need some key for value.
10
+ @default_content_key = (options[:default_content_key] || :content).to_sym
11
+ @include_root = options[:include_root]
12
+ @target = {}
13
+ @array_mode = false
14
+ end
15
+
16
+ def target!
17
+ if @include_root
18
+ @target.to_json
19
+ else
20
+ @target[@root].to_json
21
+ end
22
+ end
23
+ end
24
+
25
+ end
@@ -0,0 +1,9 @@
1
+ module Builder
2
+ class XmlMarkup
3
+
4
+ # Add this no-op
5
+ def array_mode(key = nil, &block)
6
+ yield(self)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,21 @@
1
+ module JsonBuilder
2
+ module Version
3
+ MAJOR = 0
4
+ MINOR = 0
5
+ REVISION = 6
6
+ class << self
7
+ def to_version
8
+ "#{MAJOR}.#{MINOR}.#{REVISION}"
9
+ end
10
+
11
+ def to_name
12
+ "#{MAJOR}_#{MINOR}_#{REVISION}"
13
+ end
14
+ end
15
+ end
16
+ end
17
+
18
+ require 'builder/abstract'
19
+ require 'builder/hash'
20
+ require 'builder/xml_markup'
21
+ require 'builder/json'
@@ -0,0 +1,218 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
+
3
+ describe Builder::Hash, ".new" do
4
+ it "should be accessible" do
5
+ Builder::Hash.should respond_to(:new)
6
+ end
7
+ end
8
+
9
+ describe Builder::Hash do
10
+
11
+ it "should remove the root tag" do
12
+ builder = Builder::Hash.new
13
+ # XML :: <root><tag>value</tag></root>
14
+ builder.root do
15
+ builder.tag "value"
16
+ end
17
+ builder.target!.should == {:tag => "value"}
18
+ end
19
+
20
+ it "should not remove the root tag when include_root is true" do
21
+ builder = Builder::Hash.new(:include_root => true)
22
+ # XML :: <root><tag>value</tag></root>
23
+ builder.root do
24
+ builder.tag "value"
25
+ end
26
+ builder.target!.should == {:root => {:tag => "value"}}
27
+ end
28
+
29
+ it "should use the default_content_key when both content and attributes exist" do
30
+ builder = Builder::Hash.new
31
+ # XML :: <root><tag id="1">value</tag></root>
32
+ builder.root do
33
+ builder.tag("value", :id => 1)
34
+ end
35
+ builder.target!.should == {:tag => {:id => 1, :content => "value"}}
36
+ end
37
+
38
+ it "should use the default_content_key when both cdata! and attributes exist" do
39
+ builder = Builder::Hash.new
40
+ # XML :: <root><tag id="1"><![CDATA[value]]></tag></root>
41
+ builder.root do
42
+ builder.tag(:id => 1) do
43
+ builder.cdata! "value"
44
+ end
45
+ end
46
+ builder.target!.should == {:tag => {:id => 1, :content => "value"}}
47
+ end
48
+
49
+ end
50
+
51
+ describe Builder::Hash, "#target!" do
52
+
53
+ it "should return a String when there is only a root value" do
54
+ builder = Builder::Hash.new
55
+ builder.root("value")
56
+ builder.target!.should == "value"
57
+ end
58
+
59
+ it "should return a Hash when there is only a root value and include_root option is true" do
60
+ builder = Builder::Hash.new(:include_root => true)
61
+ # XML :: <root>value</root>
62
+ builder.root "value"
63
+ builder.target!.should == {:root => "value"}
64
+ end
65
+
66
+
67
+ it "should return a Hash when root has deeper structure" do
68
+ builder = Builder::Hash.new
69
+ builder.root do
70
+ builder.item("value")
71
+ end
72
+ builder.target!.should == {:item => 'value'}
73
+ end
74
+
75
+ end
76
+
77
+ describe Builder::Hash, "#array_mode" do
78
+
79
+ it "should support <<(hash)" do
80
+ builder = Builder::Hash.new
81
+ # XML ::
82
+ # <root>
83
+ # <items>
84
+ # <item>
85
+ # <text>hello world 0</text>
86
+ # </item>
87
+ # <item>
88
+ # <text>hello world 1</text>
89
+ # </item>
90
+ # </items>
91
+ # </root>
92
+ builder.root do
93
+ builder.items do
94
+ builder.array_mode do
95
+ 2.times do |i|
96
+ _builder = Builder::Hash.new
97
+ builder << _builder.item do
98
+ _builder.text "hello world #{i}"
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
104
+ builder.target!.should == {
105
+ :items => [{:text => "hello world 0"}, {:text => "hello world 1"}]
106
+ }
107
+ end
108
+
109
+ it "should generate a new key if needed" do
110
+ builder = Builder::Hash.new
111
+ # XML ::
112
+ # <root>
113
+ # <items site="smart.fm">
114
+ # <item>
115
+ # <text>hello world 0</text>
116
+ # </item>
117
+ # <item>
118
+ # <text>hello world 1</text>
119
+ # </item>
120
+ # </items>
121
+ # </root>
122
+ builder.root do
123
+ builder.items(:site => "smart.fm") do
124
+ builder.array_mode do
125
+ 2.times do |i|
126
+ _builder = Builder::Hash.new
127
+ builder << _builder.item do
128
+ _builder.text "hello world #{i}"
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
134
+ builder.target!.should == {
135
+ :items => {
136
+ :entry => [{:text => "hello world 0"}, {:text=>"hello world 1"}],
137
+ :site=>"smart.fm"
138
+ }
139
+ }
140
+ end
141
+
142
+ it "should treat an empty block as a blank Array" do
143
+ # XML ::
144
+ # <root>
145
+ # <items>
146
+ # </items>
147
+ # </root>
148
+ builder = Builder::Hash.new
149
+ builder.root do
150
+ builder.items do
151
+ builder.array_mode do
152
+ end
153
+ end
154
+ end
155
+ builder.target!.should == {:items => []}
156
+ end
157
+
158
+ it "should raise error if tag methods (method_missing) is used inside block"do
159
+ builder = Builder::Hash.new
160
+ builder.root do
161
+ builder.items do
162
+ lambda do
163
+ builder.array_mode do
164
+ builder.item("hello world")
165
+ end
166
+ end.should raise_error
167
+ lambda do
168
+ builder.array_mode do
169
+ builder.item do
170
+ builder.text("hello world")
171
+ end
172
+ end
173
+ end.should raise_error
174
+ end
175
+ end
176
+ end
177
+
178
+ it "should raise error if tag! is used inside block"do
179
+ builder = Builder::Hash.new
180
+ builder.root do
181
+ builder.items do
182
+ lambda do
183
+ builder.array_mode do
184
+ builder.tag!("item", "item1")
185
+ end
186
+ end.should raise_error
187
+ end
188
+ end
189
+ end
190
+
191
+ it "should raise error if cdata! (or text!) is used inside block"do
192
+ builder = Builder::Hash.new
193
+ builder.root do
194
+ builder.items do
195
+ lambda do
196
+ builder.array_mode do
197
+ builder.cdata!("text")
198
+ end
199
+ end.should raise_error
200
+ end
201
+ end
202
+ end
203
+
204
+ it "should raise error if array_mode is used inside block"do
205
+ builder = Builder::Hash.new
206
+ builder.root do
207
+ builder.items do
208
+ lambda do
209
+ builder.array_mode do
210
+ builder.array_mode do
211
+ end
212
+ end
213
+ end.should raise_error
214
+ end
215
+ end
216
+ end
217
+
218
+ end
@@ -0,0 +1,26 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
+
3
+ describe Builder::Json, ".new" do
4
+ it "should be accessible" do
5
+ Builder::Hash.should respond_to(:new)
6
+ end
7
+ end
8
+
9
+ describe Builder::Json, "#target!" do
10
+
11
+ it "should return a String when there is only a root value" do
12
+ builder = Builder::Hash.new
13
+ builder.root("value")
14
+ builder.target!.should be_a(String)
15
+ end
16
+
17
+ it "should return a JSON string when root has deeper structure" do
18
+ builder = Builder::Json.new
19
+ builder.root do
20
+ builder.item("value")
21
+ end
22
+ builder.target!.should be_a(String)
23
+ builder.target!.should =="{\"item\":\"value\"}"
24
+ end
25
+
26
+ end
@@ -0,0 +1,19 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
+
3
+ describe Builder::XmlMarkup, "#array_mode" do
4
+
5
+ it "should do nothing" do
6
+ builder = Builder::XmlMarkup.new
7
+ builder.root do
8
+ builder.array_mode do
9
+ builder.item("value")
10
+ end
11
+ end
12
+ builder2 = Builder::XmlMarkup.new
13
+ builder2.root do
14
+ builder2.item("value")
15
+ end
16
+ builder.target!.should == builder2.target!
17
+ end
18
+
19
+ end
@@ -0,0 +1,13 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe JsonBuilder::Version, "#to_version" do
4
+ it "should return version in 'X.Y.Z' format" do
5
+ JsonBuilder::Version.to_version.should =~ /\d+\.\d+\.\d+/
6
+ end
7
+ end
8
+
9
+ describe JsonBuilder::Version, "#to_name" do
10
+ it "should return version in 'X_Y_Z' format" do
11
+ JsonBuilder::Version.to_name.should =~ /\d+_\d+_\d+/
12
+ end
13
+ end
@@ -0,0 +1,10 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ gem 'rspec'
6
+ require 'spec'
7
+ end
8
+ $LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), "..", "lib")))
9
+ require 'builder'
10
+ require 'jsonbuilder'
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: birkirb-jsonbuilder
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.6
5
+ platform: ruby
6
+ authors:
7
+ - nov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-06-08 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: builder
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ description: Builder::XmlMarkup like JsonBuilder (Builder::JsonMarkup)
26
+ email: nov@matake.jp
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - README
33
+ - ChangeLog
34
+ files:
35
+ - README
36
+ - ChangeLog
37
+ - Rakefile
38
+ - spec/builder
39
+ - spec/builder/hash_spec.rb
40
+ - spec/builder/json_spec.rb
41
+ - spec/builder/xml_markup_spec.rb
42
+ - spec/jsonbuilder_spec.rb
43
+ - spec/spec_helper.rb
44
+ - lib/builder
45
+ - lib/builder/abstract.rb
46
+ - lib/builder/hash.rb
47
+ - lib/builder/json.rb
48
+ - lib/builder/xml_markup.rb
49
+ - lib/jsonbuilder.rb
50
+ has_rdoc: true
51
+ homepage: http://jsonbuilder.rubyforge.org
52
+ post_install_message:
53
+ rdoc_options:
54
+ - --title
55
+ - jsonbuilder documentation
56
+ - --charset
57
+ - utf-8
58
+ - --opname
59
+ - index.html
60
+ - --line-numbers
61
+ - --main
62
+ - README
63
+ - --inline-source
64
+ - --exclude
65
+ - ^(examples)/
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: "0"
73
+ version:
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: "0"
79
+ version:
80
+ requirements: []
81
+
82
+ rubyforge_project: jsonbuilder
83
+ rubygems_version: 1.2.0
84
+ signing_key:
85
+ specification_version: 2
86
+ summary: Builder::XmlMarkup like JsonBuilder (Builder::JsonMarkup)
87
+ test_files:
88
+ - spec/jsonbuilder_spec.rb