json_builder 2.0.6 → 3.0.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.
- data/.gitignore +4 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +122 -0
- data/README.md +221 -59
- data/Rakefile +26 -0
- data/lib/json_builder.rb +1 -1
- data/lib/json_builder/compiler.rb +63 -0
- data/lib/json_builder/elements.rb +17 -0
- data/lib/json_builder/member.rb +24 -0
- data/lib/json_builder/template.rb +40 -14
- data/lib/json_builder/value.rb +30 -0
- data/lib/json_builder/version.rb +1 -1
- data/spec/benchmarks/builder.rb +60 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/controllers/users_controller.rb +5 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/helpers/users_helper.rb +2 -0
- data/spec/dummy/app/models/user.rb +9 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/app/views/users/index.json_builder +3 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +45 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +22 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +26 -0
- data/spec/dummy/config/environments/production.rb +49 -0
- data/spec/dummy/config/environments/test.rb +35 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +5 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/20111127061428_create_users.rb +14 -0
- data/spec/dummy/db/schema.rb +23 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/javascripts/application.js +2 -0
- data/spec/dummy/public/javascripts/controls.js +965 -0
- data/spec/dummy/public/javascripts/dragdrop.js +974 -0
- data/spec/dummy/public/javascripts/effects.js +1123 -0
- data/spec/dummy/public/javascripts/prototype.js +6001 -0
- data/spec/dummy/public/javascripts/rails.js +191 -0
- data/spec/dummy/public/stylesheets/.gitkeep +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/dummy/spec/controllers/users_controller_spec.rb +14 -0
- data/spec/integration/navigation_spec.rb +9 -0
- data/spec/json_builder_spec.rb +7 -0
- data/spec/spec_helper.rb +34 -0
- data/spec/support/json_builder.rb +7 -0
- data/spec/unit/json_builder_spec.rb +76 -0
- metadata +158 -93
- data/lib/json_builder/generator.rb +0 -127
- data/test/benchmarks/speed.rb +0 -85
- data/test/fixtures/simple.rb +0 -27
- data/test/test_helper.rb +0 -4
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'rubygems'
|
3
|
+
begin
|
4
|
+
require 'bundler/setup'
|
5
|
+
Bundler::GemHelper.install_tasks
|
6
|
+
rescue LoadError
|
7
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'rake'
|
11
|
+
require 'rake/task'
|
12
|
+
|
13
|
+
require 'rspec/core'
|
14
|
+
require 'rspec/core/rake_task'
|
15
|
+
|
16
|
+
RSpec::Core::RakeTask.new(:spec)
|
17
|
+
|
18
|
+
task :default => :spec
|
19
|
+
|
20
|
+
# Rake::Task.new(:rdoc) do |rdoc|
|
21
|
+
# rdoc.rdoc_dir = 'rdoc'
|
22
|
+
# rdoc.title = 'JsonBuilder'
|
23
|
+
# rdoc.options << '--line-numbers' << '--inline-source'
|
24
|
+
# rdoc.rdoc_files.include('README.rdoc')
|
25
|
+
# rdoc.rdoc_files.include('lib/**/*.rb')
|
26
|
+
# end
|
data/lib/json_builder.rb
CHANGED
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'blankslate' unless defined? BlankSlate
|
2
|
+
require 'json_builder/member'
|
3
|
+
|
4
|
+
module JSONBuilder
|
5
|
+
class Compiler < BlankSlate
|
6
|
+
class << self
|
7
|
+
def generate(*args, &block)
|
8
|
+
options = args.extract_options!
|
9
|
+
compiler = self.new(options)
|
10
|
+
compiler.compile(*args, &block)
|
11
|
+
compiler.to_s
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_accessor :members
|
16
|
+
attr_accessor :array
|
17
|
+
attr_accessor :scope
|
18
|
+
attr_accessor :callback
|
19
|
+
attr_accessor :pretty_print
|
20
|
+
|
21
|
+
def initialize(options={})
|
22
|
+
@members = []
|
23
|
+
@scope = options[:scope]
|
24
|
+
@callback = options[:callback]
|
25
|
+
@pretty_print = options[:pretty]
|
26
|
+
end
|
27
|
+
|
28
|
+
def compile(*args, &block)
|
29
|
+
instance_exec(*args, &block)
|
30
|
+
end
|
31
|
+
|
32
|
+
def array(items, &block)
|
33
|
+
@array = Elements.new(items, &block)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Need to return a Key instance to allow for arrays to be handled appropriately
|
37
|
+
def method_missing(key, *args, &block)
|
38
|
+
member = Member.new(key, *args, &block)
|
39
|
+
@members << member
|
40
|
+
member
|
41
|
+
end
|
42
|
+
alias_method :key, :method_missing
|
43
|
+
|
44
|
+
# Once all nodes are compiled, build the string
|
45
|
+
def to_s
|
46
|
+
include_callback @array ? @array.to_s : "{#{@members.collect(&:to_s).join(', ')}}"
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def include_callback(json)
|
52
|
+
@callback && request_params[:callback] ? "#{request_params[:callback]}(#{pretty_print(json)})" : pretty_print(json)
|
53
|
+
end
|
54
|
+
|
55
|
+
def pretty_print(json)
|
56
|
+
@pretty_print ? JSON.pretty_generate(JSON[json]) : json
|
57
|
+
end
|
58
|
+
|
59
|
+
def request_params
|
60
|
+
@scope.respond_to?(:params) ? @scope.params : {}
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module JSONBuilder
|
2
|
+
class Elements
|
3
|
+
attr_accessor :compilers
|
4
|
+
|
5
|
+
def initialize(items, &block)
|
6
|
+
@compilers = []
|
7
|
+
|
8
|
+
items.compact.each do |item|
|
9
|
+
@compilers << Value.new(item, &block)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_s
|
14
|
+
"[#{@compilers.collect(&:to_s).join(', ')}]"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'json_builder/value'
|
2
|
+
require 'json_builder/elements'
|
3
|
+
|
4
|
+
module JSONBuilder
|
5
|
+
class Member
|
6
|
+
attr_accessor :key
|
7
|
+
attr_accessor :value
|
8
|
+
|
9
|
+
def initialize(key, *args, &block)
|
10
|
+
@key = key
|
11
|
+
|
12
|
+
argument = args.shift
|
13
|
+
if argument.is_a?(Array)
|
14
|
+
@value = Elements.new(argument, &block)
|
15
|
+
else
|
16
|
+
@value = Value.new(argument, &block)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
"\"#{@key}\": #{@value}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -1,27 +1,53 @@
|
|
1
|
-
require 'action_view/base'
|
2
|
-
require 'action_view/template'
|
3
|
-
|
4
1
|
module ActionView #:nodoc:
|
5
2
|
class Base
|
6
3
|
cattr_accessor :pretty_print_json
|
7
|
-
@@pretty_print_json =
|
4
|
+
@@pretty_print_json = defined?(Rails) && Rails.env.development?
|
5
|
+
|
6
|
+
cattr_accessor :json_callback
|
7
|
+
@@json_callback = true
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
# Rails 2.X Template
|
12
|
+
if defined?(Rails) && Rails.version =~ /^2/
|
13
|
+
require 'action_view/base'
|
14
|
+
require 'action_view/template'
|
15
15
|
|
16
|
-
|
16
|
+
module ActionView
|
17
|
+
module TemplateHandlers
|
18
|
+
class JSONBuilder < TemplateHandler
|
19
|
+
include Compilable
|
17
20
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
";json.compile!;"
|
21
|
+
def compile(template)
|
22
|
+
"::JSONBuilder::Compiler.generate(:scope => self, :pretty => ActionView::Base.pretty_print_json, :callback => ActionView::Base.json_callback) {#{template.source}};"
|
23
|
+
end
|
22
24
|
end
|
23
25
|
end
|
24
26
|
end
|
27
|
+
|
28
|
+
ActionView::Template.register_template_handler :json_builder, ActionView::TemplateHandlers::JSONBuilder
|
25
29
|
end
|
26
30
|
|
27
|
-
|
31
|
+
# Rails 3.X Template
|
32
|
+
if defined?(Rails) && Rails.version =~ /^3/
|
33
|
+
module ActionView
|
34
|
+
module Template::Handlers
|
35
|
+
class JSONBuilder
|
36
|
+
class_attribute :default_format
|
37
|
+
self.default_format = Mime::JSON
|
38
|
+
|
39
|
+
def self.call(template)
|
40
|
+
source = if template.source.empty?
|
41
|
+
File.read(template.identifier)
|
42
|
+
else # use source
|
43
|
+
template.source
|
44
|
+
end
|
45
|
+
|
46
|
+
"::JSONBuilder::Compiler.generate(:scope => self, :pretty => ActionView::Base.pretty_print_json, :callback => ActionView::Base.json_callback) {#{source}};"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
ActionView::Template.register_template_handler :json_builder, ActionView::Template::Handlers::JSONBuilder
|
53
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'active_support/time'
|
2
|
+
|
3
|
+
module JSONBuilder
|
4
|
+
class Value
|
5
|
+
attr_accessor :value
|
6
|
+
|
7
|
+
def initialize(arg, &block)
|
8
|
+
if block_given?
|
9
|
+
@value = Compiler.new
|
10
|
+
compiled = @value.compile(*arg, &block)
|
11
|
+
|
12
|
+
# For the use case that the passed in block returns a non-member object
|
13
|
+
# or normal Ruby object
|
14
|
+
@value = compiled unless compiled.is_a?(Member)
|
15
|
+
else
|
16
|
+
@value = arg
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
case @value
|
22
|
+
when String, TrueClass, FalseClass then @value.inspect
|
23
|
+
when Hash then @value.to_json
|
24
|
+
when NilClass then 'null'
|
25
|
+
when Time, Date, DateTime then @value.iso8601.inspect
|
26
|
+
else @value.to_s
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/json_builder/version.rb
CHANGED
@@ -0,0 +1,60 @@
|
|
1
|
+
$:.push File.expand_path('../../../lib', __FILE__)
|
2
|
+
require 'rubygems'
|
3
|
+
require 'benchmark'
|
4
|
+
require 'builder'
|
5
|
+
require 'json_builder/compiler'
|
6
|
+
|
7
|
+
Benchmark.bm do |b|
|
8
|
+
b.report('JSONBuilder') do
|
9
|
+
15_000.times {
|
10
|
+
JSONBuilder::Compiler.generate {
|
11
|
+
name "Garrett Bjerkhoel"
|
12
|
+
birthday Time.local(1991, 9, 14)
|
13
|
+
street do
|
14
|
+
address "1143 1st Ave"
|
15
|
+
address2 "Apt 200"
|
16
|
+
city "New York"
|
17
|
+
state "New York"
|
18
|
+
zip 10065
|
19
|
+
end
|
20
|
+
skills do
|
21
|
+
ruby true
|
22
|
+
asp false
|
23
|
+
php true
|
24
|
+
mysql true
|
25
|
+
mongodb true
|
26
|
+
haproxy true
|
27
|
+
marathon false
|
28
|
+
end
|
29
|
+
single_skills ['ruby', 'php', 'mysql', 'mongodb', 'haproxy']
|
30
|
+
booleans [true, true, false, nil]
|
31
|
+
}
|
32
|
+
}
|
33
|
+
end
|
34
|
+
b.report('Builder') do
|
35
|
+
15_000.times {
|
36
|
+
xml = Builder::XmlMarkup.new(:indent => 2)
|
37
|
+
xml.name "Garrett Bjerkhoel"
|
38
|
+
xml.birthday Time.local(1991, 9, 14)
|
39
|
+
xml.street do
|
40
|
+
xml.address "1143 1st Ave"
|
41
|
+
xml.address2 "Apt 200"
|
42
|
+
xml.city "New York"
|
43
|
+
xml.state "New York"
|
44
|
+
xml.zip 10065
|
45
|
+
end
|
46
|
+
xml.skills do
|
47
|
+
xml.ruby true
|
48
|
+
xml.asp false
|
49
|
+
xml.php true
|
50
|
+
xml.mysql true
|
51
|
+
xml.mongodb true
|
52
|
+
xml.haproxy true
|
53
|
+
xml.marathon false
|
54
|
+
end
|
55
|
+
xml.single_skills ['ruby', 'php', 'mysql', 'mongodb', 'haproxy']
|
56
|
+
xml.booleans [true, true, false, nil]
|
57
|
+
xml.target!
|
58
|
+
}
|
59
|
+
end
|
60
|
+
end
|
data/spec/dummy/Rakefile
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
2
|
+
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
3
|
+
|
4
|
+
require File.expand_path('../config/application', __FILE__)
|
5
|
+
require 'rake'
|
6
|
+
|
7
|
+
Dummy::Application.load_tasks
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require File.expand_path('../boot', __FILE__)
|
2
|
+
|
3
|
+
require "active_model/railtie"
|
4
|
+
require "active_record/railtie"
|
5
|
+
require "action_controller/railtie"
|
6
|
+
require "action_view/railtie"
|
7
|
+
require "action_mailer/railtie"
|
8
|
+
|
9
|
+
Bundler.require
|
10
|
+
require "json_builder"
|
11
|
+
|
12
|
+
module Dummy
|
13
|
+
class Application < Rails::Application
|
14
|
+
# Settings in config/environments/* take precedence over those specified here.
|
15
|
+
# Application configuration should go into files in config/initializers
|
16
|
+
# -- all .rb files in that directory are automatically loaded.
|
17
|
+
|
18
|
+
# Custom directories with classes and modules you want to be autoloadable.
|
19
|
+
# config.autoload_paths += %W(#{config.root}/extras)
|
20
|
+
|
21
|
+
# Only load the plugins named here, in the order given (default is alphabetical).
|
22
|
+
# :all can be used as a placeholder for all plugins not explicitly named.
|
23
|
+
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]
|
24
|
+
|
25
|
+
# Activate observers that should always be running.
|
26
|
+
# config.active_record.observers = :cacher, :garbage_collector, :forum_observer
|
27
|
+
|
28
|
+
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
|
29
|
+
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
|
30
|
+
# config.time_zone = 'Central Time (US & Canada)'
|
31
|
+
|
32
|
+
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
|
33
|
+
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
|
34
|
+
# config.i18n.default_locale = :de
|
35
|
+
|
36
|
+
# JavaScript files you want as :defaults (application.js is always included).
|
37
|
+
# config.action_view.javascript_expansions[:defaults] = %w(jquery rails)
|
38
|
+
|
39
|
+
# Configure the default encoding used in templates for Ruby 1.9.
|
40
|
+
config.encoding = "utf-8"
|
41
|
+
|
42
|
+
# Configure sensitive parameters which will be filtered from the log file.
|
43
|
+
config.filter_parameters += [:password]
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# SQLite version 3.x
|
2
|
+
# gem install sqlite3
|
3
|
+
development:
|
4
|
+
adapter: sqlite3
|
5
|
+
database: db/development.sqlite3
|
6
|
+
pool: 5
|
7
|
+
timeout: 5000
|
8
|
+
|
9
|
+
# Warning: The database defined as "test" will be erased and
|
10
|
+
# re-generated from your development database when you run "rake".
|
11
|
+
# Do not set this db to the same as development or production.
|
12
|
+
test:
|
13
|
+
adapter: sqlite3
|
14
|
+
database: db/test.sqlite3
|
15
|
+
pool: 5
|
16
|
+
timeout: 5000
|
17
|
+
|
18
|
+
production:
|
19
|
+
adapter: sqlite3
|
20
|
+
database: db/production.sqlite3
|
21
|
+
pool: 5
|
22
|
+
timeout: 5000
|