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.
Files changed (63) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +13 -0
  3. data/Gemfile.lock +122 -0
  4. data/README.md +221 -59
  5. data/Rakefile +26 -0
  6. data/lib/json_builder.rb +1 -1
  7. data/lib/json_builder/compiler.rb +63 -0
  8. data/lib/json_builder/elements.rb +17 -0
  9. data/lib/json_builder/member.rb +24 -0
  10. data/lib/json_builder/template.rb +40 -14
  11. data/lib/json_builder/value.rb +30 -0
  12. data/lib/json_builder/version.rb +1 -1
  13. data/spec/benchmarks/builder.rb +60 -0
  14. data/spec/dummy/Rakefile +7 -0
  15. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  16. data/spec/dummy/app/controllers/users_controller.rb +5 -0
  17. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  18. data/spec/dummy/app/helpers/users_helper.rb +2 -0
  19. data/spec/dummy/app/models/user.rb +9 -0
  20. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  21. data/spec/dummy/app/views/users/index.json_builder +3 -0
  22. data/spec/dummy/config.ru +4 -0
  23. data/spec/dummy/config/application.rb +45 -0
  24. data/spec/dummy/config/boot.rb +10 -0
  25. data/spec/dummy/config/database.yml +22 -0
  26. data/spec/dummy/config/environment.rb +5 -0
  27. data/spec/dummy/config/environments/development.rb +26 -0
  28. data/spec/dummy/config/environments/production.rb +49 -0
  29. data/spec/dummy/config/environments/test.rb +35 -0
  30. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  31. data/spec/dummy/config/initializers/inflections.rb +10 -0
  32. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  33. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  34. data/spec/dummy/config/initializers/session_store.rb +8 -0
  35. data/spec/dummy/config/locales/en.yml +5 -0
  36. data/spec/dummy/config/routes.rb +5 -0
  37. data/spec/dummy/db/development.sqlite3 +0 -0
  38. data/spec/dummy/db/migrate/20111127061428_create_users.rb +14 -0
  39. data/spec/dummy/db/schema.rb +23 -0
  40. data/spec/dummy/db/test.sqlite3 +0 -0
  41. data/spec/dummy/public/404.html +26 -0
  42. data/spec/dummy/public/422.html +26 -0
  43. data/spec/dummy/public/500.html +26 -0
  44. data/spec/dummy/public/favicon.ico +0 -0
  45. data/spec/dummy/public/javascripts/application.js +2 -0
  46. data/spec/dummy/public/javascripts/controls.js +965 -0
  47. data/spec/dummy/public/javascripts/dragdrop.js +974 -0
  48. data/spec/dummy/public/javascripts/effects.js +1123 -0
  49. data/spec/dummy/public/javascripts/prototype.js +6001 -0
  50. data/spec/dummy/public/javascripts/rails.js +191 -0
  51. data/spec/dummy/public/stylesheets/.gitkeep +0 -0
  52. data/spec/dummy/script/rails +6 -0
  53. data/spec/dummy/spec/controllers/users_controller_spec.rb +14 -0
  54. data/spec/integration/navigation_spec.rb +9 -0
  55. data/spec/json_builder_spec.rb +7 -0
  56. data/spec/spec_helper.rb +34 -0
  57. data/spec/support/json_builder.rb +7 -0
  58. data/spec/unit/json_builder_spec.rb +76 -0
  59. metadata +158 -93
  60. data/lib/json_builder/generator.rb +0 -127
  61. data/test/benchmarks/speed.rb +0 -85
  62. data/test/fixtures/simple.rb +0 -27
  63. 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
@@ -1,3 +1,3 @@
1
1
  require 'json_builder/version'
2
- require 'json_builder/generator'
2
+ require 'json_builder/compiler'
3
3
  require 'json_builder/template' if defined? Rails
@@ -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 = false
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
- module ActionView
12
- module Template::Handlers
13
- class JSONBuilder < Template::Handler
14
- include Compilable
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
- self.default_format = Mime::JSON
16
+ module ActionView
17
+ module TemplateHandlers
18
+ class JSONBuilder < TemplateHandler
19
+ include Compilable
17
20
 
18
- def compile(template)
19
- "json = ::JSONBuilder::Generator.new(:pretty => #{ActionView::Base.pretty_print_json});" +
20
- template.source +
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
- ActionView::Template.register_template_handler :json_builder, ActionView::Template::Handlers::JSONBuilder
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
@@ -1,3 +1,3 @@
1
1
  module JSONBuilder
2
- VERSION = '2.0.6'.freeze
2
+ VERSION = '3.0.0'
3
3
  end
@@ -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
@@ -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,3 @@
1
+ class ApplicationController < ActionController::Base
2
+ protect_from_forgery
3
+ end
@@ -0,0 +1,5 @@
1
+ class UsersController < ApplicationController
2
+ def index
3
+ @users = User.all
4
+ end
5
+ end
@@ -0,0 +1,2 @@
1
+ module ApplicationHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ module UsersHelper
2
+ end
@@ -0,0 +1,9 @@
1
+ class User < ActiveRecord::Base
2
+ def disabled?
3
+ false
4
+ end
5
+
6
+ def activated?
7
+ true
8
+ end
9
+ end
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Dummy</title>
5
+ <%= stylesheet_link_tag :all %>
6
+ <%= javascript_include_tag :defaults %>
7
+ <%= csrf_meta_tag %>
8
+ </head>
9
+ <body>
10
+
11
+ <%= yield %>
12
+
13
+ </body>
14
+ </html>
@@ -0,0 +1,3 @@
1
+ testing ["1", 2, true] do |t|
2
+ variable t
3
+ end
@@ -0,0 +1,4 @@
1
+ # This file is used by Rack-based servers to start the application.
2
+
3
+ require ::File.expand_path('../config/environment', __FILE__)
4
+ run Dummy::Application
@@ -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,10 @@
1
+ require 'rubygems'
2
+ gemfile = File.expand_path('../../../../Gemfile', __FILE__)
3
+
4
+ if File.exist?(gemfile)
5
+ ENV['BUNDLE_GEMFILE'] = gemfile
6
+ require 'bundler'
7
+ Bundler.setup
8
+ end
9
+
10
+ $:.unshift File.expand_path('../../../../lib', __FILE__)
@@ -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