birkirb-jsonbuilder 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
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