rabl-0.11.4/0000755000004100000410000000000012432721713012547 5ustar www-datawww-datarabl-0.11.4/Rakefile0000644000004100000410000000313112432721713014212 0ustar www-datawww-datainclude Rake::DSL require 'bundler' Bundler::GemHelper.install_tasks require 'rake/testtask' Rake::TestTask.new(:test) do |test| test.libs << 'lib' << 'test' test.pattern = 'test/*_test.rb' test.warning = true test.verbose = true test.ruby_opts = ['-rubygems'] end # Running integration tests # rake test:clean # rake test:setup # rake test:full fixture_list = "{padrino_test,sinatra_test,rails2,rails3,rails3_2,rails4}" desc "Clean up the fixtures being tested by cleaning and installing dependencies" task "test:clean" do Dir[File.dirname(__FILE__) + "/fixtures/#{fixture_list}"].each do |fixture| puts "\n*** Cleaning up for #{File.basename(fixture)} tests ***\n" Dir.chdir(fixture) { puts `rm Gemfile.lock` } end end desc "Prepares the fixtures being tested by installing dependencies" task "test:setup" do Dir[File.dirname(__FILE__) + "/fixtures/#{fixture_list}"].each do |fixture| puts "\n*** Setting up for #{File.basename(fixture)} tests ***\n" `export BUNDLE_GEMFILE="#{fixture}/Gemfile"` if ENV["TRAVIS"] Bundler.with_clean_env { Dir.chdir(fixture) { puts `mkdir -p tmp/cache; bundle install --gemfile="#{fixture}/Gemfile"`; } } end end desc "Executes the fixture tests" task "test:fixtures" do Dir[File.dirname(__FILE__) + "/fixtures/#{fixture_list}"].each do |fixture| puts "\n*** Running tests for #{File.basename(fixture)}... ***\n" Bundler.with_clean_env { Dir.chdir(fixture) { puts `bundle check; bundle exec rake test:rabl` } } end end task "test:full" => [:test, "test:fixtures"] desc "Run tests for rabl" task :default => :testrabl-0.11.4/Gemfile0000644000004100000410000000072712432721713014050 0ustar www-datawww-datasource 'https://rubygems.org' # Specify your gem's dependencies in rabl.gemspec gemspec gem 'rake', :require => false gem 'i18n', '~> 0.6' platforms :mri_18 do gem 'SystemTimer' gem 'json' end group :test do # RABL TEST gem 'builder' # FIXTURES gem 'rack-test', :require => 'rack/test' gem 'activerecord', :require => 'active_record' gem 'sqlite3' gem 'sinatra', '>= 1.2.0' gem 'hashie' end group :development, :test do # gem 'debugger' end rabl-0.11.4/examples/0000755000004100000410000000000012432721713014365 5ustar www-datawww-datarabl-0.11.4/examples/base.json.rabl0000644000004100000410000000027112432721713017111 0ustar www-datawww-data# See 'inherited' for an example of how to extend this template # Include these three attributes attributes :title, :kind, :id child @users do attributes :full_name, :first_name endrabl-0.11.4/examples/inherited.json.rabl0000644000004100000410000000027012432721713020151 0ustar www-datawww-data# Extends base.json.rabl and adds additional nodes extends("base") code :release_year do |m| m.release_date.year end code :poster_image_url do |m| m.poster_image_url(:large) endrabl-0.11.4/examples/demo.json.rabl0000644000004100000410000000230312432721713017121 0ustar www-datawww-data# Use the @media object set in route object @media # Include these three attributes attributes :title, :kind, :id # Rename 'studio' to be the 'company' node attributes :studio => :company # Arbitrary code blocks can be defined # Creates a 'release_year' node code :release_year do |m| date = m.release_date || m.series_start date.try(:year) end # Creates a node 'users' with an array of the nested users for media # Block is the same rabl syntax for the sub object child @users do attributes :full_name, :first_name end # Uses the associations of the parent media object # Rename 'users' association to 'people' node child :users => :people do attributes :full_name, :first_name end # Creates the "actor" association as a 'user' node # Use the information from another rabl template to describe the representation child :actor => :user do extends "users/simple" end # Append attributes to the root node with prefixed names glue @users.first do attributes :full_name => :user_full_name, :first_name => :user_first_name end # Render an arbitrary hash with a partial rabl json as one of the keys code :topics do |m| { :fake => partial("media/user", :object => @users.first), :raw => @users.first } endrabl-0.11.4/MIT-LICENSE0000644000004100000410000000204312432721713014202 0ustar www-datawww-dataCopyright (c) 2010 Nathan Esquenazi Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.rabl-0.11.4/.travis.yml0000644000004100000410000000035512432721713014663 0ustar www-datawww-data# http://about.travis-ci.org/docs/user/build-configuration/ rvm: - 1.8.7 - 1.9.3 - 2.0.0 gemfile: Gemfile.ci notifications: recipients: - nesquena@gmail.com - databyte@gmail.com matrix: allow_failures: - rvm: 1.8.7 rabl-0.11.4/lib/0000755000004100000410000000000012432721713013315 5ustar www-datawww-datarabl-0.11.4/lib/rabl.rb0000644000004100000410000000457512432721713014575 0ustar www-datawww-datarequire 'active_support' require 'active_support/core_ext/string/inflections' require 'active_support/core_ext/object/blank' require 'active_support/core_ext/hash/reverse_merge' require 'active_support/core_ext/hash/except' require 'active_support/core_ext/hash/slice' require 'rabl/version' require 'rabl/helpers' require 'rabl/sources' require 'rabl/partials' require 'rabl/engine' require 'rabl/builder' require 'rabl/multi_builder' require 'rabl/configuration' require 'rabl/renderer' require 'rabl/cache_engine' if defined?(Rails) require 'rabl/tracker' if Rails.version =~ /^[4]/ require 'rabl/digestor' if Rails.version =~ /^[4]/ require 'rabl/railtie' if Rails.version =~ /^[34]/ end # Rabl.register! module Rabl class << self # Initialize RABL within an application # Rabl.register! def register! require 'rabl/template' end # Yields a RABL configuration block # Rabl.configure do |config| # config.include_json_root = false # config.enable_json_callbacks = true # end def configure(&block) yield(configuration) configuration end # Returns the configuration options set for RABL # Rabl.configuration.include_json_root => false def configuration @_configuration ||= Configuration.new end # Resets the RABL configuration back to the defaults. def reset_configuration! @_configuration = nil end # Fetches from the source_cache, stores block result in cache if nil # Used to cache the contents and paths to various rabl templates # source_cache("users/index", "path/to/view") { "/full/path/to/template/users/index" } def source_cache(file, view_path, &block) return yield unless Rabl.configuration.cache_sources cache_key = [file, view_path].compact.join(":") @_source_cache ||= {} @_source_cache[cache_key] ||= yield end # Resets the RABL source cache def reset_source_cache! @_source_cache = {} end # Renders an object using a specified template within an application. # render(@post, 'posts/show', :view_path => "/path/to/app/views") def render(object, source, options = {}) Rabl::Renderer.new(source, object, options).render end end end # Register if defined?(Padrino) require 'padrino-core' Padrino.after_load { Rabl.register! } elsif defined?(Rails) && Rails.version =~ /^2/ Rabl.register! end rabl-0.11.4/lib/rabl/0000755000004100000410000000000012432721713014235 5ustar www-datawww-datarabl-0.11.4/lib/rabl/configuration.rb0000644000004100000410000000757712432721713017451 0ustar www-datawww-data# We load the msgpack library if it is available. begin require 'msgpack' rescue LoadError end # We load the bson library if it is available. begin require 'bson' rescue LoadError end # We load the plist library if it is available. begin require 'plist' rescue LoadError end # Set default options for Oj json parser (if exists) begin require 'oj' Oj.default_options = { :mode => :compat, :time_format => :ruby, :use_to_json => true } rescue LoadError end module Rabl # Rabl.host class Configuration attr_accessor :include_json_root attr_accessor :include_child_root attr_accessor :include_msgpack_root attr_accessor :include_plist_root attr_accessor :include_xml_root attr_accessor :include_bson_root attr_accessor :enable_json_callbacks attr_accessor :bson_check_keys attr_accessor :bson_move_id attr_writer :json_engine attr_writer :msgpack_engine attr_writer :bson_engine attr_writer :plist_engine attr_writer :xml_options attr_accessor :cache_sources attr_accessor :cache_all_output attr_accessor :escape_all_output attr_accessor :view_paths attr_accessor :cache_engine attr_accessor :raise_on_missing_attribute attr_accessor :perform_caching attr_accessor :use_read_multi attr_accessor :replace_nil_values_with_empty_strings attr_accessor :replace_empty_string_values_with_nil_values attr_accessor :exclude_nil_values attr_accessor :exclude_empty_values_in_collections DEFAULT_XML_OPTIONS = { :dasherize => true, :skip_types => false } def initialize @include_json_root = true @include_child_root = true @include_msgpack_root = true @include_plist_root = true @include_xml_root = false @include_bson_root = true @enable_json_callbacks = false @bson_check_keys = false @bson_move_id = false @json_engine = nil @msgpack_engine = nil @bson_engine = nil @plist_engine = nil @xml_options = {} @cache_sources = false @cache_all_output = false @escape_all_output = false @view_paths = [] @cache_engine = Rabl::CacheEngine.new @perform_caching = false @use_read_multi = true @replace_nil_values_with_empty_strings = false @replace_empty_string_values_with_nil_values = false @exclude_nil_values = false @exclude_empty_values_in_collections = false end # @return The JSON engine used to encode Rabl templates into JSON def json_engine @json_engine || (defined?(::Oj) ? ::Oj : ::JSON) end ## # @return the MessagePack encoder/engine to use. def msgpack_engine @msgpack_engine || ::MessagePack end ## # @return the Bson encoder/engine to use. def bson_engine @bson_engine || ::BSON end ## # @return the Plist encoder/engine to use. def plist_engine @plist_engine || ::Plist::Emit end # Allows config options to be read like a hash # # @param [Symbol] option Key for a given attribute def [](option) __send__(option) end # Returns merged default and inputted xml options def default_xml_options @_default_xml_options ||= @xml_options.reverse_merge(DEFAULT_XML_OPTIONS) end end end rabl-0.11.4/lib/rabl/tracker.rb0000644000004100000410000000245512432721713016223 0ustar www-datawww-datamodule Rabl # DependencyTracker for ActionView to support cache digest class Tracker # Matches: # extends "categories/show" EXTENDS_DEPENDENCY = / extends\s* # extends, followed by optional whitespace \(? # start an optional parenthesis for the extends call \s*["']([0-9a-z_\/\.]+) # the template name itself /x # Matches: # partial "categories/show" PARTIAL_DEPENDENCY = / partial\s* # partial, followed by optional whitespace \(? # start an optional parenthesis for the partial call \s*["']([0-9a-z_\/\.]+) # the template name itself /x def self.call(name, template) new(name, template).dependencies end def initialize(name, template) @name, @template = name, template end def dependencies (extends_dependencies + partial_dependencies).uniq end attr_reader :name, :template private :name, :template private def source template.source end def directory name.split("/")[0..-2].join("/") end def extends_dependencies source.scan(EXTENDS_DEPENDENCY).flatten end def partial_dependencies source.scan(PARTIAL_DEPENDENCY).flatten end end end rabl-0.11.4/lib/rabl/engine.rb0000644000004100000410000003402512432721713016033 0ustar www-datawww-datamodule Rabl class Engine include Helpers include Partials include Helpers::Escaper # List of supported rendering formats FORMATS = [:json, :xml, :plist, :bson, :msgpack] # Constructs a new ejs engine based on given vars, handler and declarations # Rabl::Engine.new("...source...", { :format => "xml", :root => true, :view_path => "/path/to/views" }) def initialize(source, options = {}) @_source = source @_settings = {} @_options = options @_view_path = options[:view_path] @_context_scope = options[:scope] @_cache_read_on_render = true end def source=(source) @_source = source end # Renders the representation based on source, object, context_scope and locals # Rabl::Engine.new("...source...", { :format => "xml" }).apply(context_scope, { :foo => "bar", :object => @user }) def apply(context_scope, locals, &block) set_instance_variables!(context_scope, locals) reset_settings! reset_options! eval_source(locals, &block) instance_exec(root_object, &block) if block_given? self end # Renders the representation based on a previous apply # Rabl::Engine.new("...source...", { :format => "xml" }).apply(context_scope, { :foo => "bar", :object => @user }).render def render(context_scope = nil, locals = nil, &block) apply(context_scope, locals, &block) if context_scope || locals || block cache_results do send("to_#{@_options[:format]}") end end def cache_key return unless defined?(@_cache_key) @_full_cache_key ||= begin cache_key = Array(@_cache_key) + [@_options[:root_name], @_options[:format]] if digestor_available? && respond_to?(:lookup_context) && lookup_context template = @_options[:template] || @virtual_path digest = \ if Gem::Version.new(Rails.version) >= Gem::Version.new('4.1') Digestor.digest(:name => template, :finder => lookup_context) else Digestor.digest(template, :rabl, lookup_context) end cache_key << digest end cache_key end end # Returns a hash representation of the data object # to_hash(:root => true, :child_root => true) def to_hash(options = {}) options = @_options.merge(options) data = root_object options[:root_name] = determine_object_root(data, root_name, options[:root]) result = \ if is_object?(data) || !data # object @user Builder.new(data, @_settings, options).to_hash elsif is_collection?(data) # collection @users MultiBuilder.new(data, @_settings, options).to_a end result = escape_output(result) if Rabl.configuration.escape_all_output result end def to_dumpable(options = {}) options = { :child_root => Rabl.configuration.include_child_root }.merge(options) result = to_hash(options) result = { collection_root_name => result } if collection_root_name result end # Returns a json representation of the data object # to_json(:root => true) def to_json(options = {}) options = { :root => Rabl.configuration.include_json_root }.merge(options) result = to_dumpable(options) format_json(result) end # Returns a msgpack representation of the data object # to_msgpack(:root => true) def to_msgpack(options = {}) options = { :root => Rabl.configuration.include_msgpack_root }.merge(options) result = to_dumpable(options) Rabl.configuration.msgpack_engine.pack(result) end alias_method :to_mpac, :to_msgpack # Returns a plist representation of the data object # to_plist(:root => true) def to_plist(options = {}) options = { :root => Rabl.configuration.include_plist_root }.merge(options) result = to_dumpable(options) Rabl.configuration.plist_engine.dump(result) end # Returns an xml representation of the data object # to_xml(:root => true) def to_xml(options = {}) options = { :root => (include_root = Rabl.configuration.include_xml_root), :child_root => include_root && Rabl.configuration.include_child_root }.merge(options) xml_options = Rabl.configuration.default_xml_options.merge(:root => collection_root_name || root_name) result = to_hash(options) result.to_xml(xml_options) end # Returns a bson representation of the data object # to_bson(:root => true) def to_bson(options = {}) options = { :root => Rabl.configuration.include_bson_root }.merge(options) result = to_dumpable(options) if !collection_root_name && is_collection?(root_object) && root_object.is_a?(Array) result = { root_name => result } end Rabl.configuration.bson_engine.serialize(result).to_s end # Sets the object to be used as the data source for this template # object(@user) # object @user => :person # object @users def object(template_data) current_data = (@_locals[:object].nil? || template_data == false) ? template_data : @_locals[:object] @_data_object = data_object(current_data) @_data_name = data_name(template_data.is_a?(Hash) && !current_data.is_a?(Hash) ? template_data : current_data) if @_data_name == false @_object_root_name = false @_collection_name = false end end # Returns the current object that is the topic of this template # Can be the collection or the object depending on topic assigned # root_object => @user def root_object return @_data_object if defined?(@_data_object) data = @_locals[:object].nil? ? default_object : @_locals[:object] @_data_object = data_object(data) end def root_name return @_data_name if defined?(@_data_name) @_data_name = @_options[:object_root_name] || begin data = @_locals[:object].nil? ? root_object : @_locals[:object] data_name(data) end end # Sets the object as a collection casted to a simple array # collection @users # collection @users => :people # collection @users, :root => :person # collection @users, :object_root => :person def collection(data, options = {}) @_collection_name = options[:root] if options[:root] @_collection_name ||= data.values.first if data.is_a?(Hash) @_object_root_name = options[:object_root] if options.has_key?(:object_root) object(Array(data_object(data))) end # Sets the cache key to be used by ActiveSupport::Cache.expand_cache_key # cache @user # calls @user.cache_key # cache ['rabl', @user] # calls @user.cache_key and prefixes with rabl/ # cache 'user' # explicit key of 'user' # cache # uses the current item within a collection # cache 'user', expires_in: 1.hour # options is passed through to the cache store def cache(key = nil, options = nil) key ||= root_object # if called but missing, use object @_cache_key = key @_cache_options = options end # Indicates an attribute or method should be included in the json output # attribute :foo, :as => "bar" # attribute :foo => :bar, :bar => :baz # attribute :foo => :bar, :bar => :baz, :if => lambda { |r| r.foo } def attribute(*args) if args.first.is_a?(Hash) # :foo => :bar, :bar => :baz attr_aliases = args.first.except(:if, :unless) conditions = args.first.slice(:if, :unless) attr_aliases.each do |key, as| attribute(key, conditions.merge(:as => as)) end else # array of attributes i.e :foo, :bar, :baz options = args.extract_options! args.each do |name| @_settings[:attributes] << { :name => name, :options => options } end end end alias_method :attributes, :attribute # Creates an arbitrary node that is included in the json output. # node(:foo) { "bar" } # node(:foo, :if => lambda { ... }) { "bar" } def node(name = nil, options = {}, &block) @_settings[:node] << { :name => name, :options => options, :block => block } end alias_method :code, :node # Creates a child node that is included in json output # child(@user) { attribute :full_name } def child(data, options = {}, &block) @_settings[:child] << { :data => data, :options => options, :block => block } end # Glues data from a child node to the json_output # glue(@user) { attribute :full_name => :user_full_name } def glue(data, options = {}, &block) @_settings[:glue] << { :data => data, :options => options, :block => block } end # Extends an existing rabl template with additional attributes in the block # extends("users/show", :object => @user) { attribute :full_name } def extends(file, options = {}, &block) options = { :view_path => options[:view_path] || view_path }.merge(options) @_settings[:extends] << { :file => file, :options => options, :block => block } end # Includes a helper module with a RABL template # helper ExampleHelper def helper(*klasses) klasses.each { |klass| self.class.__send__(:include, klass) } end alias_method :helpers, :helper # Returns a hash representing the partial # partial("users/show", :object => @user) # options must have :object # options can have :view_path, :child_root, :root def partial(file, options = {}, &block) engine = partial_as_engine(file, options, &block) engine = engine.render if engine.is_a?(Engine) engine end # Disables reading (but not writing) from the cache when rendering. def cache_read_on_render=(read) @_cache_read_on_render = read end def cache_read_on_render? @_cache_read_on_render end protected # Returns a guess at the default object for this template # default_object => @user def default_object return unless context_scope.respond_to?(:controller) controller_name = context_scope.controller.controller_name stripped_name = controller_name.split(%r{::|\/}).last ivar_object = instance_variable_get("@#{stripped_name}") ivar_object if is_object?(ivar_object) end # Returns a guess at the format in this context_scope # request_format => "xml" def request_format format = request_params[:format] if format.nil? && context_scope.respond_to?(:request) request = context_scope.request format = request.format.to_sym.to_s if request.respond_to?(:format) end format = "json" unless format && respond_to?("to_#{format}") format end # Returns the request parameters if available in the context_scope # request_params => { :foo => "bar" } def request_params (context_scope.params if context_scope.respond_to?(:params)) || {} end # Returns data as json embraced with callback when detected # format_json({ :foo => "bar" }) => "test({ foo : 'bar' })" # format_json("{ foo : "bar" }") => "test({ foo : 'bar' })" def format_json(json_output) unless json_output.is_a?(String) json_engine = Rabl.configuration.json_engine json_output = if json_engine.respond_to?(:dump) json_engine.dump(json_output) else json_engine.encode(json_output) end end use_callback = Rabl.configuration.enable_json_callbacks && request_params[:callback].present? json_output = "#{request_params[:callback]}(#{json_output})" if use_callback json_output end # Augments respond to supporting context_scope methods def respond_to?(name, include_private = false) context_scope.respond_to?(name, include_private) || super end # Supports calling helpers defined for the template context_scope using method_missing hook def method_missing(name, *args, &block) context_scope.respond_to?(name, true) ? context_scope.__send__(name, *args, &block) : super end def copy_instance_variables_from(object, exclude = []) #:nodoc: vars = object.instance_variables.map(&:to_s) - exclude.map(&:to_s) vars.each { |name| instance_variable_set(name, object.instance_variable_get(name)) } end def reset_settings! @_settings[:attributes] = [] @_settings[:node] = [] @_settings[:child] = [] @_settings[:glue] = [] @_settings[:extends] = [] end # Resets the options parsed from a rabl template. def reset_options! @_options[:root_name] = nil @_options[:read_multi] = false @_options[:scope] = context_scope end # Caches the results of the block based on object cache_key # cache_results { compile_hash(options) } def cache_results(&block) return yield unless template_cache_configured? && defined?(@_cache_key) if cache_read_on_render? fetch_result_from_cache(cache_key, @_cache_options, &block) else write_result_to_cache(cache_key, @_cache_options, &block) end end def digestor_available? defined?(Rails) && Rails.version =~ /^[4]/ end def set_instance_variables!(context_scope, locals) @_context_scope = context_scope @_locals = locals copy_instance_variables_from(context_scope, [:@assigns, :@helpers]) @_options[:format] ||= request_format set_locals(locals) end def set_locals(locals) locals.merge!(locals.delete(:locals) || {}) locals.each { |key, value| instance_variable_set(:"@#{key}", value) } end def eval_source(locals, &block) # Note: locals and block may be used by the eval'ed source return unless @_source.present? if @_options[:source_location] instance_eval(@_source, @_options[:source_location]) else instance_eval(@_source) end end end end rabl-0.11.4/lib/rabl/sources.rb0000644000004100000410000000761412432721713016255 0ustar www-datawww-datamodule Rabl module Sources include Helpers # Returns source for a given relative file # fetch_source("show", :view_path => "...") => "...contents..." def fetch_source(file, options = {}) view_paths = Array(options[:view_path]) + Array(Rabl.configuration.view_paths) Rabl.source_cache(file, view_paths) do file_path = \ if defined?(Padrino) && context_scope.respond_to?(:settings) && context_scope.respond_to?(:resolve_template) fetch_padrino_source(file, options) elsif defined?(Rails) && context_scope.respond_to?(:view_paths) _view_paths = view_paths + Array(context_scope.view_paths.to_a) fetch_rails_source(file, options) || fetch_manual_template(_view_paths, file) elsif defined?(Sinatra) && context_scope.respond_to?(:settings) fetch_sinatra_source(file, options) else # generic template resolution fetch_manual_template(view_paths, file) end unless File.exist?(file_path.to_s) raise "Cannot find rabl template '#{file}' within registered (#{view_paths.map(&:to_s).inspect}) view paths!" end [File.read(file_path.to_s), file_path.to_s] end end private # Returns the rabl template path for padrino views using configured views def fetch_padrino_source(file, options = {}) view_path = Array(options[:view_path] || context_scope.settings.views) # use Padrino's own template resolution mechanism file_path, _ = context_scope.instance_eval { resolve_template(file) } # Padrino chops the extension, stitch it back on File.join(view_path.first.to_s, (file_path.to_s + ".rabl")) end # Returns the rabl template path for Rails, including special lookups for Rails 2 and 3 def fetch_rails_source(file, options = {}) # use Rails template resolution mechanism if possible (find_template) source_format = request_format if defined?(request_format) if source_format && context_scope.respond_to?(:lookup_context) # Rails 3 lookup_proc = lambda do |partial| if ActionPack::VERSION::MAJOR == 3 && ActionPack::VERSION::MINOR < 2 context_scope.lookup_context.find(file, [], partial) else # Rails 3.2 and higher # pull format directly from rails unless it is html request_format = context_scope.request.format.to_sym source_format = request_format unless request_format == :html context_scope.lookup_context.find(file, [], partial, [], { :formats => [source_format] }) end end template = lookup_proc.call(false) rescue nil template ||= lookup_proc.call(true) rescue nil template.identifier if template elsif source_format && context_scope.respond_to?(:view_paths) # Rails 2 template = context_scope.view_paths.find_template(file, source_format, false) template.filename if template end end # Returns the rabl template path for sinatra views using configured views def fetch_sinatra_source(file, options = {}) view_path = Array(options[:view_path] || context_scope.settings.views) fetch_manual_template(view_path, file) end # Returns the rabl template by looking up files within the view_path and specified file path def fetch_manual_template(view_path, file) Dir[File.join("{#{view_path.join(",")}}", "{#{file},#{partialized(file)}}" + ".{*.,}rabl")].first end # Returns a partialized version of a file path # partialized("v1/variants/variant") => "v1/variants/_variant" def partialized(file) partial_file = file.split(File::SEPARATOR) partial_file[-1] = "_#{partial_file[-1]}" unless partial_file[-1].start_with?("_") partial_file.join(File::SEPARATOR) end end # Partials end # Rabl rabl-0.11.4/lib/rabl/digestor.rb0000644000004100000410000000235712432721713016411 0ustar www-datawww-datamodule Rabl class Digestor < ActionView::Digestor # Override the original digest function to ignore partial which # rabl doesn't use the Rails conventional _ symbol. if Gem::Version.new(Rails.version) >= Gem::Version.new('4.1') def self.digest(options = {}) cache_key = [options[:name]] + Array.wrap(options[:dependencies]) @@cache[cache_key.join('.')] ||= begin Digestor.new({ :name => options[:name], :finder => options[:finder] }.merge!(options)).digest end end else def self.digest(name, format, finder, options = {}) cache_key = [name, format] + Array.wrap(options[:dependencies]) @@cache[cache_key.join('.')] ||= begin Digestor.new(name, format, finder, options).digest end end end private def dependency_digest template_digests = (dependencies - [template.virtual_path]).collect do |template_name| if Gem::Version.new(Rails.version) >= Gem::Version.new('4.1') Digestor.digest(:name => template_name, :finder => finder) else Digestor.digest(template_name, format, finder) end end (template_digests + injected_dependencies).join("-") end end end rabl-0.11.4/lib/rabl/multi_builder.rb0000644000004100000410000000550212432721713017424 0ustar www-datawww-datamodule Rabl class MultiBuilder include Helpers # Constructs a new MultiBuilder given the data and options. # The options will be re-used for all Rabl::Builders. # Rabl::MultiBuilder.new([#, #, ...], { :format => 'json', :child_root => true }) def initialize(data, settings = {}, options = {}) @data = data @settings = settings @options = options @builders = [] @engine_to_builder = {} @cache_key_to_engine = {} end # Returns the result of all of the builders as an array def to_a generate_builders if template_cache_configured? && Rabl.configuration.use_read_multi map_engines_to_builders read_cache_results replace_engines_with_cache_results end result = @builders.map(&:to_hash) result = result.map(&:presence).compact if Rabl.configuration.exclude_empty_values_in_collections result end private # Creates a builder for each of the data objects # and maps the cache keys for each of the engines # the builders generated def generate_builders @builders = @data.map do |object| Builder.new(object, @settings, @options) end end def map_engines_to_builders @builders.each do |builder| builder.engines.each do |engine| @engine_to_builder[engine] = builder map_cache_key_to_engine(engine) end end end # Maps a cache key to an engine def map_cache_key_to_engine(engine) if cache_key = cache_key_for(engine) result_cache_key = ActiveSupport::Cache.expand_cache_key(cache_key, :rabl) @cache_key_to_engine[result_cache_key] = engine disable_cache_read_on_render(engine) end end def disable_cache_read_on_render(engine) case engine when Hash disable_cache_read_on_render(engine.values.first) when Engine engine.cache_read_on_render = false end end def cache_key_for(engine) case engine when Hash cache_key_for(engine.values.first) when Engine engine.cache_key end end # Returns the items that were found in the cache def read_cache_results @cache_results ||= begin mutable_keys = @cache_key_to_engine.keys.map { |k| k.dup } if mutable_keys.empty? {} else Rabl.configuration.cache_engine.read_multi(*mutable_keys) end end end # Maps the results from the cache back to the builders def replace_engines_with_cache_results @cache_results.each do |key, value| engine = @cache_key_to_engine[key] builder = @engine_to_builder[engine] builder.replace_engine(engine, value) if value end end end end rabl-0.11.4/lib/rabl/helpers.rb0000644000004100000410000001474212432721713016234 0ustar www-datawww-datarequire 'active_support/inflector' # for the sake of pluralizing require 'set' module Rabl module Helpers # Set of class names known to be objects, not collections KNOWN_OBJECT_CLASSES = Set.new(['Struct', 'Hashie::Mash']) # data_object(data) => # data_object(@user => :person) => @user # data_object(:user => :person) => @_object.send(:user) def data_object(data) data = data.keys.first if data.is_a?(Hash) && data.keys.size == 1 data = @_object.__send__(data) if data.is_a?(Symbol) && defined?(@_object) && @_object && @_object.respond_to?(data) data end # data_object_attribute(data) => @_object.send(data) def data_object_attribute(data) attribute = @_object.__send__(data) attribute = attribute.as_json if is_collection?(attribute, false) && attribute.respond_to?(:as_json) attribute end # data_name(data) => "user" # data_name(@user => :person) => :person # data_name(@users) => :user # data_name([@user]) => "users" # data_name([]) => "array" def data_name(data_token) return unless data_token # nil or false return data_token.values.first if data_token.is_a?(Hash) # @user => :user data = data_object(data_token) if is_collection?(data) # data is a collection object_name = data.table_name if data.respond_to?(:table_name) if object_name.nil? && data.respond_to?(:first) first = data.first object_name = data_name(first).to_s.pluralize if first.present? end object_name ||= data_token if data_token.is_a?(Symbol) object_name elsif is_object?(data) # data is an object object_name = object_root_name if object_root_name object_name ||= data if data.is_a?(Symbol) object_name ||= collection_root_name.to_s.singularize if collection_root_name object_name ||= data.class.respond_to?(:model_name) ? data.class.model_name.element : data.class.to_s.downcase object_name else data_token end end # Returns the object rootname based on if the root should be included # Can be called with data as a collection or object # determine_object_root(@user, :user, true) => "user" # determine_object_root(@user, :person) => "person" # determine_object_root([@user, @user]) => "user" def determine_object_root(data_token, data_name = nil, include_root = true) return if object_root_name == false root_name = data_name.to_s if include_root if is_object?(data_token) || data_token.nil? root_name elsif is_collection?(data_token) object_root_name || (root_name.singularize if root_name) end end # Returns true if obj is not a collection # is_object?(@user) => true # is_object?([]) => false # is_object?({}) => false def is_object?(obj, follow_symbols = true) obj && !is_collection?(obj, follow_symbols) end # Returns true if the obj is a collection of items # is_collection?(@user) => false # is_collection?([]) => true def is_collection?(obj, follow_symbols = true) data_obj = follow_symbols ? data_object(obj) : obj data_obj && data_obj.respond_to?(:map) && data_obj.respond_to?(:each) && obj.class.ancestors.none? { |a| KNOWN_OBJECT_CLASSES.include?(a.name) } end # Returns the context_scope wrapping this engine, used for retrieving data, invoking methods, etc # In Rails, this is the controller and in Padrino this is the request context def context_scope defined?(@_context_scope) ? @_context_scope : nil end def view_path defined?(@_view_path) ? @_view_path : nil end # Returns the root (if any) name for an object within a collection # Sets the name of the object i.e "person" # => { "users" : [{ "person" : {} }] } def object_root_name defined?(@_object_root_name) ? @_object_root_name : nil end # Returns the root for the collection # Sets the name of the collection i.e "people" # => { "people" : [] } def collection_root_name defined?(@_collection_name) ? @_collection_name : nil end # Returns true if the value is a name value (symbol or string) def is_name_value?(val) val.is_a?(String) || val.is_a?(Symbol) end # Returns an Engine based representation of any data object given ejs template block # object_to_engine(@user) { attribute :full_name } => { ... } # object_to_engine(@user, :source => "...") { attribute :full_name } => { ... } # object_to_engine([@user], :source => "...") { attribute :full_name } => { ... } # options must have :source (rabl file contents) # options can have :source_location (source filename) def object_to_engine(object, options = {}, &block) return if object.nil? options = { :format => "hash", :view_path => view_path, :root => (options[:root] || false) }.merge(options) Engine.new(options[:source], options).apply(context_scope, :object => object, :locals => options[:locals], &block) end # Fetches a key from the cache and stores rabl template result otherwise # fetch_from_cache('some_key') { ...rabl template result... } def fetch_result_from_cache(cache_key, cache_options = nil, &block) expanded_cache_key = ActiveSupport::Cache.expand_cache_key(cache_key, :rabl) Rabl.configuration.cache_engine.fetch(expanded_cache_key, cache_options, &block) end def write_result_to_cache(cache_key, cache_options = nil, &block) expanded_cache_key = ActiveSupport::Cache.expand_cache_key(cache_key, :rabl) result = yield Rabl.configuration.cache_engine.write(expanded_cache_key, result, cache_options) result end # Returns true if the cache has been enabled for the application def template_cache_configured? if defined?(Rails) defined?(ActionController::Base) && ActionController::Base.perform_caching else Rabl.configuration.perform_caching end end module Escaper def escape_output(response) case response when Hash response.each{|k,v| response[k] = escape_value(v) } when Array response.map!{|v| escape_value(v) } else response end end def escape_value(value) case value when String ERB::Util.h(value) when Array, Hash escape_output(value) else value end end end end end rabl-0.11.4/lib/rabl/version.rb0000644000004100000410000000004512432721713016246 0ustar www-datawww-datamodule Rabl VERSION = "0.11.4" end rabl-0.11.4/lib/rabl/renderer.rb0000644000004100000410000000556212432721713016400 0ustar www-datawww-datamodule Rabl class Renderer # Defines class method rendering in supported formats # Rabl::Renderer.json(@post, 'posts/show') # Rabl::Renderer.xml(@post, 'posts/show') Rabl::Engine::FORMATS.each do |fmt| instance_eval <<-CODE def #{fmt}(object, source, options = {}) new(source, object, options.merge(:format => :#{fmt})).render end CODE end attr_reader :object, :options # Public: Instantiate a new renderer # This is a standalone class used for rendering rabl templates # outside of a framework like Rails. You may want to use # this when using Rabl to render the request objects passed to # message queues. # # Example: # renderer = Rabl::Renderer.new('template_name', user, { :format => 'json', :view_path => 'app/views' }) # renderer.render # => '{"user":{"name": "ivan" }}' # def initialize(source, object = nil, options = {}) options = { :format => :json, :scope => self, :view_path => [], :template => source }.merge(options) @options = options @object = object engine.source = process_source(source) end # Public: Actually render the template to the requested output format. # # - context_scope: # Override the render context_scope to the 'context_scope' object. Defaults to self. # # Returns: And object representing the tranformed object in the requested format. # e.g. json, xml, bson, plist def render(context_scope = nil) context_scope ||= options[:scope] || self set_object_instance_variable if context_scope == self locals = { :object => object }.merge(options.fetch(:locals, {})) engine.apply(context_scope, locals).render end protected def engine @engine ||= Rabl::Engine.new(nil, options) end # Returns the source given a relative template path def process_source(source) return source if source.is_a?(String) && source =~ /\n/ source, _ = engine.fetch_source(source, { :view_path => options[:view_path] }) source end # Internal: Sets an instance variable named after the class of `object` # # Example: # object.class.name # => User # set_object_instance_variable # => @user == object # def set_object_instance_variable instance_variable_set(:"@#{object_model_name}", object) end # Internal: Returns the model name for an object # # Example: # object.class.name # => User # object_model_name => "user" # def object_model_name item = object is_collection = item.is_a?(Array) item = item.first if is_collection name = item.class.name.underscore name = name.pluralize if is_collection name.split("/").last end end end rabl-0.11.4/lib/rabl/partials.rb0000644000004100000410000000106712432721713016405 0ustar www-datawww-datamodule Rabl module Partials include Helpers include Sources def partial_as_engine(file, options = {}, &block) raise ArgumentError, "Must provide an :object option to render a partial" unless options.has_key?(:object) object = options.delete(:object) view_path = options[:view_path] || view_path source, location = fetch_source(file, :view_path => view_path) options = options.merge(:source => source, :source_location => location, :template => file) object_to_engine(object, options, &block) end end end rabl-0.11.4/lib/rabl/cache_engine.rb0000644000004100000410000000207512432721713017156 0ustar www-datawww-data# Defines the default cache engine for RABL when caching is invoked for a template. # You can define your own caching engines by creating an object that responds to fetch and # setting the configuration option: # # config.cache_engine = AdvancedCacheEngine.new # module Rabl class CacheEngine # Fetch given a key and options and a fallback block attempts to find the key in the cache # and stores the block result in there if no key is found. # # cache = Rabl::CacheEngine.new; cache.fetch("some_key") { "fallback data" } # def fetch(key, cache_options, &block) if defined?(Rails) Rails.cache.fetch(key, cache_options, &block) else yield end end def write(key, value, options = {}) if defined?(Rails) Rails.cache.write(key, value, options) end end def read_multi(*keys) options = keys.extract_options! if defined?(Rails) Rails.cache.read_multi(*keys, options) else keys.inject({}) { |hash, key| hash[key] = nil; hash } end end end end rabl-0.11.4/lib/rabl/railtie.rb0000644000004100000410000000065012432721713016214 0ustar www-datawww-datamodule Rabl class Railtie < Rails::Railtie initializer "rabl.initialize" do |app| ActiveSupport.on_load(:action_view) do Rabl.register! # Inject dependency tracker for :rabl if Rails.version =~ /^[4]/ require 'action_view/dependency_tracker' ActionView::DependencyTracker.register_tracker :rabl, Rabl::Tracker end end end end # Railtie end # Rabl rabl-0.11.4/lib/rabl/builder.rb0000644000004100000410000002062312432721713016213 0ustar www-datawww-datamodule Rabl class Builder include Helpers include Partials SETTING_TYPES = { :attributes => :name, :node => :name, :child => :data, :glue => :data, :extends => :file } unless const_defined?(:SETTING_TYPES) # Constructs a new rabl hash based on given object and options # options = { :format => "json", :root => true, :child_root => true, # :attributes, :node, :child, :glue, :extends } # def initialize(object, settings = {}, options = {}, &block) @_object = object @settings = settings @options = options @_context_scope = options[:scope] @_view_path = options[:view_path] end def engines return @_engines if defined?(@_engines) @_engines = [] # Append onto @_engines compile_settings(:extends) compile_settings(:child) compile_settings(:glue) @_engines end def replace_engine(engine, value) engines[engines.index(engine)] = value end def to_hash(object = nil, settings = {}, options = {}) @_object = object if object @options.merge!(options) if options @settings.merge!(settings) if settings cache_results do @_result = {} # Merges directly into @_result compile_settings(:attributes) merge_engines_into_result # Merges directly into @_result compile_settings(:node) replace_nil_values if Rabl.configuration.replace_nil_values_with_empty_strings replace_empty_string_values if Rabl.configuration.replace_empty_string_values_with_nil_values remove_nil_values if Rabl.configuration.exclude_nil_values result = @_result result = { @options[:root_name] => result } if @options[:root_name].present? result end end protected def replace_nil_values @_result = deep_replace_nil_values(@_result) end def deep_replace_nil_values(hash) hash.inject({}) do |new_hash, (k, v)| new_hash[k] = if v.is_a?(Hash) deep_replace_nil_values(v) else v.nil? ? '' : v end new_hash end end def replace_empty_string_values @_result = deep_replace_empty_string_values(@_result) end def deep_replace_empty_string_values(hash) hash.inject({}) do |new_hash, (k, v)| new_hash[k] = if v.is_a?(Hash) deep_replace_empty_string_values(v) else (!v.nil? && v != "") ? v : nil end new_hash end end def remove_nil_values @_result = @_result.inject({}) do |new_hash, (k, v)| new_hash[k] = v unless v.nil? new_hash end end def compile_settings(type) return unless @settings.has_key?(type) settings_type = SETTING_TYPES[type] @settings[type].each do |setting| send(type, setting[settings_type], setting[:options] || {}, &setting[:block]) end end def merge_engines_into_result engines.each do |engine| case engine when Hash # engine was stored in the form { name => # } engine.each do |key, value| engine[key] = value.render if value.is_a?(Engine) end when Engine engine = engine.render end @_result.merge!(engine) if engine.is_a?(Hash) end end # Indicates an attribute or method should be included in the json output # attribute :foo, :as => "bar" # attribute :foo, :as => "bar", :if => lambda { |m| m.foo } def attribute(name, options = {}) return unless @_object && attribute_present?(name) && resolve_condition(options) attribute = data_object_attribute(name) name = (options[:as] || name).to_sym @_result[name] = attribute end alias_method :attributes, :attribute # Creates an arbitrary node that is included in the json output # node(:foo) { "bar" } # node(:foo, :if => lambda { |m| m.foo.present? }) { "bar" } def node(name, options = {}, &block) return unless resolve_condition(options) result = block.call(@_object) if name.present? @_result[name.to_sym] = result elsif result.is_a?(Hash) # merge hash into root hash @_result.merge!(result) end end alias_method :code, :node # Creates a child node that is included in json output # child(@user) { attribute :full_name } # child(@user => :person) { ... } # child(@users => :people) { ... } def child(data, options = {}, &block) return unless data.present? && resolve_condition(options) name = is_name_value?(options[:root]) ? options[:root] : data_name(data) object = data_object(data) include_root = is_collection?(object) && options.fetch(:object_root, @options[:child_root]) # child @users engine_options = @options.slice(:child_root).merge(:root => include_root) engine_options.merge!(:object_root_name => options[:object_root]) if is_name_value?(options[:object_root]) object = { object => name } if data.is_a?(Hash) && object # child :users => :people engines << { name.to_sym => object_to_engine(object, engine_options, &block) } end # Glues data from a child node to the json_output # glue(@user) { attribute :full_name => :user_full_name } def glue(data, options = {}, &block) return unless data.present? && resolve_condition(options) object = data_object(data) engine = object_to_engine(object, :root => false, &block) engines << engine if engine end # Extends an existing rabl template with additional attributes in the block # extends("users/show") { attribute :full_name } def extends(file, options = {}, &block) return unless resolve_condition(options) options = @options.slice(:child_root).merge(:object => @_object).merge(options) engines << partial_as_engine(file, options, &block) end # Evaluate conditions given a symbol to evaluate def call_condition_proc(condition, object, &block) block = lambda { |v| v } unless block_given? if condition.respond_to?(:call) # condition is a block to pass to the block block.call(condition.call(object)) elsif condition.is_a?(Symbol) && object.respond_to?(condition) # condition is a property of the object block.call(object.send(condition)) else false end end # resolve_condition(:if => true) => true # resolve_condition(:if => lambda { |m| false }) => false # resolve_condition(:unless => lambda { |m| true }) => true def resolve_condition(options) return true if options[:if].nil? && options[:unless].nil? result = nil if options.has_key?(:if) result = options[:if] == true || call_condition_proc(options[:if], @_object) end if options.has_key?(:unless) inverse_proc = lambda { |r| !r } result = options[:unless] == false || call_condition_proc(options[:unless], @_object, &inverse_proc) end result end private # Checks if an attribute is present. If not, check if the configuration specifies that this is an error # attribute_present?(created_at) => true def attribute_present?(name) if @_object.respond_to?(name) true elsif Rabl.configuration.raise_on_missing_attribute raise "Failed to render missing attribute #{name}" else false end end # Returns a guess at the format in this context_scope # request_format => "xml" def request_format format = @options[:format] format = "json" if !format || format == "hash" format end # Caches the results of the block based on object cache_key # cache_results { compile_hash(options) } def cache_results(&block) if template_cache_configured? && Rabl.configuration.cache_all_output && @_object.respond_to?(:cache_key) cache_key = [@_object, @options[:root_name], @options[:format]] fetch_result_from_cache(cache_key, &block) else # skip cache yield end end end end rabl-0.11.4/lib/rabl/template.rb0000644000004100000410000000327612432721713016405 0ustar www-datawww-data# TILT Template if defined?(Tilt) class RablTemplate < Tilt::Template def initialize_engine return if defined?(::Rabl) require_template_library 'rabl' end def prepare options = @options.merge(:format => @options[:format], :source_location => file) @engine = ::Rabl::Engine.new(data, options) end def evaluate(context_scope, locals, &block) @engine.apply(context_scope, locals, &block).render end end Tilt.register 'rabl', RablTemplate end # Rails 2.X Template if defined?(ActionView) && defined?(Rails) && Rails.version.to_s =~ /^2/ require 'action_view/base' require 'action_view/template' module ActionView module TemplateHandlers class RablHandler < TemplateHandler include Compilable def compile(template) %{ ::Rabl::Engine.new(#{template.source.inspect}, { :format => #{template.format.inspect} }). render(self, assigns.merge(local_assigns)) } end end end end ActionView::Template.register_template_handler :rabl, ActionView::TemplateHandlers::RablHandler end # Rails 3.X / 4.X Template if defined?(ActionView) && defined?(Rails) && Rails.version.to_s =~ /^[34]/ module ActionView module Template::Handlers class Rabl class_attribute :default_format self.default_format = Mime::JSON def self.call(template) source = template.source %{ ::Rabl::Engine.new(#{source.inspect}). apply(self, assigns.merge(local_assigns)). render } end # call end # rabl class end # handlers end ActionView::Template.register_template_handler :rabl, ActionView::Template::Handlers::Rabl end rabl-0.11.4/fixtures/0000755000004100000410000000000012432721713014420 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/0000755000004100000410000000000012432721713016036 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/Rakefile0000644000004100000410000000060412432721713017503 0ustar www-datawww-data#!/usr/bin/env rake # Add your own tasks in files placed in lib/tasks ending in .rake, # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. require File.expand_path('../config/application', __FILE__) Rails32::Application.load_tasks Rake::TestTask.new("test:rabl") do |test| test.pattern = "test/functional/**/*_test.rb" test.verbose = true endrabl-0.11.4/fixtures/rails3_2/Gemfile0000644000004100000410000000152612432721713017335 0ustar www-datawww-datasource 'https://rubygems.org' gem 'rails', '~> 3.2.9.rc3' # Bundle edge Rails instead: # gem 'rails', :git => 'git://github.com/rails/rails.git' gem 'sqlite3' gem 'rabl', :path => File.expand_path(File.dirname(__FILE__) + "/../../") gem 'riot', :group => "test" # Gems used only for assets and not required # in production environments by default. group :assets do gem 'sass-rails', '~> 3.2.3' gem 'coffee-rails', '~> 3.2.1' # See https://github.com/sstephenson/execjs#readme for more supported runtimes # gem 'therubyracer' gem 'uglifier', '>= 1.0.3' end gem 'jquery-rails' # To use ActiveModel has_secure_password # gem 'bcrypt-ruby', '~> 3.0.0' # To use Jbuilder templates for JSON # gem 'jbuilder' # Use unicorn as the app server # gem 'unicorn' # Deploy with Capistrano # gem 'capistrano' # To use debugger # gem 'debugger' rabl-0.11.4/fixtures/rails3_2/doc/0000755000004100000410000000000012432721713016603 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/doc/README_FOR_APP0000644000004100000410000000032312432721713020667 0ustar www-datawww-dataUse this README file to introduce your application and point to useful places in the API for learning more. Run "rake doc:app" to generate API documentation for your models, controllers, helpers, and libraries. rabl-0.11.4/fixtures/rails3_2/script/0000755000004100000410000000000012432721713017342 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/script/rails0000755000004100000410000000044712432721713020407 0ustar www-datawww-data#!/usr/bin/env ruby # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. APP_PATH = File.expand_path('../../config/application', __FILE__) require File.expand_path('../../config/boot', __FILE__) require 'rails/commands' rabl-0.11.4/fixtures/rails3_2/log/0000755000004100000410000000000012432721713016617 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/log/.gitkeep0000644000004100000410000000000012432721713020236 0ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/db/0000755000004100000410000000000012432721713016423 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/db/schema.rb0000644000004100000410000000266112432721713020215 0ustar www-datawww-data# encoding: UTF-8 # This file is auto-generated from the current state of the database. Instead # of editing this file, please use the migrations feature of Active Record to # incrementally modify your database, and then regenerate this schema definition. # # Note that this schema.rb definition is the authoritative source for your # database schema. If you need to create the application database on another # system, you should be using db:schema:load, not running all the migrations # from scratch. The latter is a flawed and unsustainable approach (the more migrations # you'll amass, the slower it'll run and the greater likelihood for issues). # # It's strongly recommended to check this file into your version control system. ActiveRecord::Schema.define(:version => 20111002092024) do create_table "phone_numbers", :force => true do |t| t.integer "user_id" t.boolean "is_primary" t.string "area_code" t.string "prefix" t.string "suffix" t.string "name" end create_table "posts", :force => true do |t| t.integer "user_id" t.string "title" t.text "body" t.datetime "created_at", :null => false t.datetime "updated_at", :null => false end create_table "users", :force => true do |t| t.string "username" t.string "email" t.string "location" t.boolean "is_admin" t.datetime "created_at", :null => false t.datetime "updated_at", :null => false end end rabl-0.11.4/fixtures/rails3_2/db/seeds.rb0000644000004100000410000000054112432721713020053 0ustar www-datawww-data# This file should contain all the record creation needed to seed the database with its default values. # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). # # Examples: # # cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }]) # Mayor.create(:name => 'Daley', :city => cities.first) rabl-0.11.4/fixtures/rails3_2/vendor/0000755000004100000410000000000012432721713017333 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/vendor/assets/0000755000004100000410000000000012432721713020635 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/vendor/assets/javascripts/0000755000004100000410000000000012432721713023166 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/vendor/assets/javascripts/.gitkeep0000644000004100000410000000000012432721713024605 0ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/vendor/assets/stylesheets/0000755000004100000410000000000012432721713023211 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/vendor/assets/stylesheets/.gitkeep0000644000004100000410000000000012432721713024630 0ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/vendor/plugins/0000755000004100000410000000000012432721713021014 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/vendor/plugins/.gitkeep0000644000004100000410000000000012432721713022433 0ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/public/0000755000004100000410000000000012432721713017314 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/public/422.html0000644000004100000410000000130712432721713020512 0ustar www-datawww-data The change you wanted was rejected (422)

The change you wanted was rejected.

Maybe you tried to change something you didn't have access to.

rabl-0.11.4/fixtures/rails3_2/public/favicon.ico0000644000004100000410000000000012432721713021423 0ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/public/robots.txt0000644000004100000410000000031412432721713021363 0ustar www-datawww-data# See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file # # To ban all spiders from the entire site uncomment the next two lines: # User-Agent: * # Disallow: / rabl-0.11.4/fixtures/rails3_2/public/404.html0000644000004100000410000000133012432721713020506 0ustar www-datawww-data The page you were looking for doesn't exist (404)

The page you were looking for doesn't exist.

You may have mistyped the address or the page may have moved.

rabl-0.11.4/fixtures/rails3_2/public/500.html0000644000004100000410000000120312432721713020502 0ustar www-datawww-data We're sorry, but something went wrong (500)

We're sorry, but something went wrong.

rabl-0.11.4/fixtures/rails3_2/public/index.html0000644000004100000410000001342212432721713021313 0ustar www-datawww-data Ruby on Rails: Welcome aboard

Getting started

Here’s how to get rolling:

  1. Use rails generate to create your models and controllers

    To see all available options, run it without parameters.

  2. Set up a default route and remove public/index.html

    Routes are set up in config/routes.rb.

  3. Create your database

    Run rake db:create to create your database. If you're not using SQLite (the default), edit config/database.yml with your username and password.

rabl-0.11.4/fixtures/rails3_2/README.rdoc0000644000004100000410000002177012432721713017653 0ustar www-datawww-data== Welcome to Rails Rails is a web-application framework that includes everything needed to create database-backed web applications according to the Model-View-Control pattern. This pattern splits the view (also called the presentation) into "dumb" templates that are primarily responsible for inserting pre-built data in between HTML tags. The model contains the "smart" domain objects (such as Account, Product, Person, Post) that holds all the business logic and knows how to persist themselves to a database. The controller handles the incoming requests (such as Save New Account, Update Product, Show Post) by manipulating the model and directing data to the view. In Rails, the model is handled by what's called an object-relational mapping layer entitled Active Record. This layer allows you to present the data from database rows as objects and embellish these data objects with business logic methods. You can read more about Active Record in link:files/vendor/rails/activerecord/README.html. The controller and view are handled by the Action Pack, which handles both layers by its two parts: Action View and Action Controller. These two layers are bundled in a single package due to their heavy interdependence. This is unlike the relationship between the Active Record and Action Pack that is much more separate. Each of these packages can be used independently outside of Rails. You can read more about Action Pack in link:files/vendor/rails/actionpack/README.html. == Getting Started 1. At the command prompt, create a new Rails application: rails new myapp (where myapp is the application name) 2. Change directory to myapp and start the web server: cd myapp; rails server (run with --help for options) 3. Go to http://localhost:3000/ and you'll see: "Welcome aboard: You're riding Ruby on Rails!" 4. Follow the guidelines to start developing your application. You can find the following resources handy: * The Getting Started Guide: http://guides.rubyonrails.org/getting_started.html * Ruby on Rails Tutorial Book: http://www.railstutorial.org/ == Debugging Rails Sometimes your application goes wrong. Fortunately there are a lot of tools that will help you debug it and get it back on the rails. First area to check is the application log files. Have "tail -f" commands running on the server.log and development.log. Rails will automatically display debugging and runtime information to these files. Debugging info will also be shown in the browser on requests from 127.0.0.1. You can also log your own messages directly into the log file from your code using the Ruby logger class from inside your controllers. Example: class WeblogController < ActionController::Base def destroy @weblog = Weblog.find(params[:id]) @weblog.destroy logger.info("#{Time.now} Destroyed Weblog ID ##{@weblog.id}!") end end The result will be a message in your log file along the lines of: Mon Oct 08 14:22:29 +1000 2007 Destroyed Weblog ID #1! More information on how to use the logger is at http://www.ruby-doc.org/core/ Also, Ruby documentation can be found at http://www.ruby-lang.org/. There are several books available online as well: * Programming Ruby: http://www.ruby-doc.org/docs/ProgrammingRuby/ (Pickaxe) * Learn to Program: http://pine.fm/LearnToProgram/ (a beginners guide) These two books will bring you up to speed on the Ruby language and also on programming in general. == Debugger Debugger support is available through the debugger command when you start your Mongrel or WEBrick server with --debugger. This means that you can break out of execution at any point in the code, investigate and change the model, and then, resume execution! You need to install ruby-debug to run the server in debugging mode. With gems, use sudo gem install ruby-debug. Example: class WeblogController < ActionController::Base def index @posts = Post.all debugger end end So the controller will accept the action, run the first line, then present you with a IRB prompt in the server window. Here you can do things like: >> @posts.inspect => "[#nil, "body"=>nil, "id"=>"1"}>, #"Rails", "body"=>"Only ten..", "id"=>"2"}>]" >> @posts.first.title = "hello from a debugger" => "hello from a debugger" ...and even better, you can examine how your runtime objects actually work: >> f = @posts.first => #nil, "body"=>nil, "id"=>"1"}> >> f. Display all 152 possibilities? (y or n) Finally, when you're ready to resume execution, you can enter "cont". == Console The console is a Ruby shell, which allows you to interact with your application's domain model. Here you'll have all parts of the application configured, just like it is when the application is running. You can inspect domain models, change values, and save to the database. Starting the script without arguments will launch it in the development environment. To start the console, run rails console from the application directory. Options: * Passing the -s, --sandbox argument will rollback any modifications made to the database. * Passing an environment name as an argument will load the corresponding environment. Example: rails console production. To reload your controllers and models after launching the console run reload! More information about irb can be found at: link:http://www.rubycentral.org/pickaxe/irb.html == dbconsole You can go to the command line of your database directly through rails dbconsole. You would be connected to the database with the credentials defined in database.yml. Starting the script without arguments will connect you to the development database. Passing an argument will connect you to a different database, like rails dbconsole production. Currently works for MySQL, PostgreSQL and SQLite 3. == Description of Contents The default directory structure of a generated Ruby on Rails application: |-- app | |-- assets | |-- images | |-- javascripts | `-- stylesheets | |-- controllers | |-- helpers | |-- mailers | |-- models | `-- views | `-- layouts |-- config | |-- environments | |-- initializers | `-- locales |-- db |-- doc |-- lib | `-- tasks |-- log |-- public |-- script |-- test | |-- fixtures | |-- functional | |-- integration | |-- performance | `-- unit |-- tmp | |-- cache | |-- pids | |-- sessions | `-- sockets `-- vendor |-- assets `-- stylesheets `-- plugins app Holds all the code that's specific to this particular application. app/assets Contains subdirectories for images, stylesheets, and JavaScript files. app/controllers Holds controllers that should be named like weblogs_controller.rb for automated URL mapping. All controllers should descend from ApplicationController which itself descends from ActionController::Base. app/models Holds models that should be named like post.rb. Models descend from ActiveRecord::Base by default. app/views Holds the template files for the view that should be named like weblogs/index.html.erb for the WeblogsController#index action. All views use eRuby syntax by default. app/views/layouts Holds the template files for layouts to be used with views. This models the common header/footer method of wrapping views. In your views, define a layout using the layout :default and create a file named default.html.erb. Inside default.html.erb, call <% yield %> to render the view using this layout. app/helpers Holds view helpers that should be named like weblogs_helper.rb. These are generated for you automatically when using generators for controllers. Helpers can be used to wrap functionality for your views into methods. config Configuration files for the Rails environment, the routing map, the database, and other dependencies. db Contains the database schema in schema.rb. db/migrate contains all the sequence of Migrations for your schema. doc This directory is where your application documentation will be stored when generated using rake doc:app lib Application specific libraries. Basically, any kind of custom code that doesn't belong under controllers, models, or helpers. This directory is in the load path. public The directory available for the web server. Also contains the dispatchers and the default HTML files. This should be set as the DOCUMENT_ROOT of your web server. script Helper scripts for automation and generation. test Unit and functional tests along with fixtures. When using the rails generate command, template test files will be generated for you and placed in this directory. vendor External libraries that the application depends on. Also includes the plugins subdirectory. If the app has frozen rails, those gems also go here, under vendor/rails/. This directory is in the load path. rabl-0.11.4/fixtures/rails3_2/lib/0000755000004100000410000000000012432721713016604 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/lib/assets/0000755000004100000410000000000012432721713020106 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/lib/assets/.gitkeep0000644000004100000410000000000012432721713021525 0ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/lib/tasks/0000755000004100000410000000000012432721713017731 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/lib/tasks/.gitkeep0000644000004100000410000000000012432721713021350 0ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/test/0000755000004100000410000000000012432721713017015 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/test/fixtures/0000755000004100000410000000000012432721713020666 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/test/fixtures/posts.yml0000644000004100000410000000054112432721713022561 0ustar www-datawww-data# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html # This model initially had no columns defined. If you add columns to the # model remove the '{}' from the fixture names and add the columns immediately # below each fixture, per the syntax in the comments below # one: {} # column: value # two: {} # column: value rabl-0.11.4/fixtures/rails3_2/test/fixtures/phone_numbers.yml0000644000004100000410000000054112432721713024255 0ustar www-datawww-data# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html # This model initially had no columns defined. If you add columns to the # model remove the '{}' from the fixture names and add the columns immediately # below each fixture, per the syntax in the comments below # one: {} # column: value # two: {} # column: value rabl-0.11.4/fixtures/rails3_2/test/fixtures/users.yml0000644000004100000410000000054112432721713022552 0ustar www-datawww-data# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html # This model initially had no columns defined. If you add columns to the # model remove the '{}' from the fixture names and add the columns immediately # below each fixture, per the syntax in the comments below # one: {} # column: value # two: {} # column: value rabl-0.11.4/fixtures/rails3_2/test/test_helper.rb0000644000004100000410000000140312432721713021656 0ustar www-datawww-data# Load Silence Functionality require File.expand_path(File.dirname(__FILE__) + "/../../../test/silence.rb") # Load Environment silence_warnings do ENV["RAILS_ENV"] = "test" require File.expand_path('../../config/environment', __FILE__) require 'rails/test_help' end # Load Riot Test Environment require File.expand_path(File.dirname(__FILE__) + "/../../../test/integration/test_init.rb") # Run Migrations silence_stream(STDOUT) do dbconf = YAML::load(File.open('config/database.yml'))[Rails.env] ActiveRecord::Base.establish_connection(dbconf) ActiveRecord::Base.logger = Logger.new(File.open('log/database.log', 'a')) silence_stream(STDOUT) { ActiveRecord::Migrator.up('db/migrate') } end class Riot::Situation def app Rails.application end endrabl-0.11.4/fixtures/rails3_2/test/performance/0000755000004100000410000000000012432721713021316 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/test/performance/browsing_test.rb0000644000004100000410000000056212432721713024537 0ustar www-datawww-datarequire 'test_helper' require 'rails/performance_test_help' class BrowsingTest < ActionDispatch::PerformanceTest # Refer to the documentation for all available options # self.profile_options = { :runs => 5, :metrics => [:wall_time, :memory] # :output => 'tmp/performance', :formats => [:flat] } def test_homepage get '/' end end rabl-0.11.4/fixtures/rails3_2/test/integration/0000755000004100000410000000000012432721713021340 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/test/integration/.gitkeep0000644000004100000410000000000012432721713022757 0ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/test/unit/0000755000004100000410000000000012432721713017774 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/test/unit/post_test.rb0000644000004100000410000000016612432721713022350 0ustar www-datawww-datarequire 'test_helper' class PostTest < ActiveSupport::TestCase # test "the truth" do # assert true # end end rabl-0.11.4/fixtures/rails3_2/test/unit/phone_number_test.rb0000644000004100000410000000017512432721713024044 0ustar www-datawww-datarequire 'test_helper' class PhoneNumberTest < ActiveSupport::TestCase # test "the truth" do # assert true # end end rabl-0.11.4/fixtures/rails3_2/test/unit/user_test.rb0000644000004100000410000000016612432721713022341 0ustar www-datawww-datarequire 'test_helper' class UserTest < ActiveSupport::TestCase # test "the truth" do # assert true # end end rabl-0.11.4/fixtures/rails3_2/test/unit/helpers/0000755000004100000410000000000012432721713021436 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/test/unit/helpers/users_helper_test.rb0000644000004100000410000000011012432721713025512 0ustar www-datawww-datarequire 'test_helper' class UsersHelperTest < ActionView::TestCase end rabl-0.11.4/fixtures/rails3_2/test/unit/helpers/posts_helper_test.rb0000644000004100000410000000011012432721713025521 0ustar www-datawww-datarequire 'test_helper' class PostsHelperTest < ActionView::TestCase end rabl-0.11.4/fixtures/rails3_2/test/functional/0000755000004100000410000000000012432721713021157 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/test/functional/users_controller_test.rb0000644000004100000410000000636712432721713026163 0ustar www-datawww-data# Lives in /test/integration/users_controller_test.rb # Symlinked to fixture applications begin # Sinatra require File.expand_path(File.dirname(__FILE__) + '/../../test_config.rb') rescue LoadError # Rails require File.expand_path(File.dirname(__FILE__) + '/../test_helper.rb') end context "UsersController" do helper(:json_output) { JSON.parse(last_response.body) } setup do create_users! end context "for index action" do # Tests `collection @users` extending from 'show' template setup do get "/users" end # Attributes (regular) asserts("contains user usernames") do json_output.map { |u| u["user"]["username"] } end.equals { @users.map(&:username) } asserts("contains email") do json_output.map { |u| u["user"]["email"] } end.equals { @users.map(&:email) } asserts("contains location") do json_output.map { |u| u["user"]["location"] } end.equals { @users.map(&:location) } # Attributes (custom name) asserts("contains registered_at") do json_output.map { |u| u["user"]["registered_at"] } end.equals { @users.map(&:created_at).map { |t| t.iso8601 } } # Node (renders based on attribute) asserts("contains role") do json_output.map { |u| u["user"]["role"] } end.equals ['normal', 'normal', 'admin'] # Child (custom collection name) asserts("contains formatted phone numbers") do json_output.map { |u| u["user"]["pnumbers"].map { |n| n["pnumber"]["formatted"] } } end.equals { @users.map { |u| u.phone_numbers.map(&:formatted) } } # Node (renders collection partial) asserts("contains reversed node numbers") do json_output.map { |u| u["user"]["node_numbers"].map { |n| n["reversed"] } } end.equals { @users.map { |u| u.phone_numbers.map(&:formatted).map(&:reverse) } } end # index context "for show action" do # Tests `object :user => :person` custom parent node name setup do get "/users/#{@user1.id}" end # Attributes (regular) asserts("contains username") { json_output["person"]["username"] }.equals { @user1.username } asserts("contains email") { json_output["person"]["email"] }.equals { @user1.email } asserts("contains location") { json_output["person"]["location"] }.equals { @user1.location } # Attributes (custom name) asserts("contains registered_at") { json_output["person"]["registered_at"] }.equals { @user1.created_at.iso8601 } # Node (renders based on attribute) asserts("contains role node") { json_output["person"]["role"] }.equals "normal" # Child (custom collection name) asserts("contains first phone number") { json_output["person"]["pnumbers"][0]["pnumber"]["formatted"] }.equals { @user1.phone_numbers[0].formatted } asserts("contains second phone number") { json_output["person"]["pnumbers"][1]["pnumber"]["formatted"] }.equals { @user1.phone_numbers[1].formatted } # Node (renders collection partial) asserts("contains first node number") { json_output["person"]["node_numbers"][0]["formatted"] }.equals { @user1.phone_numbers[0].formatted } asserts("contains second node number") { json_output["person"]["node_numbers"][1]["formatted"] }.equals { @user1.phone_numbers[1].formatted } end # show endrabl-0.11.4/fixtures/rails3_2/test/functional/posts_controller_test.rb0000755000004100000410000002205712432721713026167 0ustar www-datawww-data# Lives in /test/integration/posts_controller_test.rb # Symlinked to fixture applications begin # Padrino require File.expand_path(File.dirname(__FILE__) + '/../../test_config.rb') rescue LoadError # Rails require File.expand_path(File.dirname(__FILE__) + '/../test_helper.rb') end require 'rexml/document' context "PostsController" do helper(:json_output) { JSON.parse(last_response.body) } setup do create_users! Post.delete_all @post1 = Post.create(:title => "Foo", :body => "Bar", :user_id => @user1.id) @post2 = Post.create(:title => "Baz", :body => "Bah", :user_id => @user2.id) @post3 = Post.create(:title => "Kaz", :body => "", :user_id => @user3.id) @posts = [@post1, @post2, @post3] end context "for index action" do setup do get "/posts", format: :json end # Attributes (regular) asserts("contains post titles") do json_output['articles'].map { |o| o["article"]["title"] } end.equals { @posts.map(&:title) } asserts("contains post bodies") do json_output['articles'].map { |o| o["article"]["body"] } end.equals { @posts.map(&:body) } # Attributes (custom name) asserts("contains post posted_at") do json_output['articles'].map { |o| o["article"]["posted_at"] } end.equals { @posts.map(&:created_at).map(&:iso8601) } # Child asserts("contains post user child username") do json_output['articles'].map { |o| o["article"]["user"]["username"] } end.equals { @posts.map(&:user).map(&:username) } asserts("contains post user child role") do json_output['articles'].map { |o| o["article"]["user"]["role"] } end.equals { ["normal", "normal", "admin"] } # Child Numbers of the Child User asserts("contains post user child numbers") do json_output['articles'].map { |o| o["article"]["user"]["pnumbers"][0]["pnumber"]["formatted"] } end.equals { @posts.map(&:user).map(&:phone_numbers).map(&:first).map(&:formatted) } # Glue (username to article) asserts("contains glued usernames") do json_output['articles'].map { |o| o["article"]["author_name"] } end.equals { @posts.map(&:user).map(&:username) } # Conditional Child (admin) asserts("contains admin child only for admins") do json_output['articles'].map { |o| o["article"]["admin"]["username"] if o["article"].has_key?("admin") }.compact end.equals { [@user3.username] } # Conditional Node (created_by_admin) asserts("contains created_by_admin node for admins") do json_output['articles'].last['article']['created_by_admin'] end.equals { true } denies("contains no created_by_admin node for non-admins") do json_output['articles'].first['article'] end.includes(:created_by_admin) context "mime types" do setup do get "/posts", format: :rabl_test_v1 end asserts("contains post title") do json_output['articles'].first['article'] end.includes("title_v1") asserts("contains post user child username") do json_output['articles'].first['article']["user"] end.includes("username_v1") end end context "escaping output in index action" do context "for first post" do setup do Rabl.configuration.escape_all_output = true get "/posts/#{@post1.id}", format: :json json_output['post'] end # Attributes (regular) asserts("contains post title") { topic['title'] }.equals { @post1.title } asserts("contains post body") { topic['body'] }.equals { @post1.body } end context "for third post with script tags" do setup do Rabl.configuration.escape_all_output = true get "/posts/#{@post3.id}", format: :json json_output['post'] end # Attributes (regular) asserts("contains post title") { topic['title'] }.equals { @post3.title } asserts("contains escaped post body") { topic['body'] }.equals { ERB::Util.h(@post3.body) } end end # escaping output context "for show action" do setup do get "/posts/#{@post1.id}", format: :json json_output['post'] end # Attributes (regular) asserts("contains post title") { topic['title'] }.equals { @post1.title } asserts("contains post body") { topic['body'] }.equals { @post1.body } # Attributes (custom name) asserts("contains post posted_at") { topic['posted_at'] }.equals { @post1.created_at.iso8601 } # Child asserts("contains post user child username") { topic["user"]["username"] }.equals { @post1.user.username } asserts("contains post user child role") { topic["user"]["role"] }.equals { "normal" } # Child Numbers of the Child User asserts("contains post user child numbers") do topic["user"]["pnumbers"][0]["pnumber"]["formatted"] end.equals { @post1.user.phone_numbers[0].formatted } # Glue (username to article) asserts("contains glued username") { topic["author_name"] }.equals { @post1.user.username } # Non-ORM Date Node Partial context "for date node" do setup { json_output['post']['created_date'] } asserts("contains date partial with day") { topic['day'] }.equals { @post1.created_at.day } asserts("contains date partial with hour") { topic['hour'] }.equals { @post1.created_at.hour } asserts("contains date partial with full") { topic['full'] }.equals { @post1.created_at.iso8601 } end # date node asserts("contains helper action") { topic["foo"] }.equals { "BAR!" } denies("contains helper action") { topic["created_at_in_words"] }.nil asserts("contains post attributes via node") { topic["post"] }.equals { [@post1.title, @post1.body] } end # show action, json context "renderer" do setup do mock(ActionController::Base).perform_caching.any_number_of_times { true } get "/posts/#{@post1.id}/renderer" json_output['post'] end # Attributes (regular) asserts("contains post title") { topic['title'] }.equals { @post1.title } asserts("contains post body") { topic['body'] }.equals { @post1.body } # Attributes (partial) asserts("contains post partial title") { topic['partial']['title'] }.equals { @post1.title } asserts("contains post partial body") { topic['partial']['body'] }.equals { @post1.body } end # renderer action, json context "for index action rendering JSON within HTML" do setup do get "/posts", format: :html end asserts(:body).includes { "" } end # index action, html context "for show action rendering JSON within HTML" do setup do get "/posts/#{@post1.id}", format: :html end asserts(:body).includes { "" } end # show action, html context "mime_type" do setup do get "/posts/#{@post1.id}", format: :rabl_test_v1 end asserts("contains post title") { json_output['post']['title_v1'] }.equals { @post1.title } asserts("contains username") { json_output['post']['user']['username_v1'] }.equals { @post1.user.username } end context "caching" do helper(:cache_hit) do |key| Rails.cache.read(ActiveSupport::Cache.expand_cache_key(key, :rabl)) end setup do mock(ActionController::Base).perform_caching.any_number_of_times { true } Rails.cache.clear end context "for index action with caching in json" do setup do get "/posts", format: :json end asserts("contains post titles") do json_output['articles'].map { |o| o['article']['title'] } end.equals { @posts.map(&:title) } asserts(:body).equals { cache_hit ['kittens!', @posts, nil, 'json'] } asserts("contains cache hits per object (posts by title)") do json_output['articles'].map { |o| o['article']['title'] } end.equals { @posts.map{ |p| cache_hit([p, nil, 'hash'])[:title] } } end # index action, caching, json context "for index action with caching in xml" do setup do get "/posts", format: :xml end asserts("contains post titles") do doc = REXML::Document.new topic.body doc.elements.inject('articles/article/title', []) {|arr, ele| arr << ele.text} end.equals { @posts.map(&:title) } asserts(:body).equals { cache_hit ['kittens!', @posts, nil, 'xml'] } end # index action, caching, xml context "for show action with caching" do setup do get "/posts/#{@post1.id}", format: :json end asserts("contains post title") { json_output['post']['title'] }.equals { @post1.title } asserts(:body).equals { cache_hit [@post1, nil, 'json'] } end # show action, caching, json context "cache_all_output" do helper(:cache_hit) do |key| Rails.cache.read(ActiveSupport::Cache.expand_cache_key([key, 'article', 'json'], :rabl)) end setup do Rabl.configuration.cache_all_output = true get "/posts", format: :json end asserts("contains cache hits per object (posts by title)") do json_output['articles'].map { |o| o['article']['title'] } end.equals { @posts.map{ |p| cache_hit(p)['article'][:title] } } end # index action, cache_all_output end end rabl-0.11.4/fixtures/rails3_2/.gitignore0000644000004100000410000000065612432721713020035 0ustar www-datawww-data# See http://help.github.com/ignore-files/ for more about ignoring files. # # If you find yourself ignoring temporary files generated by your text editor # or operating system, you probably want to add a global ignore instead: # git config --global core.excludesfile ~/.gitignore_global # Ignore bundler config /.bundle # Ignore the default SQLite database. /db/*.sqlite3 # Ignore all logfiles and tempfiles. /log/*.log /tmp rabl-0.11.4/fixtures/rails3_2/config/0000755000004100000410000000000012432721713017303 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/config/application.rb0000644000004100000410000000523312432721713022136 0ustar www-datawww-datarequire File.expand_path('../boot', __FILE__) require 'rails/all' if defined?(Bundler) # If you precompile assets before deploying to production, use this line Bundler.require(*Rails.groups(:assets => %w(development test))) # If you want your assets lazily compiled in production, use this line # Bundler.require(:default, :assets, Rails.env) end module Rails32 class Application < Rails::Application # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers # -- all .rb files in that directory are automatically loaded. # Custom directories with classes and modules you want to be autoloadable. # config.autoload_paths += %W(#{config.root}/extras) # Only load the plugins named here, in the order given (default is alphabetical). # :all can be used as a placeholder for all plugins not explicitly named. # config.plugins = [ :exception_notification, :ssl_requirement, :all ] # Activate observers that should always be running. # config.active_record.observers = :cacher, :garbage_collector, :forum_observer # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. # config.time_zone = 'Central Time (US & Canada)' # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] # config.i18n.default_locale = :de # Configure the default encoding used in templates for Ruby 1.9. config.encoding = "utf-8" # Configure sensitive parameters which will be filtered from the log file. config.filter_parameters += [:password] # Use SQL instead of Active Record's schema dumper when creating the database. # This is necessary if your schema can't be completely dumped by the schema dumper, # like if you have constraints or database-specific column types # config.active_record.schema_format = :sql # Enforce whitelist mode for mass assignment. # This will create an empty whitelist of attributes available for mass-assignment for all models # in your app. As such, your models will need to explicitly whitelist or blacklist accessible # parameters by using an attr_accessible or attr_protected declaration. # config.active_record.whitelist_attributes = true # Enable the asset pipeline config.assets.enabled = true # Version of your assets, change this if you want to expire all your assets config.assets.version = '1.0' end end rabl-0.11.4/fixtures/rails3_2/config/initializers/0000755000004100000410000000000012432721713022011 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/config/initializers/secret_token.rb0000644000004100000410000000076212432721713025030 0ustar www-datawww-data# Be sure to restart your server when you modify this file. # Your secret key for verifying the integrity of signed cookies. # If you change this key, all old signed cookies will become invalid! # Make sure the secret is at least 30 characters and all random, # no regular words or you'll be exposed to dictionary attacks. Rails32::Application.config.secret_token = '889df7428c5678596588834e106a8ef76583e31ce7cfcd60246419917f91d713ff33f8f9d1267ed80cd10bddfd3e934e9fb1cad0401315cb61dfde1fbdbc75a3' rabl-0.11.4/fixtures/rails3_2/config/initializers/session_store.rb0000644000004100000410000000063612432721713025242 0ustar www-datawww-data# Be sure to restart your server when you modify this file. Rails32::Application.config.session_store :cookie_store, key: '_Rails3_2_session' # Use the database for sessions instead of the cookie-based default, # which shouldn't be used to store highly confidential information # (create the session table with "rails generate session_migration") # Rails32::Application.config.session_store :active_record_store rabl-0.11.4/fixtures/rails3_2/config/initializers/mime_types.rb0000644000004100000410000000042512432721713024512 0ustar www-datawww-data# Be sure to restart your server when you modify this file. # Add new mime types for use in respond_to blocks: # Mime::Type.register "text/richtext", :rtf # Mime::Type.register_alias "text/html", :iphone Mime::Type.register 'application/vnd.rabl-test_v1+json', :rabl_test_v1 rabl-0.11.4/fixtures/rails3_2/config/initializers/wrap_parameters.rb0000644000004100000410000000072112432721713025532 0ustar www-datawww-data# Be sure to restart your server when you modify this file. # # This file contains settings for ActionController::ParamsWrapper which # is enabled by default. # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. ActiveSupport.on_load(:action_controller) do wrap_parameters format: [:json] end # Disable root element in JSON by default. ActiveSupport.on_load(:active_record) do self.include_root_in_json = false end rabl-0.11.4/fixtures/rails3_2/config/initializers/backtrace_silencers.rb0000644000004100000410000000062412432721713026326 0ustar www-datawww-data# Be sure to restart your server when you modify this file. # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. # Rails.backtrace_cleaner.remove_silencers! rabl-0.11.4/fixtures/rails3_2/config/initializers/inflections.rb0000644000004100000410000000102512432721713024651 0ustar www-datawww-data# Be sure to restart your server when you modify this file. # Add new inflection rules using the following format # (all these examples are active by default): # ActiveSupport::Inflector.inflections do |inflect| # inflect.plural /^(ox)$/i, '\1en' # inflect.singular /^(ox)en/i, '\1' # inflect.irregular 'person', 'people' # inflect.uncountable %w( fish sheep ) # end # # These inflection rules are supported but not enabled by default: # ActiveSupport::Inflector.inflections do |inflect| # inflect.acronym 'RESTful' # end rabl-0.11.4/fixtures/rails3_2/config/boot.rb0000644000004100000410000000027712432721713020601 0ustar www-datawww-datarequire 'rubygems' # Set up gems listed in the Gemfile. ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE']) rabl-0.11.4/fixtures/rails3_2/config/environments/0000755000004100000410000000000012432721713022032 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/config/environments/test.rb0000644000004100000410000000276712432721713023352 0ustar www-datawww-dataRails32::Application.configure do # Settings specified here will take precedence over those in config/application.rb # The test environment is used exclusively to run your application's # test suite. You never need to work with it otherwise. Remember that # your test database is "scratch space" for the test suite and is wiped # and recreated between test runs. Don't rely on the data there! config.cache_classes = true # Configure static asset server for tests with Cache-Control for performance config.serve_static_assets = true config.static_cache_control = "public, max-age=3600" # Log error messages when you accidentally call methods on nil config.whiny_nils = true # Show full error reports and disable caching config.consider_all_requests_local = true config.action_controller.perform_caching = false # Raise exceptions instead of rendering exception templates config.action_dispatch.show_exceptions = false # Disable request forgery protection in test environment config.action_controller.allow_forgery_protection = false # Tell Action Mailer not to deliver emails to the real world. # The :test delivery method accumulates sent emails in the # ActionMailer::Base.deliveries array. config.action_mailer.delivery_method = :test # Raise exception on mass assignment protection for Active Record models config.active_record.mass_assignment_sanitizer = :strict # Print deprecation notices to the stderr config.active_support.deprecation = :stderr end rabl-0.11.4/fixtures/rails3_2/config/environments/production.rb0000644000004100000410000000462612432721713024555 0ustar www-datawww-dataRails32::Application.configure do # Settings specified here will take precedence over those in config/application.rb # Code is not reloaded between requests config.cache_classes = true # Full error reports are disabled and caching is turned on config.consider_all_requests_local = false config.action_controller.perform_caching = true # Disable Rails's static asset server (Apache or nginx will already do this) config.serve_static_assets = false # Compress JavaScripts and CSS config.assets.compress = true # Don't fallback to assets pipeline if a precompiled asset is missed config.assets.compile = false # Generate digests for assets URLs config.assets.digest = true # Defaults to Rails.root.join("public/assets") # config.assets.manifest = YOUR_PATH # Specifies the header that your server uses for sending files # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. # config.force_ssl = true # See everything in the log (default is :info) # config.log_level = :debug # Prepend all log lines with the following tags # config.log_tags = [ :subdomain, :uuid ] # Use a different logger for distributed setups # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) # Use a different cache store in production # config.cache_store = :mem_cache_store # Enable serving of images, stylesheets, and JavaScripts from an asset server # config.action_controller.asset_host = "http://assets.example.com" # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added) # config.assets.precompile += %w( search.js ) # Disable delivery errors, bad email addresses will be ignored # config.action_mailer.raise_delivery_errors = false # Enable threaded mode # config.threadsafe! # Enable locale fallbacks for I18n (makes lookups for any locale fall back to # the I18n.default_locale when a translation can not be found) config.i18n.fallbacks = true # Send deprecation notices to registered listeners config.active_support.deprecation = :notify # Log the query plan for queries taking more than this (works # with SQLite, MySQL, and PostgreSQL) # config.active_record.auto_explain_threshold_in_seconds = 0.5 end rabl-0.11.4/fixtures/rails3_2/config/environments/development.rb0000644000004100000410000000253612432721713024707 0ustar www-datawww-dataRails32::Application.configure do # Settings specified here will take precedence over those in config/application.rb # In the development environment your application's code is reloaded on # every request. This slows down response time but is perfect for development # since you don't have to restart the web server when you make code changes. config.cache_classes = false # Log error messages when you accidentally call methods on nil. config.whiny_nils = true # Show full error reports and disable caching config.consider_all_requests_local = true config.action_controller.perform_caching = false # Don't care if the mailer can't send config.action_mailer.raise_delivery_errors = false # Print deprecation notices to the Rails logger config.active_support.deprecation = :log # Only use best-standards-support built into browsers config.action_dispatch.best_standards_support = :builtin # Raise exception on mass assignment protection for Active Record models config.active_record.mass_assignment_sanitizer = :strict # Log the query plan for queries taking more than this (works # with SQLite, MySQL, and PostgreSQL) config.active_record.auto_explain_threshold_in_seconds = 0.5 # Do not compress assets config.assets.compress = false # Expands the lines which load the assets config.assets.debug = true end rabl-0.11.4/fixtures/rails3_2/config/database.yml0000644000004100000410000000110012432721713021562 0ustar www-datawww-data# SQLite version 3.x # gem install sqlite3 # # Ensure the SQLite 3 gem is defined in your Gemfile # gem 'sqlite3' development: adapter: sqlite3 database: db/development.sqlite3 pool: 5 timeout: 5000 # Warning: The database defined as "test" will be erased and # re-generated from your development database when you run "rake". # Do not set this db to the same as development or production. test: adapter: sqlite3 database: db/test.sqlite3 pool: 5 timeout: 5000 production: adapter: sqlite3 database: db/production.sqlite3 pool: 5 timeout: 5000 rabl-0.11.4/fixtures/rails3_2/config/routes.rb0000644000004100000410000000353012432721713021152 0ustar www-datawww-dataRails32::Application.routes.draw do resources :users resources :posts do member do get 'renderer' end end # The priority is based upon order of creation: # first created -> highest priority. # Sample of regular route: # match 'products/:id' => 'catalog#view' # Keep in mind you can assign values other than :controller and :action # Sample of named route: # match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase # This route can be invoked with purchase_url(:id => product.id) # Sample resource route (maps HTTP verbs to controller actions automatically): # resources :products # Sample resource route with options: # resources :products do # member do # get 'short' # post 'toggle' # end # # collection do # get 'sold' # end # end # Sample resource route with sub-resources: # resources :products do # resources :comments, :sales # resource :seller # end # Sample resource route with more complex sub-resources # resources :products do # resources :comments # resources :sales do # get 'recent', :on => :collection # end # end # Sample resource route within a namespace: # namespace :admin do # # Directs /admin/products/* to Admin::ProductsController # # (app/controllers/admin/products_controller.rb) # resources :products # end # You can have the root of your site routed with "root" # just remember to delete public/index.html. # root :to => 'welcome#index' # See how all your routes lay out with "rake routes" # This is a legacy wild controller route that's not recommended for RESTful applications. # Note: This route will make all actions in every controller accessible via GET requests. # match ':controller(/:action(/:id))(.:format)' end rabl-0.11.4/fixtures/rails3_2/config/environment.rb0000644000004100000410000000022712432721713022175 0ustar www-datawww-data# Load the rails application require File.expand_path('../application', __FILE__) # Initialize the rails application Rails32::Application.initialize! rabl-0.11.4/fixtures/rails3_2/config/locales/0000755000004100000410000000000012432721713020725 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/config/locales/en.yml0000644000004100000410000000032612432721713022053 0ustar www-datawww-data# Sample localization file for English. Add more files in this directory for other locales. # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. en: hello: "Hello world" rabl-0.11.4/fixtures/rails3_2/app/0000755000004100000410000000000012432721713016616 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/app/controllers/0000755000004100000410000000000012432721713021164 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/app/controllers/posts_controller.rb0000644000004100000410000000057412432721713025132 0ustar www-datawww-dataclass PostsController < ApplicationController respond_to :json, :xml, :html, :rabl_test_v1 def index @posts = Post.all(:order => "id ASC") end def show @post = Post.find(params[:id]) end def renderer post = Post.find(params[:id]) render json: Rabl.render(post, 'posts/renderer', view_path: 'app/views', format: :json, scope: view_context) end end rabl-0.11.4/fixtures/rails3_2/app/controllers/users_controller.rb0000644000004100000410000000027512432721713025121 0ustar www-datawww-dataclass UsersController < ApplicationController respond_to :json def index @users = User.all(:order => "username ASC") end def show @user = User.find(params[:id]) end end rabl-0.11.4/fixtures/rails3_2/app/controllers/application_controller.rb0000644000004100000410000000042512432721713026260 0ustar www-datawww-dataclass ApplicationController < ActionController::Base protect_from_forgery before_filter :default_format_json protected def default_format_json if(request.headers["HTTP_ACCEPT"].nil? && params[:format].nil?) request.format = "json" end end end rabl-0.11.4/fixtures/rails3_2/app/mailers/0000755000004100000410000000000012432721713020252 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/app/mailers/.gitkeep0000644000004100000410000000000012432721713021671 0ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/app/assets/0000755000004100000410000000000012432721713020120 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/app/assets/images/0000755000004100000410000000000012432721713021365 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3_2/app/assets/images/rails.png0000644000004100000410000001476612432721713023223 0ustar www-datawww-dataPNG  IHDR2@X${tEXtSoftwareAdobe ImageReadyqe<IDATxڬ[ \eR֮^;Iwga@`gGgDgtqDFqFDqF@NRU]˫|_-Qy^Ǹ.݋0W_6kbf̻ܸ6<4 w5~*r?9m&"M7@vm' {_S)Vi\WG?իjMd@ lDLX鸺W-TU+@EPo\&*Rnn, fDWrX|3M=\EJB[d6A'=tx^$a86̈{, ϱPepN*_W_3o;ޥ(0E:i6eXnhGf"L|S+(+.gФg=Ych=m#V_#}Ǫ|tR D8VՄM~xg!ni%Dy( B,{(Np$3iر$h.@e[a'eJԂyϠ4>H*MHQ(Jgt-֢QI ^d„@s-'- 51{'0 |n4ۉh{V@ܩw"BT =rzqPpBHȃ?ň ]-qpgsPiSӪg`jn)m 御B2L.x!jJP! K/\ ʮRB[09Trӈu. uH$ DDQ+:ݘٻ 3/nލ%Sjm2!&D/[EHwW A-RR!PeuHim"t6lFgЫ-O.1?ƞksX~VtmZJR11Nu&<⽩,Tb,`w WPx-G5 `մ/5pbAtIVJ_]0/DiH=ô#*77-3 VuQ0.pݔ%yw hљW0),2$b6&I/@bj$I(fx' JnO"`<-/LѮ%^ȫͶn2wҗ2}}XսL'Q-,m/ꤋ4#0Q&00NKrsA,Aײ)aIEC(ERK{8Ȭ[y?iI5$%f{}u F 1~;v1l'@F 'IF'm!K7"&]w 15#4Vižn[v 8Ě)>C=LBo~/3% wF4֓ʿ8>bWX@bb@IzP9IvFfQL!2cEP(se4~5RhAŽ90_? cMEteVOaOr B]pȱؓ"Eyx: NJ)bl׋hYuTdԫw=آMgwVPOFΒ25-TD[Z2>]V,xӛIOƅ)Jͺ[)?cn28p#(mk+./phʮQ6?w7HIoSj)1<#-N9O1ͰސkIKr:(ŗ;rR&<93v@w(w:~:TFSޒ" ՊTdT9PIb3JzTQׄBP23ƵW*|@^)Qw?Iq =,<@ B8);50H-=T SA@@f5r[T%#c|Z&w(B)tDQ%vyC(,Ɵ|ʰi&<#u:3EHkzд)ndF>1V2kFGYL KMQlR&TB,igv8]C8Sf#ą4Q'?,= aV9WEXYrr*!cƯ~),=yџ]jlGeE̺5r_2Ԏ}d"a]0M9PZG17nE"Rr\YQ)!|5U(d=^ŗo8+2NU6jB[B5V.]ŲW/^䩬 ;Y"Vi$2ٲ_c(F^Egq{CP/ #K8Y+Q M1>ܞAߏ,gytޕn,zE$V.v.PyLapG9Tn:uiRZ! zI0?Џ1u#$6ɱGMhFdtd|~d\O9Ij**zD؍b)PBҽh-q ql%/{Gz*d7=QS]:RQbUMPᒯ$% du] XefQz$('ИZH#ARXDB ~`0.F|XXK)wFolzyhߚKz>.&n EjU,2' &iw[d[ V)*Qavl QDit[VIQhR@$)y~m|>?cJ+VH'6? 7 i.XH8Fި)dAYUBjE".4w-?l2Y.RjWD@Bج.߆s[H-gASF3Fj]آBP떬_>M%bt ?_rլ -h]r_ž[nȶQ+Gԭ_\Ê Z٦fet(|U('.g VFEN9}Ll4T&nto¨Ӓ X F "_fYzF~y& Gu]$O[v#].@$VA`ⱧTѰZ[2u+/mUC_ TnyѠ |l\ M"G[R$d|:ěFIire"ٵt,+ی1Z11udt*K2 sd; [)xW.z2jTh#DV\NO &e_vU2B^%0FH(/ԘI2>=L]dv UUpk"ijB$,O-0y<}~*T5LErE4B߳XXN:<9>Ed -V*uBLsN**JxRU辖,T( Gu @ůY{u|CJF(OLbnմiKhpFtx8#9FsFڋDTAn1veF^M ^kf.ĆݠVʓǰ3JaY@n&jLl:McӚ…vu?9w!/~#hM ڛ ̴nMA}m W,)(î.N y%$*={P9c DzH>Blu޾K78x->V,'JU \L]l>W*r-hXf~oI Z3f玱>vN3 uZTgg}Վ363:.g /-H+"PKۉSZ4Z_GlXMc7";ҿ (5fMUCOF6 CNft>$S1VaR&4) ٗay]%W A*|gX{Qc>iTX1F M`|![$P4ʊ$#,dɌ(?KTJR۸S%C7jHb浃j+N$,[.@˹_ ?.3ĵH"U$Z^ X02!Kc 8q.NMI6N&3n8exoWfPIJB<pREAdo$*m)e9D 5X[T$LΠ:]C$n#mC[P~Yt*d?\q^WXs!E-2#_mw8;2!vw:DUn$)GiGn3_o EZE3k-EHv.OûzE>"֛}l\/-nرQHԽab*#K׋eIƳd#G et\ ,:MێÜIC}m ٽO?eb%ːٰStB|Aznaz*FlQ/K uu*1wDvE֯SJTK;(4kƣ;v2P9`k{?~_[hʢ^9фǡ;m|]o9<#jz\wD,8V]]%K9er懇0n^FcI>`Ub+kօO1|NO]t+,Ȑl_ˮ6 ĒDbrz^pe7^[aþo確jN+xsNC߅wμ7|za2, omrbZ~,pN>;?Y,z[u◿jq 4aqڶNu6Zid@h!!F9#,#UrOa0=Då ,,,bE#ȮX3ªޏ=a< =&_~ ٵѽacj񫒆LsXuXB (wzEk_QIف*4'ѣSl{.,p۵2`jp^؇nZXPź^]wމ]aQ-oI5O3a] _wb ŭL]$"|sԩȬ= VсLIUbYY搮͢I$tf$2|r;~'GSXkᇦԭF4b4 xo[,04F~<}ۭR%myb׾\mlO.4}tE\7}M)tՉ13xF [-26t䢄&E"9;ٜrq e)K!:bwY }g;Jר)5D$!Kɤ9߫-K$$ hlDUFF J{s2R6rC&&0;@>]/Z3E,k;( 2^09 3.0.17' # Bundle edge Rails instead: # gem 'rails', :git => 'git://github.com/rails/rails.git' gem 'sqlite3' gem 'json' gem 'rabl', :path => File.expand_path(File.dirname(__FILE__) + "/../../") # TEST gem 'riot', :group => "test" gem 'rack-test', :require => "rack/test", :group => "test" # Use unicorn as the web server # gem 'unicorn' # Deploy with Capistrano # gem 'capistrano' # To use debugger (ruby-debug for Ruby 1.8.7+, ruby-debug19 for Ruby 1.9.2+) # gem 'ruby-debug' # gem 'ruby-debug19', :require => 'ruby-debug' # Bundle the extra gems: # gem 'bj' # gem 'nokogiri' # gem 'sqlite3-ruby', :require => 'sqlite3' # gem 'aws-s3', :require => 'aws/s3' # Bundle gems for the local environment. Make sure to # put test-only gems in this group so their generators # and rake tasks are available in development mode: # group :development, :test do # gem 'webrat' # end rabl-0.11.4/fixtures/rails3/script/0000755000004100000410000000000012432721713017121 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3/script/rails0000755000004100000410000000044712432721713020166 0ustar www-datawww-data#!/usr/bin/env ruby # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. APP_PATH = File.expand_path('../../config/application', __FILE__) require File.expand_path('../../config/boot', __FILE__) require 'rails/commands' rabl-0.11.4/fixtures/rails3/db/0000755000004100000410000000000012432721713016202 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3/db/seeds.rb0000644000004100000410000000054112432721713017632 0ustar www-datawww-data# This file should contain all the record creation needed to seed the database with its default values. # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). # # Examples: # # cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }]) # Mayor.create(:name => 'Daley', :city => cities.first) rabl-0.11.4/fixtures/rails3/public/0000755000004100000410000000000012432721713017073 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3/public/images/0000755000004100000410000000000012432721713020340 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3/public/images/rails.png0000644000004100000410000001476612432721713022176 0ustar www-datawww-dataPNG  IHDR2@X${tEXtSoftwareAdobe ImageReadyqe<IDATxڬ[ \eR֮^;Iwga@`gGgDgtqDFqFDqF@NRU]˫|_-Qy^Ǹ.݋0W_6kbf̻ܸ6<4 w5~*r?9m&"M7@vm' {_S)Vi\WG?իjMd@ lDLX鸺W-TU+@EPo\&*Rnn, fDWrX|3M=\EJB[d6A'=tx^$a86̈{, ϱPepN*_W_3o;ޥ(0E:i6eXnhGf"L|S+(+.gФg=Ych=m#V_#}Ǫ|tR D8VՄM~xg!ni%Dy( B,{(Np$3iر$h.@e[a'eJԂyϠ4>H*MHQ(Jgt-֢QI ^d„@s-'- 51{'0 |n4ۉh{V@ܩw"BT =rzqPpBHȃ?ň ]-qpgsPiSӪg`jn)m 御B2L.x!jJP! K/\ ʮRB[09Trӈu. uH$ DDQ+:ݘٻ 3/nލ%Sjm2!&D/[EHwW A-RR!PeuHim"t6lFgЫ-O.1?ƞksX~VtmZJR11Nu&<⽩,Tb,`w WPx-G5 `մ/5pbAtIVJ_]0/DiH=ô#*77-3 VuQ0.pݔ%yw hљW0),2$b6&I/@bj$I(fx' JnO"`<-/LѮ%^ȫͶn2wҗ2}}XսL'Q-,m/ꤋ4#0Q&00NKrsA,Aײ)aIEC(ERK{8Ȭ[y?iI5$%f{}u F 1~;v1l'@F 'IF'm!K7"&]w 15#4Vižn[v 8Ě)>C=LBo~/3% wF4֓ʿ8>bWX@bb@IzP9IvFfQL!2cEP(se4~5RhAŽ90_? cMEteVOaOr B]pȱؓ"Eyx: NJ)bl׋hYuTdԫw=آMgwVPOFΒ25-TD[Z2>]V,xӛIOƅ)Jͺ[)?cn28p#(mk+./phʮQ6?w7HIoSj)1<#-N9O1ͰސkIKr:(ŗ;rR&<93v@w(w:~:TFSޒ" ՊTdT9PIb3JzTQׄBP23ƵW*|@^)Qw?Iq =,<@ B8);50H-=T SA@@f5r[T%#c|Z&w(B)tDQ%vyC(,Ɵ|ʰi&<#u:3EHkzд)ndF>1V2kFGYL KMQlR&TB,igv8]C8Sf#ą4Q'?,= aV9WEXYrr*!cƯ~),=yџ]jlGeE̺5r_2Ԏ}d"a]0M9PZG17nE"Rr\YQ)!|5U(d=^ŗo8+2NU6jB[B5V.]ŲW/^䩬 ;Y"Vi$2ٲ_c(F^Egq{CP/ #K8Y+Q M1>ܞAߏ,gytޕn,zE$V.v.PyLapG9Tn:uiRZ! zI0?Џ1u#$6ɱGMhFdtd|~d\O9Ij**zD؍b)PBҽh-q ql%/{Gz*d7=QS]:RQbUMPᒯ$% du] XefQz$('ИZH#ARXDB ~`0.F|XXK)wFolzyhߚKz>.&n EjU,2' &iw[d[ V)*Qavl QDit[VIQhR@$)y~m|>?cJ+VH'6? 7 i.XH8Fި)dAYUBjE".4w-?l2Y.RjWD@Bج.߆s[H-gASF3Fj]آBP떬_>M%bt ?_rլ -h]r_ž[nȶQ+Gԭ_\Ê Z٦fet(|U('.g VFEN9}Ll4T&nto¨Ӓ X F "_fYzF~y& Gu]$O[v#].@$VA`ⱧTѰZ[2u+/mUC_ TnyѠ |l\ M"G[R$d|:ěFIire"ٵt,+ی1Z11udt*K2 sd; [)xW.z2jTh#DV\NO &e_vU2B^%0FH(/ԘI2>=L]dv UUpk"ijB$,O-0y<}~*T5LErE4B߳XXN:<9>Ed -V*uBLsN**JxRU辖,T( Gu @ůY{u|CJF(OLbnմiKhpFtx8#9FsFڋDTAn1veF^M ^kf.ĆݠVʓǰ3JaY@n&jLl:McӚ…vu?9w!/~#hM ڛ ̴nMA}m W,)(î.N y%$*={P9c DzH>Blu޾K78x->V,'JU \L]l>W*r-hXf~oI Z3f玱>vN3 uZTgg}Վ363:.g /-H+"PKۉSZ4Z_GlXMc7";ҿ (5fMUCOF6 CNft>$S1VaR&4) ٗay]%W A*|gX{Qc>iTX1F M`|![$P4ʊ$#,dɌ(?KTJR۸S%C7jHb浃j+N$,[.@˹_ ?.3ĵH"U$Z^ X02!Kc 8q.NMI6N&3n8exoWfPIJB<pREAdo$*m)e9D 5X[T$LΠ:]C$n#mC[P~Yt*d?\q^WXs!E-2#_mw8;2!vw:DUn$)GiGn3_o EZE3k-EHv.OûzE>"֛}l\/-nرQHԽab*#K׋eIƳd#G et\ ,:MێÜIC}m ٽO?eb%ːٰStB|Aznaz*FlQ/K uu*1wDvE֯SJTK;(4kƣ;v2P9`k{?~_[hʢ^9фǡ;m|]o9<#jz\wD,8V]]%K9er懇0n^FcI>`Ub+kօO1|NO]t+,Ȑl_ˮ6 ĒDbrz^pe7^[aþo確jN+xsNC߅wμ7|za2, omrbZ~,pN>;?Y,z[u◿jq 4aqڶNu6Zid@h!!F9#,#UrOa0=Då ,,,bE#ȮX3ªޏ=a< =&_~ ٵѽacj񫒆LsXuXB (wzEk_QIف*4'ѣSl{.,p۵2`jp^؇nZXPź^]wމ]aQ-oI5O3a] _wb ŭL]$"|sԩȬ= VсLIUbYY搮͢I$tf$2|r;~'GSXkᇦԭF4b4 xo[,04F~<}ۭR%myb׾\mlO.4}tE\7}M)tՉ13xF [-26t䢄&E"9;ٜrq e)K!:bwY }g;Jר)5D$!Kɤ9߫-K$$ hlDUFF J{s2R6rC&&0;@>]/Z3E,k;( 2^09 The change you wanted was rejected (422)

The change you wanted was rejected.

Maybe you tried to change something you didn't have access to.

rabl-0.11.4/fixtures/rails3/public/favicon.ico0000644000004100000410000000000012432721713021202 0ustar www-datawww-datarabl-0.11.4/fixtures/rails3/public/robots.txt0000644000004100000410000000031412432721713021142 0ustar www-datawww-data# See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file # # To ban all spiders from the entire site uncomment the next two lines: # User-Agent: * # Disallow: / rabl-0.11.4/fixtures/rails3/public/404.html0000644000004100000410000000133012432721713020265 0ustar www-datawww-data The page you were looking for doesn't exist (404)

The page you were looking for doesn't exist.

You may have mistyped the address or the page may have moved.

rabl-0.11.4/fixtures/rails3/public/stylesheets/0000755000004100000410000000000012432721713021447 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3/public/stylesheets/.gitkeep0000644000004100000410000000000012432721713023066 0ustar www-datawww-datarabl-0.11.4/fixtures/rails3/public/500.html0000644000004100000410000000133012432721713020262 0ustar www-datawww-data We're sorry, but something went wrong (500)

We're sorry, but something went wrong.

We've been notified about this issue and we'll take a look at it shortly.

rabl-0.11.4/fixtures/rails3/public/index.html0000644000004100000410000001322412432721713021072 0ustar www-datawww-data Ruby on Rails: Welcome aboard

Getting started

Here’s how to get rolling:

  1. Use rails generate to create your models and controllers

    To see all available options, run it without parameters.

  2. Set up a default route and remove or rename this file

    Routes are set up in config/routes.rb.

  3. Create your database

    Run rake db:migrate to create your database. If you're not using SQLite (the default), edit config/database.yml with your username and password.

rabl-0.11.4/fixtures/rails3/lib/0000755000004100000410000000000012432721713016363 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3/lib/tasks/0000755000004100000410000000000012432721713017510 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3/lib/tasks/.gitkeep0000644000004100000410000000000012432721713021127 0ustar www-datawww-datarabl-0.11.4/fixtures/rails3/test/0000755000004100000410000000000012432721713016574 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3/test/test_helper.rb0000644000004100000410000000140312432721713021435 0ustar www-datawww-data# Load Silence Functionality require File.expand_path(File.dirname(__FILE__) + "/../../../test/silence.rb") # Load Environment silence_warnings do ENV["RAILS_ENV"] = "test" require File.expand_path('../../config/environment', __FILE__) require 'rails/test_help' end # Load Riot Test Environment require File.expand_path(File.dirname(__FILE__) + "/../../../test/integration/test_init.rb") # Run Migrations silence_stream(STDOUT) do dbconf = YAML::load(File.open('config/database.yml'))[Rails.env] ActiveRecord::Base.establish_connection(dbconf) ActiveRecord::Base.logger = Logger.new(File.open('log/database.log', 'a')) silence_stream(STDOUT) { ActiveRecord::Migrator.up('db/migrate') } end class Riot::Situation def app Rails.application end endrabl-0.11.4/fixtures/rails3/test/functional/0000755000004100000410000000000012432721713020736 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3/test/functional/users_controller_test.rb0000644000004100000410000000634312432721713025734 0ustar www-datawww-data# Lives in /test/integration/users_controller_test.rb # Symlinked to fixture applications begin # Sinatra require File.expand_path(File.dirname(__FILE__) + '/../../test_config.rb') rescue LoadError # Rails require File.expand_path(File.dirname(__FILE__) + '/../test_helper.rb') end context "UsersController" do helper(:json_output) { JSON.parse(last_response.body) } setup do create_users! end context "for index action" do # Tests `collection @users` extending from 'show' template setup do get "/users" end # Attributes (regular) asserts("contains user usernames") do json_output.map { |u| u["user"]["username"] } end.equals { @users.map(&:username) } asserts("contains email") do json_output.map { |u| u["user"]["email"] } end.equals { @users.map(&:email) } asserts("contains location") do json_output.map { |u| u["user"]["location"] } end.equals { @users.map(&:location) } # Attributes (custom name) asserts("contains registered_at") do json_output.map { |u| u["user"]["registered_at"] } end.equals { @users.map(&:created_at).map(&:iso8601) } # Node (renders based on attribute) asserts("contains role") do json_output.map { |u| u["user"]["role"] } end.equals ['normal', 'normal', 'admin'] # Child (custom collection name) asserts("contains formatted phone numbers") do json_output.map { |u| u["user"]["pnumbers"].map { |n| n["pnumber"]["formatted"] } } end.equals { @users.map { |u| u.phone_numbers.map(&:formatted) } } # Node (renders collection partial) asserts("contains formatted node numbers") do json_output.map { |u| u["user"]["node_numbers"].map { |n| n["formatted"] } } end.equals { @users.map { |u| u.phone_numbers.map(&:formatted) } } end # index context "for show action" do # Tests `object :user => :person` custom parent node name setup do get "/users/#{@user1.id}" end # Attributes (regular) asserts("contains username") { json_output["person"]["username"] }.equals { @user1.username } asserts("contains email") { json_output["person"]["email"] }.equals { @user1.email } asserts("contains location") { json_output["person"]["location"] }.equals { @user1.location } # Attributes (custom name) asserts("contains registered_at") { json_output["person"]["registered_at"] }.equals { @user1.created_at.iso8601 } # Node (renders based on attribute) asserts("contains role node") { json_output["person"]["role"] }.equals "normal" # Child (custom collection name) asserts("contains first phone number") { json_output["person"]["pnumbers"][0]["pnumber"]["formatted"] }.equals { @user1.phone_numbers[0].formatted } asserts("contains second phone number") { json_output["person"]["pnumbers"][1]["pnumber"]["formatted"] }.equals { @user1.phone_numbers[1].formatted } # Node (renders collection partial) asserts("contains first node number") { json_output["person"]["node_numbers"][0]["formatted"] }.equals { @user1.phone_numbers[0].formatted } asserts("contains second node number") { json_output["person"]["node_numbers"][1]["formatted"] }.equals { @user1.phone_numbers[1].formatted } end # show endrabl-0.11.4/fixtures/rails3/test/functional/posts_controller_test.rb0000644000004100000410000001021312432721713025732 0ustar www-datawww-data# Lives in /test/integration/posts_controller_test.rb # Symlinked to fixture applications begin # Padrino require File.expand_path(File.dirname(__FILE__) + '/../../test_config.rb') rescue LoadError # Rails require File.expand_path(File.dirname(__FILE__) + '/../test_helper.rb') end context "PostsController" do helper(:json_output) { JSON.parse(last_response.body) } setup do create_users! Post.delete_all @post1 = Post.create(:title => "Foo", :body => "Bar", :user_id => @user1.id) @post2 = Post.create(:title => "Baz", :body => "Bah", :user_id => @user2.id) @post3 = Post.create(:title => "Kaz", :body => "Paz", :user_id => @user3.id) @posts = [@post1, @post2, @post3] end context "for index action" do setup do get "/posts", :format => :json end # Attributes (regular) asserts("contains post titles") do json_output['articles'].map { |o| o["article"]["title"] } end.equals { @posts.map(&:title) } asserts("contains post bodies") do json_output['articles'].map { |o| o["article"]["body"] } end.equals { @posts.map(&:body) } # Attributes (custom name) asserts("contains post posted_at") do json_output['articles'].map { |o| o["article"]["posted_at"] } end.equals { @posts.map(&:created_at).map(&:iso8601) } # Child asserts("contains post user child username") do json_output['articles'].map { |o| o["article"]["user"]["username"] } end.equals { @posts.map(&:user).map(&:username) } asserts("contains post user child role") do json_output['articles'].map { |o| o["article"]["user"]["role"] } end.equals { ["normal", "normal", "admin"] } # Child Numbers of the Child User asserts("contains post user child numbers") do json_output['articles'].map { |o| o["article"]["user"]["pnumbers"][0]["pnumber"]["formatted"] } end.equals { @posts.map(&:user).map(&:phone_numbers).map(&:first).map(&:formatted) } # Glue (username to article) asserts("contains glued usernames") do json_output['articles'].map { |o| o["article"]["author_name"] } end.equals { @posts.map(&:user).map(&:username) } # Conditional Child (admin) asserts("contains admin child only for admins") do json_output['articles'].map { |o| o["article"]["admin"]["username"] if o["article"].has_key?("admin") }.compact end.equals { [@user3.username] } # Conditional Node (created_by_admin) asserts("contains created_by_admin node for admins") do json_output['articles'].last['article']['created_by_admin'] end.equals { true } denies("contains no created_by_admin node for non-admins") do json_output['articles'].first['article'] end.includes(:created_by_admin) end # index action context "for show action" do setup do get "/posts/#{@post1.id}", :format => :json json_output['post'] end # Attributes (regular) asserts("contains post title") { topic['title'] }.equals { @post1.title } asserts("contains post body") { topic['body'] }.equals { @post1.body } # Attributes (custom name) asserts("contains post posted_at") { topic['posted_at'] }.equals { @post1.created_at.iso8601 } # Child asserts("contains post user child username") { topic["user"]["username"] }.equals { @post1.user.username } asserts("contains post user child role") { topic["user"]["role"] }.equals { "normal" } # Child Numbers of the Child User asserts("contains post user child numbers") do topic["user"]["pnumbers"][0]["pnumber"]["formatted"] end.equals { @post1.user.phone_numbers[0].formatted } # Glue (username to article) asserts("contains glued username") { topic["author_name"] }.equals { @post1.user.username } # Non-ORM Date Node Partial context "for date node" do setup { json_output['post']['created_date'] } asserts("contains date partial with day") { topic['day'] }.equals { @post1.created_at.day } asserts("contains date partial with hour") { topic['hour'] }.equals { @post1.created_at.hour } asserts("contains date partial with full") { topic['full'] }.equals { @post1.created_at.iso8601 } end # date node end # show action end rabl-0.11.4/fixtures/rails3/.gitignore0000644000004100000410000000004412432721713017603 0ustar www-datawww-data.bundle db/*.sqlite3 log/*.log tmp/ rabl-0.11.4/fixtures/rails3/config/0000755000004100000410000000000012432721713017062 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3/config/application.rb0000644000004100000410000000360412432721713021715 0ustar www-datawww-datarequire File.expand_path('../boot', __FILE__) require 'rails/all' # If you have a Gemfile, require the gems listed there, including any gems # you've limited to :test, :development, or :production. Bundler.require(:default, Rails.env) if defined?(Bundler) module Rails3 class Application < Rails::Application # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers # -- all .rb files in that directory are automatically loaded. # Custom directories with classes and modules you want to be autoloadable. # config.autoload_paths += %W(#{config.root}/extras) # Only load the plugins named here, in the order given (default is alphabetical). # :all can be used as a placeholder for all plugins not explicitly named. # config.plugins = [ :exception_notification, :ssl_requirement, :all ] # Activate observers that should always be running. # config.active_record.observers = :cacher, :garbage_collector, :forum_observer # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. # config.time_zone = 'Central Time (US & Canada)' # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] # config.i18n.default_locale = :de # JavaScript files you want as :defaults (application.js is always included). # config.action_view.javascript_expansions[:defaults] = %w(jquery rails) # Configure the default encoding used in templates for Ruby 1.9. config.encoding = "utf-8" # Configure sensitive parameters which will be filtered from the log file. config.filter_parameters += [:password] end end rabl-0.11.4/fixtures/rails3/config/initializers/0000755000004100000410000000000012432721713021570 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3/config/initializers/secret_token.rb0000644000004100000410000000076112432721713024606 0ustar www-datawww-data# Be sure to restart your server when you modify this file. # Your secret key for verifying the integrity of signed cookies. # If you change this key, all old signed cookies will become invalid! # Make sure the secret is at least 30 characters and all random, # no regular words or you'll be exposed to dictionary attacks. Rails3::Application.config.secret_token = '33a413cf1c720ae36788faebb621dd9350d1c5a17f4787d6c0c9acad23e116507f246cce7fa8f70d1e6ac73c3fe5080b007b774b769166a9515f2eb6c46f47f2' rabl-0.11.4/fixtures/rails3/config/initializers/session_store.rb0000644000004100000410000000063512432721713025020 0ustar www-datawww-data# Be sure to restart your server when you modify this file. Rails3::Application.config.session_store :cookie_store, :key => '_rails3_session' # Use the database for sessions instead of the cookie-based default, # which shouldn't be used to store highly confidential information # (create the session table with "rails generate session_migration") # Rails3::Application.config.session_store :active_record_store rabl-0.11.4/fixtures/rails3/config/initializers/mime_types.rb0000644000004100000410000000031512432721713024267 0ustar www-datawww-data# Be sure to restart your server when you modify this file. # Add new mime types for use in respond_to blocks: # Mime::Type.register "text/richtext", :rtf # Mime::Type.register_alias "text/html", :iphone rabl-0.11.4/fixtures/rails3/config/initializers/backtrace_silencers.rb0000644000004100000410000000062412432721713026105 0ustar www-datawww-data# Be sure to restart your server when you modify this file. # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. # Rails.backtrace_cleaner.remove_silencers! rabl-0.11.4/fixtures/rails3/config/initializers/inflections.rb0000644000004100000410000000057012432721713024434 0ustar www-datawww-data# Be sure to restart your server when you modify this file. # Add new inflection rules using the following format # (all these examples are active by default): # ActiveSupport::Inflector.inflections do |inflect| # inflect.plural /^(ox)$/i, '\1en' # inflect.singular /^(ox)en/i, '\1' # inflect.irregular 'person', 'people' # inflect.uncountable %w( fish sheep ) # end rabl-0.11.4/fixtures/rails3/config/boot.rb0000644000004100000410000000027712432721713020360 0ustar www-datawww-datarequire 'rubygems' # Set up gems listed in the Gemfile. ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE']) rabl-0.11.4/fixtures/rails3/config/environments/0000755000004100000410000000000012432721713021611 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3/config/environments/test.rb0000644000004100000410000000274612432721713023126 0ustar www-datawww-dataRails3::Application.configure do # Settings specified here will take precedence over those in config/application.rb # The test environment is used exclusively to run your application's # test suite. You never need to work with it otherwise. Remember that # your test database is "scratch space" for the test suite and is wiped # and recreated between test runs. Don't rely on the data there! config.cache_classes = true # Log error messages when you accidentally call methods on nil. config.whiny_nils = true # Show full error reports and disable caching config.consider_all_requests_local = true config.action_controller.perform_caching = false # Raise exceptions instead of rendering exception templates config.action_dispatch.show_exceptions = false # Disable request forgery protection in test environment config.action_controller.allow_forgery_protection = false # Tell Action Mailer not to deliver emails to the real world. # The :test delivery method accumulates sent emails in the # ActionMailer::Base.deliveries array. config.action_mailer.delivery_method = :test # Use SQL instead of Active Record's schema dumper when creating the test database. # This is necessary if your schema can't be completely dumped by the schema dumper, # like if you have constraints or database-specific column types # config.active_record.schema_format = :sql # Print deprecation notices to the stderr config.active_support.deprecation = :stderr end rabl-0.11.4/fixtures/rails3/config/environments/production.rb0000644000004100000410000000333312432721713024326 0ustar www-datawww-dataRails3::Application.configure do # Settings specified here will take precedence over those in config/application.rb # The production environment is meant for finished, "live" apps. # Code is not reloaded between requests config.cache_classes = true # Full error reports are disabled and caching is turned on config.consider_all_requests_local = false config.action_controller.perform_caching = true # Specifies the header that your server uses for sending files config.action_dispatch.x_sendfile_header = "X-Sendfile" # For nginx: # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # If you have no front-end server that supports something like X-Sendfile, # just comment this out and Rails will serve the files # See everything in the log (default is :info) # config.log_level = :debug # Use a different logger for distributed setups # config.logger = SyslogLogger.new # Use a different cache store in production # config.cache_store = :mem_cache_store # Disable Rails's static asset server # In production, Apache or nginx will already do this config.serve_static_assets = false # Enable serving of images, stylesheets, and javascripts from an asset server # config.action_controller.asset_host = "http://assets.example.com" # Disable delivery errors, bad email addresses will be ignored # config.action_mailer.raise_delivery_errors = false # Enable threaded mode # config.threadsafe! # Enable locale fallbacks for I18n (makes lookups for any locale fall back to # the I18n.default_locale when a translation can not be found) config.i18n.fallbacks = true # Send deprecation notices to registered listeners config.active_support.deprecation = :notify end rabl-0.11.4/fixtures/rails3/config/environments/development.rb0000644000004100000410000000173212432721713024463 0ustar www-datawww-dataRails3::Application.configure do # Settings specified here will take precedence over those in config/application.rb # In the development environment your application's code is reloaded on # every request. This slows down response time but is perfect for development # since you don't have to restart the webserver when you make code changes. config.cache_classes = false # Log error messages when you accidentally call methods on nil. config.whiny_nils = true # Show full error reports and disable caching config.consider_all_requests_local = true config.action_view.debug_rjs = true config.action_controller.perform_caching = false # Don't care if the mailer can't send config.action_mailer.raise_delivery_errors = false # Print deprecation notices to the Rails logger config.active_support.deprecation = :log # Only use best-standards-support built into browsers config.action_dispatch.best_standards_support = :builtin end rabl-0.11.4/fixtures/rails3/config/database.yml0000644000004100000410000000076512432721713021361 0ustar www-datawww-data# SQLite version 3.x # gem install sqlite3 development: adapter: sqlite3 database: db/development.sqlite3 pool: 5 timeout: 5000 # Warning: The database defined as "test" will be erased and # re-generated from your development database when you run "rake". # Do not set this db to the same as development or production. test: adapter: sqlite3 database: db/test.sqlite3 pool: 5 timeout: 5000 production: adapter: sqlite3 database: db/production.sqlite3 pool: 5 timeout: 5000 rabl-0.11.4/fixtures/rails3/config/routes.rb0000644000004100000410000000344412432721713020735 0ustar www-datawww-dataRails3::Application.routes.draw do resources :users resources :posts # The priority is based upon order of creation: # first created -> highest priority. # Sample of regular route: # match 'products/:id' => 'catalog#view' # Keep in mind you can assign values other than :controller and :action # Sample of named route: # match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase # This route can be invoked with purchase_url(:id => product.id) # Sample resource route (maps HTTP verbs to controller actions automatically): # resources :products # Sample resource route with options: # resources :products do # member do # get 'short' # post 'toggle' # end # # collection do # get 'sold' # end # end # Sample resource route with sub-resources: # resources :products do # resources :comments, :sales # resource :seller # end # Sample resource route with more complex sub-resources # resources :products do # resources :comments # resources :sales do # get 'recent', :on => :collection # end # end # Sample resource route within a namespace: # namespace :admin do # # Directs /admin/products/* to Admin::ProductsController # # (app/controllers/admin/products_controller.rb) # resources :products # end # You can have the root of your site routed with "root" # just remember to delete public/index.html. # root :to => "welcome#index" # See how all your routes lay out with "rake routes" # This is a legacy wild controller route that's not recommended for RESTful applications. # Note: This route will make all actions in every controller accessible via GET requests. # match ':controller(/:action(/:id(.:format)))' end rabl-0.11.4/fixtures/rails3/config/environment.rb0000644000004100000410000000022612432721713021753 0ustar www-datawww-data# Load the rails application require File.expand_path('../application', __FILE__) # Initialize the rails application Rails3::Application.initialize! rabl-0.11.4/fixtures/rails3/config/locales/0000755000004100000410000000000012432721713020504 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3/config/locales/en.yml0000644000004100000410000000032512432721713021631 0ustar www-datawww-data# Sample localization file for English. Add more files in this directory for other locales. # See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. en: hello: "Hello world" rabl-0.11.4/fixtures/rails3/app/0000755000004100000410000000000012432721713016375 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3/app/controllers/0000755000004100000410000000000012432721713020743 5ustar www-datawww-datarabl-0.11.4/fixtures/rails3/app/controllers/posts_controller.rb0000644000004100000410000000030412432721713024700 0ustar www-datawww-dataclass PostsController < ApplicationController respond_to :json, :xml, :html def index @posts = Post.all(:order => "id ASC") end def show @post = Post.find(params[:id]) end end rabl-0.11.4/fixtures/rails3/app/controllers/users_controller.rb0000644000004100000410000000027512432721713024700 0ustar www-datawww-dataclass UsersController < ApplicationController respond_to :json def index @users = User.all(:order => "username ASC") end def show @user = User.find(params[:id]) end end rabl-0.11.4/fixtures/rails3/app/controllers/application_controller.rb0000644000004100000410000000042512432721713026037 0ustar www-datawww-dataclass ApplicationController < ActionController::Base protect_from_forgery before_filter :default_format_json protected def default_format_json if(request.headers["HTTP_ACCEPT"].nil? && params[:format].nil?) request.format = "json" end end end rabl-0.11.4/fixtures/rails3/config.ru0000644000004100000410000000023412432721713017431 0ustar www-datawww-data# This file is used by Rack-based servers to start the application. require ::File.expand_path('../config/environment', __FILE__) run Rails3::Application rabl-0.11.4/fixtures/sinatra_test/0000755000004100000410000000000012432721713017120 5ustar www-datawww-datarabl-0.11.4/fixtures/sinatra_test/Rakefile0000644000004100000410000000021412432721713020562 0ustar www-datawww-datarequire 'rake/testtask' Rake::TestTask.new("test:rabl") do |test| test.pattern = "test/functional/**/*_test.rb" test.verbose = true endrabl-0.11.4/fixtures/sinatra_test/Gemfile0000644000004100000410000000050512432721713020413 0ustar www-datawww-datasource 'https://rubygems.org' gem 'rake' gem 'activerecord', :require => "active_record" gem 'sqlite3' gem 'sinatra', '>= 1.3.3' gem 'json' gem 'rabl', :path => File.expand_path(File.dirname(__FILE__) + "/../../") # Test requirements gem 'riot', :group => "test" gem 'rack-test', :require => "rack/test", :group => "test" rabl-0.11.4/fixtures/sinatra_test/test/0000755000004100000410000000000012432721713020077 5ustar www-datawww-datarabl-0.11.4/fixtures/sinatra_test/test/test_helper.rb0000644000004100000410000000107512432721713022745 0ustar www-datawww-data# Load Silence Functionality require File.expand_path(File.dirname(__FILE__) + "/../../../test/silence.rb") silence_warnings do PADRINO_ENV = 'test' unless defined?(PADRINO_ENV) require 'bundler' Bundler.require require File.expand_path(File.dirname(__FILE__) + "/../app.rb") silence_stream(STDOUT) { ActiveRecord::Migrator.up('db/migrate') } # Load up test migrations end # Load Riot Test Environment require File.expand_path(File.dirname(__FILE__) + "/../../../test/integration/test_init.rb") class Riot::Situation def app @app || SinatraTest end endrabl-0.11.4/fixtures/sinatra_test/test/functional/0000755000004100000410000000000012432721713022241 5ustar www-datawww-datarabl-0.11.4/fixtures/sinatra_test/test/functional/users_controller_test.rb0000644000004100000410000000634312432721713027237 0ustar www-datawww-data# Lives in /test/integration/users_controller_test.rb # Symlinked to fixture applications begin # Sinatra require File.expand_path(File.dirname(__FILE__) + '/../../test_config.rb') rescue LoadError # Rails require File.expand_path(File.dirname(__FILE__) + '/../test_helper.rb') end context "UsersController" do helper(:json_output) { JSON.parse(last_response.body) } setup do create_users! end context "for index action" do # Tests `collection @users` extending from 'show' template setup do get "/users" end # Attributes (regular) asserts("contains user usernames") do json_output.map { |u| u["user"]["username"] } end.equals { @users.map(&:username) } asserts("contains email") do json_output.map { |u| u["user"]["email"] } end.equals { @users.map(&:email) } asserts("contains location") do json_output.map { |u| u["user"]["location"] } end.equals { @users.map(&:location) } # Attributes (custom name) asserts("contains registered_at") do json_output.map { |u| u["user"]["registered_at"] } end.equals { @users.map(&:created_at).map(&:iso8601) } # Node (renders based on attribute) asserts("contains role") do json_output.map { |u| u["user"]["role"] } end.equals ['normal', 'normal', 'admin'] # Child (custom collection name) asserts("contains formatted phone numbers") do json_output.map { |u| u["user"]["pnumbers"].map { |n| n["pnumber"]["formatted"] } } end.equals { @users.map { |u| u.phone_numbers.map(&:formatted) } } # Node (renders collection partial) asserts("contains formatted node numbers") do json_output.map { |u| u["user"]["node_numbers"].map { |n| n["formatted"] } } end.equals { @users.map { |u| u.phone_numbers.map(&:formatted) } } end # index context "for show action" do # Tests `object :user => :person` custom parent node name setup do get "/users/#{@user1.id}" end # Attributes (regular) asserts("contains username") { json_output["person"]["username"] }.equals { @user1.username } asserts("contains email") { json_output["person"]["email"] }.equals { @user1.email } asserts("contains location") { json_output["person"]["location"] }.equals { @user1.location } # Attributes (custom name) asserts("contains registered_at") { json_output["person"]["registered_at"] }.equals { @user1.created_at.iso8601 } # Node (renders based on attribute) asserts("contains role node") { json_output["person"]["role"] }.equals "normal" # Child (custom collection name) asserts("contains first phone number") { json_output["person"]["pnumbers"][0]["pnumber"]["formatted"] }.equals { @user1.phone_numbers[0].formatted } asserts("contains second phone number") { json_output["person"]["pnumbers"][1]["pnumber"]["formatted"] }.equals { @user1.phone_numbers[1].formatted } # Node (renders collection partial) asserts("contains first node number") { json_output["person"]["node_numbers"][0]["formatted"] }.equals { @user1.phone_numbers[0].formatted } asserts("contains second node number") { json_output["person"]["node_numbers"][1]["formatted"] }.equals { @user1.phone_numbers[1].formatted } end # show endrabl-0.11.4/fixtures/sinatra_test/test/functional/posts_controller_test.rb0000644000004100000410000001021312432721713027235 0ustar www-datawww-data# Lives in /test/integration/posts_controller_test.rb # Symlinked to fixture applications begin # Padrino require File.expand_path(File.dirname(__FILE__) + '/../../test_config.rb') rescue LoadError # Rails require File.expand_path(File.dirname(__FILE__) + '/../test_helper.rb') end context "PostsController" do helper(:json_output) { JSON.parse(last_response.body) } setup do create_users! Post.delete_all @post1 = Post.create(:title => "Foo", :body => "Bar", :user_id => @user1.id) @post2 = Post.create(:title => "Baz", :body => "Bah", :user_id => @user2.id) @post3 = Post.create(:title => "Kaz", :body => "Paz", :user_id => @user3.id) @posts = [@post1, @post2, @post3] end context "for index action" do setup do get "/posts", :format => :json end # Attributes (regular) asserts("contains post titles") do json_output['articles'].map { |o| o["article"]["title"] } end.equals { @posts.map(&:title) } asserts("contains post bodies") do json_output['articles'].map { |o| o["article"]["body"] } end.equals { @posts.map(&:body) } # Attributes (custom name) asserts("contains post posted_at") do json_output['articles'].map { |o| o["article"]["posted_at"] } end.equals { @posts.map(&:created_at).map(&:iso8601) } # Child asserts("contains post user child username") do json_output['articles'].map { |o| o["article"]["user"]["username"] } end.equals { @posts.map(&:user).map(&:username) } asserts("contains post user child role") do json_output['articles'].map { |o| o["article"]["user"]["role"] } end.equals { ["normal", "normal", "admin"] } # Child Numbers of the Child User asserts("contains post user child numbers") do json_output['articles'].map { |o| o["article"]["user"]["pnumbers"][0]["pnumber"]["formatted"] } end.equals { @posts.map(&:user).map(&:phone_numbers).map(&:first).map(&:formatted) } # Glue (username to article) asserts("contains glued usernames") do json_output['articles'].map { |o| o["article"]["author_name"] } end.equals { @posts.map(&:user).map(&:username) } # Conditional Child (admin) asserts("contains admin child only for admins") do json_output['articles'].map { |o| o["article"]["admin"]["username"] if o["article"].has_key?("admin") }.compact end.equals { [@user3.username] } # Conditional Node (created_by_admin) asserts("contains created_by_admin node for admins") do json_output['articles'].last['article']['created_by_admin'] end.equals { true } denies("contains no created_by_admin node for non-admins") do json_output['articles'].first['article'] end.includes(:created_by_admin) end # index action context "for show action" do setup do get "/posts/#{@post1.id}", :format => :json json_output['post'] end # Attributes (regular) asserts("contains post title") { topic['title'] }.equals { @post1.title } asserts("contains post body") { topic['body'] }.equals { @post1.body } # Attributes (custom name) asserts("contains post posted_at") { topic['posted_at'] }.equals { @post1.created_at.iso8601 } # Child asserts("contains post user child username") { topic["user"]["username"] }.equals { @post1.user.username } asserts("contains post user child role") { topic["user"]["role"] }.equals { "normal" } # Child Numbers of the Child User asserts("contains post user child numbers") do topic["user"]["pnumbers"][0]["pnumber"]["formatted"] end.equals { @post1.user.phone_numbers[0].formatted } # Glue (username to article) asserts("contains glued username") { topic["author_name"] }.equals { @post1.user.username } # Non-ORM Date Node Partial context "for date node" do setup { json_output['post']['created_date'] } asserts("contains date partial with day") { topic['day'] }.equals { @post1.created_at.day } asserts("contains date partial with hour") { topic['hour'] }.equals { @post1.created_at.hour } asserts("contains date partial with full") { topic['full'] }.equals { @post1.created_at.iso8601 } end # date node end # show action end rabl-0.11.4/fixtures/sinatra_test/app.rb0000644000004100000410000000230712432721713020227 0ustar www-datawww-datarequire 'rubygems' require 'sinatra' require 'rabl' require 'active_support/core_ext' require 'active_support/inflector' require 'active_record' require 'builder' ActiveRecord::Base.establish_connection( :adapter => 'sqlite3', :database => ':memory:' ) Dir[File.dirname(__FILE__) + "/models/*.rb"].each do |file| require File.expand_path(file) end # Register RABL Rabl.configure do |config| config.perform_caching = true end Rabl.register! class SinatraTest < Sinatra::Application set :root, File.expand_path(File.dirname(__FILE__)) set :views, Proc.new { File.join(root, "views") } get "/posts" do @posts = Post.order("id ASC") render :rabl, :"posts/index", :format => "json" end get "/posts/:id" do @post = Post.find(params[:id]) render :rabl, :"posts/show", :format => "json" end get "/users" do @users = User.order("username ASC") render :rabl, :"users/index.json", :format => "json" end get "/users/:id" do @user = User.find(params[:id]) render :rabl, :"users/show.json", :format => "json" end end # Patch times to return as iso8601 class Time alias_method :old_to_s, :to_s def to_s(format=nil) format ? old_to_s(format) : iso8601 end endrabl-0.11.4/fixtures/sinatra_test/config.ru0000644000004100000410000000012612432721713020734 0ustar www-datawww-datarequire 'rubygems' require 'bundler' Bundler.require require './app' run SinatraTestrabl-0.11.4/fixtures/padrino_test/0000755000004100000410000000000012432721713017113 5ustar www-datawww-datarabl-0.11.4/fixtures/padrino_test/Rakefile0000644000004100000410000000015212432721713020556 0ustar www-datawww-datarequire File.expand_path('../config/boot.rb', __FILE__) require 'padrino-core/cli/rake' PadrinoTasks.init rabl-0.11.4/fixtures/padrino_test/Gemfile0000644000004100000410000000060112432721713020403 0ustar www-datawww-datasource 'https://rubygems.org' # Project requirements gem 'rake' # Component requirements gem 'activerecord', :require => "active_record" gem 'sqlite3' # Test requirements gem 'riot', :group => "test" gem 'rack-test', :require => "rack/test", :group => "test" # Padrino gem 'padrino', '~> 0.10.7' gem 'json' gem 'rabl', :path => File.expand_path(File.dirname(__FILE__) + "/../../") rabl-0.11.4/fixtures/padrino_test/db/0000755000004100000410000000000012432721713017500 5ustar www-datawww-datarabl-0.11.4/fixtures/padrino_test/db/schema.rb0000644000004100000410000000254412432721713021272 0ustar www-datawww-data# encoding: UTF-8 # This file is auto-generated from the current state of the database. Instead # of editing this file, please use the migrations feature of Active Record to # incrementally modify your database, and then regenerate this schema definition. # # Note that this schema.rb definition is the authoritative source for your # database schema. If you need to create the application database on another # system, you should be using db:schema:load, not running all the migrations # from scratch. The latter is a flawed and unsustainable approach (the more migrations # you'll amass, the slower it'll run and the greater likelihood for issues). # # It's strongly recommended to check this file into your version control system. ActiveRecord::Schema.define(:version => 3) do create_table "phone_numbers", :force => true do |t| t.integer "user_id" t.boolean "is_primary" t.string "area_code" t.string "prefix" t.string "suffix" t.string "name" end create_table "posts", :force => true do |t| t.integer "user_id" t.string "title" t.text "body" t.datetime "created_at" t.datetime "updated_at" end create_table "users", :force => true do |t| t.string "username" t.string "email" t.string "location" t.boolean "is_admin" t.datetime "created_at" t.datetime "updated_at" end end rabl-0.11.4/fixtures/padrino_test/public/0000755000004100000410000000000012432721713020371 5ustar www-datawww-datarabl-0.11.4/fixtures/padrino_test/public/favicon.ico0000644000004100000410000000000012432721713022500 0ustar www-datawww-datarabl-0.11.4/fixtures/padrino_test/test/0000755000004100000410000000000012432721713020072 5ustar www-datawww-datarabl-0.11.4/fixtures/padrino_test/test/test_config.rb0000644000004100000410000000104612432721713022724 0ustar www-datawww-data# Load Silence Functionality require File.expand_path(File.dirname(__FILE__) + "/../../../test/silence.rb") silence_warnings do PADRINO_ENV = 'test' unless defined?(PADRINO_ENV) require File.expand_path(File.dirname(__FILE__) + "/../config/boot") silence_stream(STDOUT) { ActiveRecord::Migrator.up('db/migrate') } # Load up test migrations end # Load Riot Test Environment require File.expand_path(File.dirname(__FILE__) + "/../../../test/integration/test_init.rb") class Riot::Situation def app @app || Padrino.application end end rabl-0.11.4/fixtures/padrino_test/test/test.rake0000644000004100000410000000070112432721713021713 0ustar www-datawww-datarequire 'rake/testtask' test_tasks = Dir['test/*/'].map { |d| File.basename(d) } test_tasks.each do |folder| Rake::TestTask.new("test:#{folder}") do |test| test.pattern = "test/#{folder}/**/*_test.rb" test.verbose = true end end desc "Run application test suite" task 'test' => test_tasks.map { |f| "test:#{f}" } Rake::TestTask.new("test:rabl") do |test| test.pattern = "test/app/controllers/**/*_test.rb" test.verbose = true endrabl-0.11.4/fixtures/padrino_test/test/app/0000755000004100000410000000000012432721713020652 5ustar www-datawww-datarabl-0.11.4/fixtures/padrino_test/test/app/controllers/0000755000004100000410000000000012432721713023220 5ustar www-datawww-datarabl-0.11.4/fixtures/padrino_test/test/app/controllers/users_controller_test.rb0000644000004100000410000000634312432721713030216 0ustar www-datawww-data# Lives in /test/integration/users_controller_test.rb # Symlinked to fixture applications begin # Sinatra require File.expand_path(File.dirname(__FILE__) + '/../../test_config.rb') rescue LoadError # Rails require File.expand_path(File.dirname(__FILE__) + '/../test_helper.rb') end context "UsersController" do helper(:json_output) { JSON.parse(last_response.body) } setup do create_users! end context "for index action" do # Tests `collection @users` extending from 'show' template setup do get "/users" end # Attributes (regular) asserts("contains user usernames") do json_output.map { |u| u["user"]["username"] } end.equals { @users.map(&:username) } asserts("contains email") do json_output.map { |u| u["user"]["email"] } end.equals { @users.map(&:email) } asserts("contains location") do json_output.map { |u| u["user"]["location"] } end.equals { @users.map(&:location) } # Attributes (custom name) asserts("contains registered_at") do json_output.map { |u| u["user"]["registered_at"] } end.equals { @users.map(&:created_at).map(&:iso8601) } # Node (renders based on attribute) asserts("contains role") do json_output.map { |u| u["user"]["role"] } end.equals ['normal', 'normal', 'admin'] # Child (custom collection name) asserts("contains formatted phone numbers") do json_output.map { |u| u["user"]["pnumbers"].map { |n| n["pnumber"]["formatted"] } } end.equals { @users.map { |u| u.phone_numbers.map(&:formatted) } } # Node (renders collection partial) asserts("contains formatted node numbers") do json_output.map { |u| u["user"]["node_numbers"].map { |n| n["formatted"] } } end.equals { @users.map { |u| u.phone_numbers.map(&:formatted) } } end # index context "for show action" do # Tests `object :user => :person` custom parent node name setup do get "/users/#{@user1.id}" end # Attributes (regular) asserts("contains username") { json_output["person"]["username"] }.equals { @user1.username } asserts("contains email") { json_output["person"]["email"] }.equals { @user1.email } asserts("contains location") { json_output["person"]["location"] }.equals { @user1.location } # Attributes (custom name) asserts("contains registered_at") { json_output["person"]["registered_at"] }.equals { @user1.created_at.iso8601 } # Node (renders based on attribute) asserts("contains role node") { json_output["person"]["role"] }.equals "normal" # Child (custom collection name) asserts("contains first phone number") { json_output["person"]["pnumbers"][0]["pnumber"]["formatted"] }.equals { @user1.phone_numbers[0].formatted } asserts("contains second phone number") { json_output["person"]["pnumbers"][1]["pnumber"]["formatted"] }.equals { @user1.phone_numbers[1].formatted } # Node (renders collection partial) asserts("contains first node number") { json_output["person"]["node_numbers"][0]["formatted"] }.equals { @user1.phone_numbers[0].formatted } asserts("contains second node number") { json_output["person"]["node_numbers"][1]["formatted"] }.equals { @user1.phone_numbers[1].formatted } end # show endrabl-0.11.4/fixtures/padrino_test/test/app/controllers/posts_controller_test.rb0000644000004100000410000001021312432721713030214 0ustar www-datawww-data# Lives in /test/integration/posts_controller_test.rb # Symlinked to fixture applications begin # Padrino require File.expand_path(File.dirname(__FILE__) + '/../../test_config.rb') rescue LoadError # Rails require File.expand_path(File.dirname(__FILE__) + '/../test_helper.rb') end context "PostsController" do helper(:json_output) { JSON.parse(last_response.body) } setup do create_users! Post.delete_all @post1 = Post.create(:title => "Foo", :body => "Bar", :user_id => @user1.id) @post2 = Post.create(:title => "Baz", :body => "Bah", :user_id => @user2.id) @post3 = Post.create(:title => "Kaz", :body => "Paz", :user_id => @user3.id) @posts = [@post1, @post2, @post3] end context "for index action" do setup do get "/posts", :format => :json end # Attributes (regular) asserts("contains post titles") do json_output['articles'].map { |o| o["article"]["title"] } end.equals { @posts.map(&:title) } asserts("contains post bodies") do json_output['articles'].map { |o| o["article"]["body"] } end.equals { @posts.map(&:body) } # Attributes (custom name) asserts("contains post posted_at") do json_output['articles'].map { |o| o["article"]["posted_at"] } end.equals { @posts.map(&:created_at).map(&:iso8601) } # Child asserts("contains post user child username") do json_output['articles'].map { |o| o["article"]["user"]["username"] } end.equals { @posts.map(&:user).map(&:username) } asserts("contains post user child role") do json_output['articles'].map { |o| o["article"]["user"]["role"] } end.equals { ["normal", "normal", "admin"] } # Child Numbers of the Child User asserts("contains post user child numbers") do json_output['articles'].map { |o| o["article"]["user"]["pnumbers"][0]["pnumber"]["formatted"] } end.equals { @posts.map(&:user).map(&:phone_numbers).map(&:first).map(&:formatted) } # Glue (username to article) asserts("contains glued usernames") do json_output['articles'].map { |o| o["article"]["author_name"] } end.equals { @posts.map(&:user).map(&:username) } # Conditional Child (admin) asserts("contains admin child only for admins") do json_output['articles'].map { |o| o["article"]["admin"]["username"] if o["article"].has_key?("admin") }.compact end.equals { [@user3.username] } # Conditional Node (created_by_admin) asserts("contains created_by_admin node for admins") do json_output['articles'].last['article']['created_by_admin'] end.equals { true } denies("contains no created_by_admin node for non-admins") do json_output['articles'].first['article'] end.includes(:created_by_admin) end # index action context "for show action" do setup do get "/posts/#{@post1.id}", :format => :json json_output['post'] end # Attributes (regular) asserts("contains post title") { topic['title'] }.equals { @post1.title } asserts("contains post body") { topic['body'] }.equals { @post1.body } # Attributes (custom name) asserts("contains post posted_at") { topic['posted_at'] }.equals { @post1.created_at.iso8601 } # Child asserts("contains post user child username") { topic["user"]["username"] }.equals { @post1.user.username } asserts("contains post user child role") { topic["user"]["role"] }.equals { "normal" } # Child Numbers of the Child User asserts("contains post user child numbers") do topic["user"]["pnumbers"][0]["pnumber"]["formatted"] end.equals { @post1.user.phone_numbers[0].formatted } # Glue (username to article) asserts("contains glued username") { topic["author_name"] }.equals { @post1.user.username } # Non-ORM Date Node Partial context "for date node" do setup { json_output['post']['created_date'] } asserts("contains date partial with day") { topic['day'] }.equals { @post1.created_at.day } asserts("contains date partial with hour") { topic['hour'] }.equals { @post1.created_at.hour } asserts("contains date partial with full") { topic['full'] }.equals { @post1.created_at.iso8601 } end # date node end # show action end rabl-0.11.4/fixtures/padrino_test/.components0000644000004100000410000000014012432721713021274 0ustar www-datawww-data--- :orm: activerecord :test: riot :mock: none :script: none :renderer: haml :stylesheet: none rabl-0.11.4/fixtures/padrino_test/.gitignore0000644000004100000410000000012112432721713021075 0ustar www-datawww-data.DS_Store log/**/* tmp/**/* bin/* vendor/gems/* !vendor/gems/cache/ .sass-cache/*rabl-0.11.4/fixtures/padrino_test/config/0000755000004100000410000000000012432721713020360 5ustar www-datawww-datarabl-0.11.4/fixtures/padrino_test/config/apps.rb0000644000004100000410000000250112432721713021646 0ustar www-datawww-data## # This file mounts each app in the Padrino project to a specified sub-uri. # You can mount additional applications using any of these commands below: # # Padrino.mount("blog").to('/blog') # Padrino.mount("blog", :app_class => "BlogApp").to('/blog') # Padrino.mount("blog", :app_file => "path/to/blog/app.rb").to('/blog') # # You can also map apps to a specified host: # # Padrino.mount("Admin").host("admin.example.org") # Padrino.mount("WebSite").host(/.*\.?example.org/) # Padrino.mount("Foo").to("/foo").host("bar.example.org") # # Note 1: Mounted apps (by default) should be placed into the project root at '/app_name'. # Note 2: If you use the host matching remember to respect the order of the rules. # # By default, this file mounts the primary app which was generated with this project. # However, the mounted app can be modified as needed: # # Padrino.mount("AppName", :app_file => "path/to/file", :app_class => "BlogApp").to('/') # ## # Setup global project settings for your apps. These settings are inherited by every subapp. You can # override these settings in the subapps as needed. # Padrino.configure_apps do # enable :sessions set :session_secret, '1559bdc5e1f33a0d1c9a597580a189080b39ab7d06eed1a7db12e90f9d269e89' end # Mounts the core application for this project Padrino.mount("PadrinoTest").to('/') rabl-0.11.4/fixtures/padrino_test/config/boot.rb0000644000004100000410000000117412432721713021653 0ustar www-datawww-data# Defines our constants PADRINO_ENV = ENV["PADRINO_ENV"] ||= ENV["RACK_ENV"] ||= "development" unless defined?(PADRINO_ENV) PADRINO_ROOT = File.expand_path('../..', __FILE__) unless defined?(PADRINO_ROOT) # Load our dependencies require 'rubygems' unless defined?(Gem) require 'bundler/setup' Bundler.require(:default, PADRINO_ENV) ## # Enable devel logging # # Padrino::Logger::Config[:development] = { :log_level => :devel, :stream => :stdout } # Padrino::Logger.log_static = true # ## # Add your before load hooks here # Padrino.before_load do end ## # Add your after load hooks here # Padrino.after_load do end Padrino.load! rabl-0.11.4/fixtures/padrino_test/config/database.rb0000644000004100000410000000242212432721713022451 0ustar www-datawww-data## # You can use other adapters like: # # ActiveRecord::Base.configurations[:development] = { # :adapter => 'mysql', # :encoding => 'utf8', # :reconnect => true, # :database => 'your_database', # :pool => 5, # :username => 'root', # :password => '', # :host => 'localhost', # :socket => '/tmp/mysql.sock' # } # ActiveRecord::Base.configurations[:development] = { :adapter => 'sqlite3', :database => ":memory:" } ActiveRecord::Base.configurations[:test] = { :adapter => 'sqlite3', :database => ":memory:" } # Setup our logger ActiveRecord::Base.logger = logger # Include Active Record class name as root for JSON serialized output. ActiveRecord::Base.include_root_in_json = true # Store the full class name (including module namespace) in STI type column. ActiveRecord::Base.store_full_sti_class = true # Use ISO 8601 format for JSON serialized times and dates. ActiveSupport.use_standard_json_time_format = true # Don't escape HTML entities in JSON, leave that for the #json_escape helper. # if you're including raw json in an HTML page. ActiveSupport.escape_html_entities_in_json = false # Now we can estabilish connection with our db ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations[Padrino.env]) rabl-0.11.4/fixtures/padrino_test/app/0000755000004100000410000000000012432721713017673 5ustar www-datawww-datarabl-0.11.4/fixtures/padrino_test/app/controllers/0000755000004100000410000000000012432721713022241 5ustar www-datawww-datarabl-0.11.4/fixtures/padrino_test/app/controllers/posts.rb0000644000004100000410000000035012432721713023734 0ustar www-datawww-dataPadrinoTest.controllers :posts do get :index do @posts = Post.order("id ASC") render "posts/index" end get :show, :map => "/posts", :with => :id do @post = Post.find(params[:id]) render "posts/show" end end rabl-0.11.4/fixtures/padrino_test/app/controllers/users.rb0000644000004100000410000000035612432721713023733 0ustar www-datawww-dataPadrinoTest.controllers :users do get :index do @users = User.order("username ASC") render "users/index" end get :show, :map => "/users", :with => :id do @user = User.find(params[:id]) render "users/show" end end rabl-0.11.4/fixtures/padrino_test/app/app.rb0000644000004100000410000000261612432721713021005 0ustar www-datawww-dataclass PadrinoTest < Padrino::Application register Padrino::Rendering register Padrino::Mailer register Padrino::Helpers enable :sessions ## # Application configuration options # # set :raise_errors, true # Raise exceptions (will stop application) (default for test) # set :dump_errors, true # Exception backtraces are written to STDERR (default for production/development) # set :show_exceptions, true # Shows a stack trace in browser (default for development) # set :logging, true # Logging in STDOUT for development and file for production (default only for development) # set :public, "foo/bar" # Location for static assets (default root/public) # set :reload, false # Reload application files (default in development) # set :default_builder, "foo" # Set a custom form builder (default 'StandardFormBuilder') # set :locale_path, "bar" # Set path for I18n translations (default your_app/locales) # disable :sessions # Disabled sessions by default (enable if needed) # disable :flash # Disables rack-flash (enabled by default if Rack::Flash is defined) # layout :my_layout # Layout can be in views/layouts/foo.ext or views/foo.ext (default :application) # end # Patch times to return as iso8601 class Time alias_method :old_to_s, :to_s def to_s(format=nil) format ? old_to_s(format) : iso8601 end endrabl-0.11.4/fixtures/padrino_test/app/helpers/0000755000004100000410000000000012432721713021335 5ustar www-datawww-datarabl-0.11.4/fixtures/padrino_test/app/helpers/posts_helper.rb0000644000004100000410000000024512432721713024372 0ustar www-datawww-data# Helper methods defined here can be accessed in any controller or view in the application PadrinoTest.helpers do # def simple_helper_method # ... # end end rabl-0.11.4/fixtures/padrino_test/app/helpers/users_helper.rb0000644000004100000410000000024512432721713024363 0ustar www-datawww-data# Helper methods defined here can be accessed in any controller or view in the application PadrinoTest.helpers do # def simple_helper_method # ... # end end rabl-0.11.4/fixtures/padrino_test/config.ru0000644000004100000410000000031612432721713020730 0ustar www-datawww-data#!/usr/bin/env rackup # encoding: utf-8 # This file can be used to start Padrino, # just execute it from the command line. require File.expand_path("../config/boot.rb", __FILE__) run Padrino.application rabl-0.11.4/fixtures/rails2/0000755000004100000410000000000012432721713015614 5ustar www-datawww-datarabl-0.11.4/fixtures/rails2/Rakefile0000644000004100000410000000062012432721713017257 0ustar www-datawww-data# Add your own tasks in files placed in lib/tasks ending in .rake, # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. require(File.join(File.dirname(__FILE__), 'config', 'boot')) require 'rake' require 'rake/testtask' require 'tasks/rails' Rake::TestTask.new("test:rabl") do |test| test.pattern = "test/functionals/**/*_test.rb" test.verbose = true endrabl-0.11.4/fixtures/rails2/Gemfile0000644000004100000410000000044412432721713017111 0ustar www-datawww-datasource 'https://rubygems.org' gem "rails", "~> 2.3.18" gem "sqlite3", :require => "sqlite3" gem 'json' gem 'rabl', :path => File.expand_path(File.dirname(__FILE__) + "/../../") gem 'rake', "~> 0.9.2.2" gem 'riot', :group => "test" gem 'rack-test', :require => "rack/test", :group => "test" rabl-0.11.4/fixtures/rails2/script/0000755000004100000410000000000012432721713017120 5ustar www-datawww-datarabl-0.11.4/fixtures/rails2/script/plugin0000755000004100000410000000014712432721713020346 0ustar www-datawww-data#!/usr/bin/env ruby require File.expand_path('../../config/boot', __FILE__) require 'commands/plugin' rabl-0.11.4/fixtures/rails2/script/runner0000755000004100000410000000014712432721713020361 0ustar www-datawww-data#!/usr/bin/env ruby require File.expand_path('../../config/boot', __FILE__) require 'commands/runner' rabl-0.11.4/fixtures/rails2/script/dbconsole0000755000004100000410000000015212432721713021014 0ustar www-datawww-data#!/usr/bin/env ruby require File.expand_path('../../config/boot', __FILE__) require 'commands/dbconsole' rabl-0.11.4/fixtures/rails2/script/server0000755000004100000410000000014712432721713020356 0ustar www-datawww-data#!/usr/bin/env ruby require File.expand_path('../../config/boot', __FILE__) require 'commands/server' rabl-0.11.4/fixtures/rails2/script/performance/0000755000004100000410000000000012432721713021421 5ustar www-datawww-datarabl-0.11.4/fixtures/rails2/script/performance/profiler0000755000004100000410000000017012432721713023167 0ustar www-datawww-data#!/usr/bin/env ruby require File.expand_path('../../../config/boot', __FILE__) require 'commands/performance/profiler' rabl-0.11.4/fixtures/rails2/script/performance/benchmarker0000755000004100000410000000017312432721713023631 0ustar www-datawww-data#!/usr/bin/env ruby require File.expand_path('../../../config/boot', __FILE__) require 'commands/performance/benchmarker' rabl-0.11.4/fixtures/rails2/script/destroy0000755000004100000410000000015012432721713020533 0ustar www-datawww-data#!/usr/bin/env ruby require File.expand_path('../../config/boot', __FILE__) require 'commands/destroy' rabl-0.11.4/fixtures/rails2/script/console0000755000004100000410000000015012432721713020504 0ustar www-datawww-data#!/usr/bin/env ruby require File.expand_path('../../config/boot', __FILE__) require 'commands/console' rabl-0.11.4/fixtures/rails2/script/about0000755000004100000410000000023712432721713020162 0ustar www-datawww-data#!/usr/bin/env ruby require File.expand_path('../../config/boot', __FILE__) $LOAD_PATH.unshift "#{RAILTIES_PATH}/builtin/rails_info" require 'commands/about' rabl-0.11.4/fixtures/rails2/script/generate0000755000004100000410000000015112432721713020635 0ustar www-datawww-data#!/usr/bin/env ruby require File.expand_path('../../config/boot', __FILE__) require 'commands/generate' rabl-0.11.4/fixtures/rails2/db/0000755000004100000410000000000012432721713016201 5ustar www-datawww-datarabl-0.11.4/fixtures/rails2/db/schema.rb0000644000004100000410000000253612432721713017774 0ustar www-datawww-data# This file is auto-generated from the current state of the database. Instead of editing this file, # please use the migrations feature of Active Record to incrementally modify your database, and # then regenerate this schema definition. # # Note that this schema.rb definition is the authoritative source for your database schema. If you need # to create the application database on another system, you should be using db:schema:load, not running # all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations # you'll amass, the slower it'll run and the greater likelihood for issues). # # It's strongly recommended to check this file into your version control system. ActiveRecord::Schema.define(:version => 20111002092024) do create_table "phone_numbers", :force => true do |t| t.integer "user_id" t.boolean "is_primary" t.string "area_code" t.string "prefix" t.string "suffix" t.string "name" end create_table "posts", :force => true do |t| t.integer "user_id" t.string "title" t.text "body" t.datetime "created_at" t.datetime "updated_at" end create_table "users", :force => true do |t| t.string "username" t.string "email" t.string "location" t.boolean "is_admin" t.datetime "created_at" t.datetime "updated_at" end end rabl-0.11.4/fixtures/rails2/db/seeds.rb0000644000004100000410000000054412432721713017634 0ustar www-datawww-data# This file should contain all the record creation needed to seed the database with its default values. # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). # # Examples: # # cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }]) # Major.create(:name => 'Daley', :city => cities.first) rabl-0.11.4/fixtures/rails2/public/0000755000004100000410000000000012432721713017072 5ustar www-datawww-datarabl-0.11.4/fixtures/rails2/public/images/0000755000004100000410000000000012432721713020337 5ustar www-datawww-datarabl-0.11.4/fixtures/rails2/public/images/rails.png0000644000004100000410000001476612432721713022175 0ustar www-datawww-dataPNG  IHDR2@X${tEXtSoftwareAdobe ImageReadyqe<IDATxڬ[ \eR֮^;Iwga@`gGgDgtqDFqFDqF@NRU]˫|_-Qy^Ǹ.݋0W_6kbf̻ܸ6<4 w5~*r?9m&"M7@vm' {_S)Vi\WG?իjMd@ lDLX鸺W-TU+@EPo\&*Rnn, fDWrX|3M=\EJB[d6A'=tx^$a86̈{, ϱPepN*_W_3o;ޥ(0E:i6eXnhGf"L|S+(+.gФg=Ych=m#V_#}Ǫ|tR D8VՄM~xg!ni%Dy( B,{(Np$3iر$h.@e[a'eJԂyϠ4>H*MHQ(Jgt-֢QI ^d„@s-'- 51{'0 |n4ۉh{V@ܩw"BT =rzqPpBHȃ?ň ]-qpgsPiSӪg`jn)m 御B2L.x!jJP! K/\ ʮRB[09Trӈu. uH$ DDQ+:ݘٻ 3/nލ%Sjm2!&D/[EHwW A-RR!PeuHim"t6lFgЫ-O.1?ƞksX~VtmZJR11Nu&<⽩,Tb,`w WPx-G5 `մ/5pbAtIVJ_]0/DiH=ô#*77-3 VuQ0.pݔ%yw hљW0),2$b6&I/@bj$I(fx' JnO"`<-/LѮ%^ȫͶn2wҗ2}}XսL'Q-,m/ꤋ4#0Q&00NKrsA,Aײ)aIEC(ERK{8Ȭ[y?iI5$%f{}u F 1~;v1l'@F 'IF'm!K7"&]w 15#4Vižn[v 8Ě)>C=LBo~/3% wF4֓ʿ8>bWX@bb@IzP9IvFfQL!2cEP(se4~5RhAŽ90_? cMEteVOaOr B]pȱؓ"Eyx: NJ)bl׋hYuTdԫw=آMgwVPOFΒ25-TD[Z2>]V,xӛIOƅ)Jͺ[)?cn28p#(mk+./phʮQ6?w7HIoSj)1<#-N9O1ͰސkIKr:(ŗ;rR&<93v@w(w:~:TFSޒ" ՊTdT9PIb3JzTQׄBP23ƵW*|@^)Qw?Iq =,<@ B8);50H-=T SA@@f5r[T%#c|Z&w(B)tDQ%vyC(,Ɵ|ʰi&<#u:3EHkzд)ndF>1V2kFGYL KMQlR&TB,igv8]C8Sf#ą4Q'?,= aV9WEXYrr*!cƯ~),=yџ]jlGeE̺5r_2Ԏ}d"a]0M9PZG17nE"Rr\YQ)!|5U(d=^ŗo8+2NU6jB[B5V.]ŲW/^䩬 ;Y"Vi$2ٲ_c(F^Egq{CP/ #K8Y+Q M1>ܞAߏ,gytޕn,zE$V.v.PyLapG9Tn:uiRZ! zI0?Џ1u#$6ɱGMhFdtd|~d\O9Ij**zD؍b)PBҽh-q ql%/{Gz*d7=QS]:RQbUMPᒯ$% du] XefQz$('ИZH#ARXDB ~`0.F|XXK)wFolzyhߚKz>.&n EjU,2' &iw[d[ V)*Qavl QDit[VIQhR@$)y~m|>?cJ+VH'6? 7 i.XH8Fި)dAYUBjE".4w-?l2Y.RjWD@Bج.߆s[H-gASF3Fj]آBP떬_>M%bt ?_rլ -h]r_ž[nȶQ+Gԭ_\Ê Z٦fet(|U('.g VFEN9}Ll4T&nto¨Ӓ X F "_fYzF~y& Gu]$O[v#].@$VA`ⱧTѰZ[2u+/mUC_ TnyѠ |l\ M"G[R$d|:ěFIire"ٵt,+ی1Z11udt*K2 sd; [)xW.z2jTh#DV\NO &e_vU2B^%0FH(/ԘI2>=L]dv UUpk"ijB$,O-0y<}~*T5LErE4B߳XXN:<9>Ed -V*uBLsN**JxRU辖,T( Gu @ůY{u|CJF(OLbnմiKhpFtx8#9FsFڋDTAn1veF^M ^kf.ĆݠVʓǰ3JaY@n&jLl:McӚ…vu?9w!/~#hM ڛ ̴nMA}m W,)(î.N y%$*={P9c DzH>Blu޾K78x->V,'JU \L]l>W*r-hXf~oI Z3f玱>vN3 uZTgg}Վ363:.g /-H+"PKۉSZ4Z_GlXMc7";ҿ (5fMUCOF6 CNft>$S1VaR&4) ٗay]%W A*|gX{Qc>iTX1F M`|![$P4ʊ$#,dɌ(?KTJR۸S%C7jHb浃j+N$,[.@˹_ ?.3ĵH"U$Z^ X02!Kc 8q.NMI6N&3n8exoWfPIJB<pREAdo$*m)e9D 5X[T$LΠ:]C$n#mC[P~Yt*d?\q^WXs!E-2#_mw8;2!vw:DUn$)GiGn3_o EZE3k-EHv.OûzE>"֛}l\/-nرQHԽab*#K׋eIƳd#G et\ ,:MێÜIC}m ٽO?eb%ːٰStB|Aznaz*FlQ/K uu*1wDvE֯SJTK;(4kƣ;v2P9`k{?~_[hʢ^9фǡ;m|]o9<#jz\wD,8V]]%K9er懇0n^FcI>`Ub+kօO1|NO]t+,Ȑl_ˮ6 ĒDbrz^pe7^[aþo確jN+xsNC߅wμ7|za2, omrbZ~,pN>;?Y,z[u◿jq 4aqڶNu6Zid@h!!F9#,#UrOa0=Då ,,,bE#ȮX3ªޏ=a< =&_~ ٵѽacj񫒆LsXuXB (wzEk_QIف*4'ѣSl{.,p۵2`jp^؇nZXPź^]wމ]aQ-oI5O3a] _wb ŭL]$"|sԩȬ= VсLIUbYY搮͢I$tf$2|r;~'GSXkᇦԭF4b4 xo[,04F~<}ۭR%myb׾\mlO.4}tE\7}M)tՉ13xF [-26t䢄&E"9;ٜrq e)K!:bwY }g;Jר)5D$!Kɤ9߫-K$$ hlDUFF J{s2R6rC&&0;@>]/Z3E,k;( 2^09 The change you wanted was rejected (422)

The change you wanted was rejected.

Maybe you tried to change something you didn't have access to.

rabl-0.11.4/fixtures/rails2/public/favicon.ico0000644000004100000410000000000012432721713021201 0ustar www-datawww-datarabl-0.11.4/fixtures/rails2/public/robots.txt0000644000004100000410000000031412432721713021141 0ustar www-datawww-data# See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file # # To ban all spiders from the entire site uncomment the next two lines: # User-Agent: * # Disallow: / rabl-0.11.4/fixtures/rails2/public/404.html0000644000004100000410000000166312432721713020275 0ustar www-datawww-data The page you were looking for doesn't exist (404)

The page you were looking for doesn't exist.

You may have mistyped the address or the page may have moved.

rabl-0.11.4/fixtures/rails2/public/500.html0000644000004100000410000000166412432721713020273 0ustar www-datawww-data We're sorry, but something went wrong (500)

We're sorry, but something went wrong.

We've been notified about this issue and we'll take a look at it shortly.

rabl-0.11.4/fixtures/rails2/public/index.html0000644000004100000410000001645212432721713021077 0ustar www-datawww-data Ruby on Rails: Welcome aboard

Getting started

Here’s how to get rolling:

  1. Use script/generate to create your models and controllers

    To see all available options, run it without parameters.

  2. Set up a default route and remove or rename this file

    Routes are set up in config/routes.rb.

  3. Create your database

    Run rake db:migrate to create your database. If you're not using SQLite (the default), edit config/database.yml with your username and password.

rabl-0.11.4/fixtures/rails2/test/0000755000004100000410000000000012432721713016573 5ustar www-datawww-datarabl-0.11.4/fixtures/rails2/test/functionals/0000755000004100000410000000000012432721713021120 5ustar www-datawww-datarabl-0.11.4/fixtures/rails2/test/functionals/users_controller_test.rb0000644000004100000410000000634312432721713026116 0ustar www-datawww-data# Lives in /test/integration/users_controller_test.rb # Symlinked to fixture applications begin # Sinatra require File.expand_path(File.dirname(__FILE__) + '/../../test_config.rb') rescue LoadError # Rails require File.expand_path(File.dirname(__FILE__) + '/../test_helper.rb') end context "UsersController" do helper(:json_output) { JSON.parse(last_response.body) } setup do create_users! end context "for index action" do # Tests `collection @users` extending from 'show' template setup do get "/users" end # Attributes (regular) asserts("contains user usernames") do json_output.map { |u| u["user"]["username"] } end.equals { @users.map(&:username) } asserts("contains email") do json_output.map { |u| u["user"]["email"] } end.equals { @users.map(&:email) } asserts("contains location") do json_output.map { |u| u["user"]["location"] } end.equals { @users.map(&:location) } # Attributes (custom name) asserts("contains registered_at") do json_output.map { |u| u["user"]["registered_at"] } end.equals { @users.map(&:created_at).map(&:iso8601) } # Node (renders based on attribute) asserts("contains role") do json_output.map { |u| u["user"]["role"] } end.equals ['normal', 'normal', 'admin'] # Child (custom collection name) asserts("contains formatted phone numbers") do json_output.map { |u| u["user"]["pnumbers"].map { |n| n["pnumber"]["formatted"] } } end.equals { @users.map { |u| u.phone_numbers.map(&:formatted) } } # Node (renders collection partial) asserts("contains formatted node numbers") do json_output.map { |u| u["user"]["node_numbers"].map { |n| n["formatted"] } } end.equals { @users.map { |u| u.phone_numbers.map(&:formatted) } } end # index context "for show action" do # Tests `object :user => :person` custom parent node name setup do get "/users/#{@user1.id}" end # Attributes (regular) asserts("contains username") { json_output["person"]["username"] }.equals { @user1.username } asserts("contains email") { json_output["person"]["email"] }.equals { @user1.email } asserts("contains location") { json_output["person"]["location"] }.equals { @user1.location } # Attributes (custom name) asserts("contains registered_at") { json_output["person"]["registered_at"] }.equals { @user1.created_at.iso8601 } # Node (renders based on attribute) asserts("contains role node") { json_output["person"]["role"] }.equals "normal" # Child (custom collection name) asserts("contains first phone number") { json_output["person"]["pnumbers"][0]["pnumber"]["formatted"] }.equals { @user1.phone_numbers[0].formatted } asserts("contains second phone number") { json_output["person"]["pnumbers"][1]["pnumber"]["formatted"] }.equals { @user1.phone_numbers[1].formatted } # Node (renders collection partial) asserts("contains first node number") { json_output["person"]["node_numbers"][0]["formatted"] }.equals { @user1.phone_numbers[0].formatted } asserts("contains second node number") { json_output["person"]["node_numbers"][1]["formatted"] }.equals { @user1.phone_numbers[1].formatted } end # show endrabl-0.11.4/fixtures/rails2/test/functionals/posts_controller_test.rb0000644000004100000410000001021312432721713026114 0ustar www-datawww-data# Lives in /test/integration/posts_controller_test.rb # Symlinked to fixture applications begin # Padrino require File.expand_path(File.dirname(__FILE__) + '/../../test_config.rb') rescue LoadError # Rails require File.expand_path(File.dirname(__FILE__) + '/../test_helper.rb') end context "PostsController" do helper(:json_output) { JSON.parse(last_response.body) } setup do create_users! Post.delete_all @post1 = Post.create(:title => "Foo", :body => "Bar", :user_id => @user1.id) @post2 = Post.create(:title => "Baz", :body => "Bah", :user_id => @user2.id) @post3 = Post.create(:title => "Kaz", :body => "Paz", :user_id => @user3.id) @posts = [@post1, @post2, @post3] end context "for index action" do setup do get "/posts", :format => :json end # Attributes (regular) asserts("contains post titles") do json_output['articles'].map { |o| o["article"]["title"] } end.equals { @posts.map(&:title) } asserts("contains post bodies") do json_output['articles'].map { |o| o["article"]["body"] } end.equals { @posts.map(&:body) } # Attributes (custom name) asserts("contains post posted_at") do json_output['articles'].map { |o| o["article"]["posted_at"] } end.equals { @posts.map(&:created_at).map(&:iso8601) } # Child asserts("contains post user child username") do json_output['articles'].map { |o| o["article"]["user"]["username"] } end.equals { @posts.map(&:user).map(&:username) } asserts("contains post user child role") do json_output['articles'].map { |o| o["article"]["user"]["role"] } end.equals { ["normal", "normal", "admin"] } # Child Numbers of the Child User asserts("contains post user child numbers") do json_output['articles'].map { |o| o["article"]["user"]["pnumbers"][0]["pnumber"]["formatted"] } end.equals { @posts.map(&:user).map(&:phone_numbers).map(&:first).map(&:formatted) } # Glue (username to article) asserts("contains glued usernames") do json_output['articles'].map { |o| o["article"]["author_name"] } end.equals { @posts.map(&:user).map(&:username) } # Conditional Child (admin) asserts("contains admin child only for admins") do json_output['articles'].map { |o| o["article"]["admin"]["username"] if o["article"].has_key?("admin") }.compact end.equals { [@user3.username] } # Conditional Node (created_by_admin) asserts("contains created_by_admin node for admins") do json_output['articles'].last['article']['created_by_admin'] end.equals { true } denies("contains no created_by_admin node for non-admins") do json_output['articles'].first['article'] end.includes(:created_by_admin) end # index action context "for show action" do setup do get "/posts/#{@post1.id}", :format => :json json_output['post'] end # Attributes (regular) asserts("contains post title") { topic['title'] }.equals { @post1.title } asserts("contains post body") { topic['body'] }.equals { @post1.body } # Attributes (custom name) asserts("contains post posted_at") { topic['posted_at'] }.equals { @post1.created_at.iso8601 } # Child asserts("contains post user child username") { topic["user"]["username"] }.equals { @post1.user.username } asserts("contains post user child role") { topic["user"]["role"] }.equals { "normal" } # Child Numbers of the Child User asserts("contains post user child numbers") do topic["user"]["pnumbers"][0]["pnumber"]["formatted"] end.equals { @post1.user.phone_numbers[0].formatted } # Glue (username to article) asserts("contains glued username") { topic["author_name"] }.equals { @post1.user.username } # Non-ORM Date Node Partial context "for date node" do setup { json_output['post']['created_date'] } asserts("contains date partial with day") { topic['day'] }.equals { @post1.created_at.day } asserts("contains date partial with hour") { topic['hour'] }.equals { @post1.created_at.hour } asserts("contains date partial with full") { topic['full'] }.equals { @post1.created_at.iso8601 } end # date node end # show action end rabl-0.11.4/fixtures/rails2/test/test_helper.rb0000644000004100000410000000162212432721713021437 0ustar www-datawww-data# Load Silence Functionality require File.expand_path(File.dirname(__FILE__) + "/../../../test/silence.rb") # Load Environment silence_warnings do ENV["RAILS_ENV"] = "test" require File.expand_path(File.dirname(__FILE__) + "/../config/environment") require 'test_help' end # Load Riot Test Environment require File.expand_path(File.dirname(__FILE__) + "/../../../test/integration/test_init.rb") # Run Migrations silence_stream(STDOUT) do dbconf = YAML::load(File.open('config/database.yml'))[Rails.env] ActiveRecord::Base.establish_connection(dbconf) ActiveRecord::Base.logger = Logger.new(File.open('log/database.log', 'a')) silence_stream(STDOUT) { ActiveRecord::Migrator.up('db/migrate') } end class Riot::Situation def app ActionController::Dispatcher.new end end class ActiveSupport::TestCase self.use_transactional_fixtures = true self.use_instantiated_fixtures = false end rabl-0.11.4/fixtures/rails2/.gitignore0000644000004100000410000000000512432721713017577 0ustar www-datawww-datalog/*rabl-0.11.4/fixtures/rails2/config/0000755000004100000410000000000012432721713017061 5ustar www-datawww-datarabl-0.11.4/fixtures/rails2/config/initializers/0000755000004100000410000000000012432721713021567 5ustar www-datawww-datarabl-0.11.4/fixtures/rails2/config/initializers/session_store.rb0000644000004100000410000000143712432721713025020 0ustar www-datawww-data# Be sure to restart your server when you modify this file. # Your secret key for verifying cookie session data integrity. # If you change this key, all old sessions will become invalid! # Make sure the secret is at least 30 characters and all random, # no regular words or you'll be exposed to dictionary attacks. ActionController::Base.session = { :key => '_rails2_session', :secret => 'b2d31ab1f626a19684aee969cb099d7ab2824150dae712c1c69aaf421bbce2ceb9c2ae85ea9f213440e6baa8e6029f75cebe80fa3af2de8309f885e5f646e8a8' } # Use the database for sessions instead of the cookie-based default, # which shouldn't be used to store highly confidential information # (create the session table with "rake db:sessions:create") # ActionController::Base.session_store = :active_record_store rabl-0.11.4/fixtures/rails2/config/initializers/new_rails_defaults.rb0000644000004100000410000000150112432721713025763 0ustar www-datawww-data# Be sure to restart your server when you modify this file. # These settings change the behavior of Rails 2 apps and will be defaults # for Rails 3. You can remove this initializer when Rails 3 is released. if defined?(ActiveRecord) # Include Active Record class name as root for JSON serialized output. ActiveRecord::Base.include_root_in_json = true # Store the full class name (including module namespace) in STI type column. ActiveRecord::Base.store_full_sti_class = true end ActionController::Routing.generate_best_match = false # Use ISO 8601 format for JSON serialized times and dates. ActiveSupport.use_standard_json_time_format = true # Don't escape HTML entities in JSON, leave that for the #json_escape helper. # if you're including raw json in an HTML page. ActiveSupport.escape_html_entities_in_json = falserabl-0.11.4/fixtures/rails2/config/initializers/mime_types.rb0000644000004100000410000000031512432721713024266 0ustar www-datawww-data# Be sure to restart your server when you modify this file. # Add new mime types for use in respond_to blocks: # Mime::Type.register "text/richtext", :rtf # Mime::Type.register_alias "text/html", :iphone rabl-0.11.4/fixtures/rails2/config/initializers/cookie_verification_secret.rb0000644000004100000410000000077112432721713027501 0ustar www-datawww-data# Be sure to restart your server when you modify this file. # Your secret key for verifying the integrity of signed cookies. # If you change this key, all old signed cookies will become invalid! # Make sure the secret is at least 30 characters and all random, # no regular words or you'll be exposed to dictionary attacks. ActionController::Base.cookie_verifier_secret = '07d74a7edfe4b5e0cf80f002948a3907a515a0dc6c8fdb2411dc73de8547012acde659641dba5cc31b5a40a09c4fd1298c2ea0080eda689181ed786502e70e00'; rabl-0.11.4/fixtures/rails2/config/initializers/backtrace_silencers.rb0000644000004100000410000000062412432721713026104 0ustar www-datawww-data# Be sure to restart your server when you modify this file. # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } # You can also remove all the silencers if you're trying do debug a problem that might steem from framework code. # Rails.backtrace_cleaner.remove_silencers!rabl-0.11.4/fixtures/rails2/config/initializers/inflections.rb0000644000004100000410000000057112432721713024434 0ustar www-datawww-data# Be sure to restart your server when you modify this file. # Add new inflection rules using the following format # (all these examples are active by default): # ActiveSupport::Inflector.inflections do |inflect| # inflect.plural /^(ox)$/i, '\1en' # inflect.singular /^(ox)en/i, '\1' # inflect.irregular 'person', 'people' # inflect.uncountable %w( fish sheep ) # end rabl-0.11.4/fixtures/rails2/config/boot.rb0000644000004100000410000000616112432721713020355 0ustar www-datawww-data# Don't change this file! # Configure your app in config/environment.rb and config/environments/*.rb RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT) module Rails class << self def boot! unless booted? preinitialize pick_boot.run end end def booted? defined? Rails::Initializer end def pick_boot (vendor_rails? ? VendorBoot : GemBoot).new end def vendor_rails? File.exist?("#{RAILS_ROOT}/vendor/rails") end def preinitialize load(preinitializer_path) if File.exist?(preinitializer_path) end def preinitializer_path "#{RAILS_ROOT}/config/preinitializer.rb" end end class Boot def run load_initializer Rails::Initializer.run(:set_load_path) end end class VendorBoot < Boot def load_initializer require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer" Rails::Initializer.run(:install_gem_spec_stubs) Rails::GemDependency.add_frozen_gem_path end end class GemBoot < Boot def load_initializer self.class.load_rubygems load_rails_gem require 'initializer' end def load_rails_gem if version = self.class.gem_version gem 'rails', version else gem 'rails' end rescue Gem::LoadError => load_error if load_error.message =~ /Could not find RubyGem rails/ STDERR.puts %(Missing the Rails #{version} gem. Please `gem install -v=#{version} rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.) exit 1 else raise end end class << self def rubygems_version Gem::RubyGemsVersion rescue nil end def gem_version if defined? RAILS_GEM_VERSION RAILS_GEM_VERSION elsif ENV.include?('RAILS_GEM_VERSION') ENV['RAILS_GEM_VERSION'] else parse_gem_version(read_environment_rb) end end def load_rubygems min_version = '1.3.2' require 'rubygems' unless rubygems_version >= min_version $stderr.puts %Q(Rails requires RubyGems >= #{min_version} (you have #{rubygems_version}). Please `gem update --system` and try again.) exit 1 end rescue LoadError $stderr.puts %Q(Rails requires RubyGems >= #{min_version}. Please install RubyGems and try again: http://rubygems.rubyforge.org) exit 1 end def parse_gem_version(text) $1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/ end private def read_environment_rb File.read("#{RAILS_ROOT}/config/environment.rb") end end end end # Bundler: http://gembundler.com/rails23.html class Rails::Boot def run load_initializer Rails::Initializer.class_eval do def load_gems @bundler_loaded ||= Bundler.require :default, Rails.env end end Rails::Initializer.run(:set_load_path) end end # All that for this: Rails.boot! rabl-0.11.4/fixtures/rails2/config/environments/0000755000004100000410000000000012432721713021610 5ustar www-datawww-datarabl-0.11.4/fixtures/rails2/config/environments/test.rb0000644000004100000410000000243712432721713023122 0ustar www-datawww-data# Settings specified here will take precedence over those in config/environment.rb # The test environment is used exclusively to run your application's # test suite. You never need to work with it otherwise. Remember that # your test database is "scratch space" for the test suite and is wiped # and recreated between test runs. Don't rely on the data there! config.cache_classes = true # Log error messages when you accidentally call methods on nil. config.whiny_nils = true # Show full error reports and disable caching config.action_controller.consider_all_requests_local = true config.action_controller.perform_caching = false config.action_view.cache_template_loading = true # Disable request forgery protection in test environment config.action_controller.allow_forgery_protection = false # Tell Action Mailer not to deliver emails to the real world. # The :test delivery method accumulates sent emails in the # ActionMailer::Base.deliveries array. config.action_mailer.delivery_method = :test # Use SQL instead of Active Record's schema dumper when creating the test database. # This is necessary if your schema can't be completely dumped by the schema dumper, # like if you have constraints or database-specific column types # config.active_record.schema_format = :sqlrabl-0.11.4/fixtures/rails2/config/environments/production.rb0000644000004100000410000000176312432721713024332 0ustar www-datawww-data# Settings specified here will take precedence over those in config/environment.rb # The production environment is meant for finished, "live" apps. # Code is not reloaded between requests config.cache_classes = true # Full error reports are disabled and caching is turned on config.action_controller.consider_all_requests_local = false config.action_controller.perform_caching = true config.action_view.cache_template_loading = true # See everything in the log (default is :info) # config.log_level = :debug # Use a different logger for distributed setups # config.logger = SyslogLogger.new # Use a different cache store in production # config.cache_store = :mem_cache_store # Enable serving of images, stylesheets, and javascripts from an asset server # config.action_controller.asset_host = "http://assets.example.com" # Disable delivery errors, bad email addresses will be ignored # config.action_mailer.raise_delivery_errors = false # Enable threaded mode # config.threadsafe!rabl-0.11.4/fixtures/rails2/config/environments/development.rb0000644000004100000410000000135312432721713024461 0ustar www-datawww-data# Settings specified here will take precedence over those in config/environment.rb # In the development environment your application's code is reloaded on # every request. This slows down response time but is perfect for development # since you don't have to restart the webserver when you make code changes. config.cache_classes = false # Log error messages when you accidentally call methods on nil. config.whiny_nils = true # Show full error reports and disable caching config.action_controller.consider_all_requests_local = true config.action_view.debug_rjs = true config.action_controller.perform_caching = false # Don't care if the mailer can't send config.action_mailer.raise_delivery_errors = falserabl-0.11.4/fixtures/rails2/config/database.yml0000644000004100000410000000065512432721713021356 0ustar www-datawww-data# SQLite version 3.x # gem install sqlite3-ruby (not necessary on OS X Leopard) development: adapter: sqlite3 database: ":memory:" pool: 5 timeout: 5000 # Warning: The database defined as "test" will be erased and # re-generated from your development database when you run "rake". # Do not set this db to the same as development or production. test: adapter: sqlite3 database: ":memory:" pool: 5 timeout: 5000 rabl-0.11.4/fixtures/rails2/config/routes.rb0000644000004100000410000000364712432721713020741 0ustar www-datawww-dataActionController::Routing::Routes.draw do |map| map.resources :posts map.resources :users # The priority is based upon order of creation: first created -> highest priority. # Sample of regular route: # map.connect 'products/:id', :controller => 'catalog', :action => 'view' # Keep in mind you can assign values other than :controller and :action # Sample of named route: # map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase' # This route can be invoked with purchase_url(:id => product.id) # Sample resource route (maps HTTP verbs to controller actions automatically): # map.resources :products # Sample resource route with options: # map.resources :products, :member => { :short => :get, :toggle => :post }, :collection => { :sold => :get } # Sample resource route with sub-resources: # map.resources :products, :has_many => [ :comments, :sales ], :has_one => :seller # Sample resource route with more complex sub-resources # map.resources :products do |products| # products.resources :comments # products.resources :sales, :collection => { :recent => :get } # end # Sample resource route within a namespace: # map.namespace :admin do |admin| # # Directs /admin/products/* to Admin::ProductsController (app/controllers/admin/products_controller.rb) # admin.resources :products # end # You can have the root of your site routed with map.root -- just remember to delete public/index.html. # map.root :controller => "welcome" # See how all your routes lay out with "rake routes" # Install the default routes as the lowest priority. # Note: These default routes make all actions in every controller accessible via GET requests. You should # consider removing or commenting them out if you're using named routes and resources. # map.connect ':controller/:action/:id' # map.connect ':controller/:action/:id.:format' end rabl-0.11.4/fixtures/rails2/config/environment.rb0000644000004100000410000000465712432721713021766 0ustar www-datawww-data# Be sure to restart your server when you modify this file # Specifies gem version of Rails to use when vendor/rails is not present RAILS_GEM_VERSION = '2.3.18' unless defined? RAILS_GEM_VERSION # Bootstrap the Rails environment, frameworks, and default configuration require File.join(File.dirname(__FILE__), 'boot') # Hot patch since Gem.source_index was deprecated in later rubygems unless Gem.method_defined?(:source_index) module Gem def self.source_index sources end def self.cache sources end SourceIndex = Specification class SourceList # If you want vendor gems, this is where to start writing code. def search( *args ); []; end def each( &block ); end include Enumerable end end end Rails::Initializer.run do |config| # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers # -- all .rb files in that directory are automatically loaded. # Add additional load paths for your own custom dirs # config.autoload_paths += %W( #{RAILS_ROOT}/extras ) # Specify gems that this application depends on and have them installed with rake gems:install # config.gem "bj" # config.gem "hpricot", :version => '0.6', :source => "http://code.whytheluckystiff.net" # config.gem "sqlite3-ruby", :lib => "sqlite3" # config.gem "aws-s3", :lib => "aws/s3" config.gem "rack-test", :lib => "rack/test" # Only load the plugins named here, in the order given (default is alphabetical). # :all can be used as a placeholder for all plugins not explicitly named # config.plugins = [ :exception_notification, :ssl_requirement, :all ] # Skip frameworks you're not going to use. To use Rails without a database, # you must remove the Active Record framework. # config.frameworks -= [ :active_record, :active_resource, :action_mailer ] # Activate observers that should always be running # config.active_record.observers = :cacher, :garbage_collector, :forum_observer # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. # Run "rake -D time" for a list of tasks for finding time zone names. config.time_zone = 'UTC' # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}')] # config.i18n.default_locale = :de endrabl-0.11.4/fixtures/rails2/config/preinitializer.rb0000644000004100000410000000113012432721713022433 0ustar www-datawww-databegin require "rubygems" require "bundler" rescue LoadError raise "Could not load the bundler gem. Install it with `gem install bundler`." end if Gem::Version.new(Bundler::VERSION) <= Gem::Version.new("0.9.24") raise RuntimeError, "Your bundler version is too old for Rails 2.3." + "Run `gem install bundler` to upgrade." end begin # Set up load paths for all bundled gems ENV["BUNDLE_GEMFILE"] = File.expand_path("../../Gemfile", __FILE__) Bundler.setup rescue Bundler::GemNotFound raise RuntimeError, "Bundler couldn't find some gems." + "Did you run `bundle install`?" endrabl-0.11.4/fixtures/rails2/config/locales/0000755000004100000410000000000012432721713020503 5ustar www-datawww-datarabl-0.11.4/fixtures/rails2/config/locales/en.yml0000644000004100000410000000032412432721713021627 0ustar www-datawww-data# Sample localization file for English. Add more files in this directory for other locales. # See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. en: hello: "Hello world"rabl-0.11.4/fixtures/rails2/app/0000755000004100000410000000000012432721713016374 5ustar www-datawww-datarabl-0.11.4/fixtures/rails2/app/controllers/0000755000004100000410000000000012432721713020742 5ustar www-datawww-datarabl-0.11.4/fixtures/rails2/app/controllers/posts_controller.rb0000644000004100000410000000047612432721713024711 0ustar www-datawww-dataclass PostsController < ApplicationController def index @posts = Post.all(:order => "id ASC") respond_to do |format| format.json { render "posts/index" } end end def show @post = Post.find(params[:id]) respond_to do |format| format.json { render "posts/show" } end end end rabl-0.11.4/fixtures/rails2/app/controllers/users_controller.rb0000644000004100000410000000050412432721713024672 0ustar www-datawww-dataclass UsersController < ApplicationController def index @users = User.all(:order => "username ASC") respond_to do |format| format.json { render "users/index" } end end def show @user = User.find(params[:id]) respond_to do |format| format.json { render "users/show" } end end end rabl-0.11.4/fixtures/rails2/app/controllers/application_controller.rb0000644000004100000410000000065612432721713026044 0ustar www-datawww-data# Filters added to this controller apply to all controllers in the application. # Likewise, all the methods added will be available for all controllers. class ApplicationController < ActionController::Base helper :all # include all helpers, all the time protect_from_forgery # See ActionController::RequestForgeryProtection for details # Scrub sensitive parameters from your log # filter_parameter_logging :password end rabl-0.11.4/fixtures/rails2/app/helpers/0000755000004100000410000000000012432721713020036 5ustar www-datawww-datarabl-0.11.4/fixtures/rails2/app/helpers/posts_helper.rb0000644000004100000410000000002712432721713023071 0ustar www-datawww-datamodule PostsHelper end rabl-0.11.4/fixtures/rails2/app/helpers/application_helper.rb0000644000004100000410000000003512432721713024223 0ustar www-datawww-datamodule ApplicationHelper end rabl-0.11.4/fixtures/rails2/app/helpers/users_helper.rb0000644000004100000410000000002712432721713023062 0ustar www-datawww-datamodule UsersHelper end rabl-0.11.4/fixtures/ashared/0000755000004100000410000000000012432721713016027 5ustar www-datawww-datarabl-0.11.4/fixtures/ashared/views/0000755000004100000410000000000012432721713017164 5ustar www-datawww-datarabl-0.11.4/fixtures/ashared/views/posts/0000755000004100000410000000000012432721713020334 5ustar www-datawww-datarabl-0.11.4/fixtures/ashared/views/posts/_show_footer_script.js.erb0000644000004100000410000000011212432721713025514 0ustar www-datawww-datavar output = <%= render(file: 'posts/show', formats: :json).html_safe %>; rabl-0.11.4/fixtures/ashared/views/posts/index.rabl0000644000004100000410000000041212432721713022302 0ustar www-datawww-datacollection @posts => :articles cache ['kittens!', @posts] extends "posts/show" node(:created_by_admin, :if => lambda { |p| p.user.is_admin }) do |p| true end child({ :user => :admin }, { :if => lambda { |p| p.user.is_admin }}) do |p| extends "users/show" endrabl-0.11.4/fixtures/ashared/views/posts/show.rabl0000644000004100000410000000041512432721713022156 0ustar www-datawww-dataobject @post cache @post attributes :title, :body attributes :created_at => :posted_at child :user do extends "users/show" end glue :user do attributes :username => :author_name end code(:created_date) do |p| partial("posts/date", :object => p.created_at) endrabl-0.11.4/fixtures/ashared/views/posts/date.rabl0000644000004100000410000000012112432721713022105 0ustar www-datawww-datacode(:day) { |d| d.day } code(:hour) { |d| d.hour } code(:full) { |d| d.iso8601 }rabl-0.11.4/fixtures/ashared/views/layouts/0000755000004100000410000000000012432721713020664 5ustar www-datawww-datarabl-0.11.4/fixtures/ashared/views/layouts/application.html.erb0000644000004100000410000000016512432721713024626 0ustar www-datawww-data RABL ROCKS! <%= yield %> rabl-0.11.4/fixtures/ashared/views/users/0000755000004100000410000000000012432721713020325 5ustar www-datawww-datarabl-0.11.4/fixtures/ashared/views/users/phone_number.json.rabl0000644000004100000410000000016412432721713024621 0ustar www-datawww-dataattributes :prefix, :suffix, :area_code attributes :is_primary => :primary node :formatted do |n| n.formatted endrabl-0.11.4/fixtures/ashared/views/users/show.json.rabl0000644000004100000410000000051412432721713023117 0ustar www-datawww-dataobject @user => :person attributes :username, :email, :location attributes :created_at => :registered_at node :role do |user| user.is_admin ? 'admin' : 'normal' end child :phone_numbers => :pnumbers do extends "users/phone_number" end node :node_numbers do |u| partial("users/phone_number", :object => u.phone_numbers) endrabl-0.11.4/fixtures/ashared/views/users/index.json.rabl0000644000004100000410000000004712432721713023247 0ustar www-datawww-datacollection @users extends "users/show"rabl-0.11.4/fixtures/ashared/views_rails_3/0000755000004100000410000000000012432721713020600 5ustar www-datawww-datarabl-0.11.4/fixtures/ashared/views_rails_3/posts/0000755000004100000410000000000012432721713021750 5ustar www-datawww-datarabl-0.11.4/fixtures/ashared/views_rails_3/posts/show.rabl_test_v1.rabl0000644000004100000410000000012712432721713026156 0ustar www-datawww-dataobject @post attribute :title => :title_v1 child :user do extends "users/show" end rabl-0.11.4/fixtures/ashared/views_rails_3/posts/_show_footer_script.js.erb0000644000004100000410000000011212432721713027130 0ustar www-datawww-datavar output = <%= render(file: 'posts/show', formats: :json).html_safe %>; rabl-0.11.4/fixtures/ashared/views_rails_3/posts/show.html.erb0000644000004100000410000000015412432721713024365 0ustar www-datawww-data<%= content_for :footer_scripts do %> <%= render partial: "show_footer_script", formats: :js %> <% end %> rabl-0.11.4/fixtures/ashared/views_rails_3/posts/index.html.erb0000644000004100000410000000017512432721713024517 0ustar www-datawww-data<%= content_for :footer_scripts do %> var output = <%= render(file: 'posts/index', formats: :json).html_safe %>; <% end %> rabl-0.11.4/fixtures/ashared/views_rails_3/posts/index.rabl0000644000004100000410000000041212432721713023716 0ustar www-datawww-datacollection @posts => :articles cache ['kittens!', @posts] extends "posts/show" node(:created_by_admin, :if => lambda { |p| p.user.is_admin }) do |p| true end child({ :user => :admin }, { :if => lambda { |p| p.user.is_admin }}) do |p| extends "users/show" endrabl-0.11.4/fixtures/ashared/views_rails_3/posts/renderer_partial.rabl0000644000004100000410000000006212432721713026132 0ustar www-datawww-dataobject @post cache @post attributes :title, :bodyrabl-0.11.4/fixtures/ashared/views_rails_3/posts/show.rabl0000644000004100000410000000064112432721713023573 0ustar www-datawww-dataobject @post cache @post attributes :title, :body attributes :created_at => :posted_at child :user do extends "users/show" end glue :user do attributes :username => :author_name end code(:created_date) do |p| partial("posts/date", :object => p.created_at) end node(:post) do |post| [post.title, post.body] end node(:foo) { helper_foo } node(:created_at_in_words) {|p| time_ago_in_words(p.created_at) } rabl-0.11.4/fixtures/ashared/views_rails_3/posts/date.rabl0000644000004100000410000000012112432721713023521 0ustar www-datawww-datacode(:day) { |d| d.day } code(:hour) { |d| d.hour } code(:full) { |d| d.iso8601 }rabl-0.11.4/fixtures/ashared/views_rails_3/posts/renderer.rabl0000644000004100000410000000017312432721713024421 0ustar www-datawww-dataobject @post cache @post attributes :title, :body node :partial do |p| partial('posts/renderer_partial', object: p) endrabl-0.11.4/fixtures/ashared/views_rails_3/layouts/0000755000004100000410000000000012432721713022300 5ustar www-datawww-datarabl-0.11.4/fixtures/ashared/views_rails_3/layouts/application.html.erb0000644000004100000410000000030512432721713026236 0ustar www-datawww-data RABL ROCKS! <%= yield %> <%= javascript_tag do %> <%= yield(:footer_scripts) %> <% end %> rabl-0.11.4/fixtures/ashared/views_rails_3/users/0000755000004100000410000000000012432721713021741 5ustar www-datawww-datarabl-0.11.4/fixtures/ashared/views_rails_3/users/show.rabl_test_v1.rabl0000644000004100000410000000007512432721713026151 0ustar www-datawww-dataobject @user => :person attribute :username => :username_v1 rabl-0.11.4/fixtures/ashared/views_rails_3/users/phone_number.json.rabl0000644000004100000410000000027612432721713026241 0ustar www-datawww-dataattributes :prefix, :suffix, :area_code attributes :is_primary => :primary if locals[:reversed] node(:reversed) { |n| n.formatted.reverse } else node(:formatted) { |n| n.formatted } endrabl-0.11.4/fixtures/ashared/views_rails_3/users/show.json.rabl0000644000004100000410000000060412432721713024533 0ustar www-datawww-dataobject @user => :person attributes :username, :email, :location attributes :created_at => :registered_at node :role do |user| user.is_admin ? 'admin' : 'normal' end child :phone_numbers => :pnumbers do extends "users/phone_number" end node :node_numbers do |u| partial("users/phone_number", :object => u.phone_numbers, :locals => { :reversed => locals[:reversed].presence }) endrabl-0.11.4/fixtures/ashared/views_rails_3/users/phone_number.xml.rabl0000644000004100000410000000027612432721713026070 0ustar www-datawww-dataattributes :prefix, :suffix, :area_code attributes :is_primary => :primary if locals[:reversed] node(:reversed) { |n| n.formatted.reverse } else node(:formatted) { |n| n.formatted } endrabl-0.11.4/fixtures/ashared/views_rails_3/users/index.json.rabl0000644000004100000410000000011112432721713024653 0ustar www-datawww-datacollection @users extends "users/show", :locals => { :reversed => true }rabl-0.11.4/fixtures/ashared/README0000644000004100000410000000116312432721713016710 0ustar www-datawww-dataFixtures to test RABL: Gemfile: gem 'rabl', :path => File.expand_path(File.dirname(__FILE__) + "/../../") gem 'riot', :group => "test" models: user t.string :username t.string :email t.string :location t.boolean :is_admin t.timestamps posts t.integer :user_id t.string :title t.text :body t.timestamps phone_number t.integer :user_id t.boolean :is_primary t.string :area_code t.string :prefix t.string :suffix t.string :name controllers: users posts layouts: application.html.haml views: posts (index, show, date) users (index, show)rabl-0.11.4/fixtures/ashared/NOTES0000644000004100000410000000341312432721713016643 0ustar www-datawww-data# Sinatra cd fixtures/sinatra_test ln -s "../ashared/models" models ln -s "../ashared/views/" views ln -s "../../ashared/migrate" db/migrate ln -s ../../../../test/integration/posts_controller_test.rb test/functional/posts_controller_test.rb ln -s ../../../../test/integration/users_controller_test.rb test/functional/users_controller_test.rb # Padrino cd fixtures/padrino_test ln -s "../ashared/models" models ln -s "../../ashared/views/" app/views ln -s "../../ashared/migrate" db/migrate ln -s ../../../../../test/integration/posts_controller_test.rb test/app/controllers/posts_controller_test.rb ln -s ../../../../../test/integration/users_controller_test.rb test/app/controllers/users_controller_test.rb # Rails 2 cd fixtures/rails2 ln -s "../../ashared/models" app/models ln -s "../../ashared/views/" app/views ln -s "../../ashared/migrate" db/migrate ln -s ../../../../test/integration/posts_controller_test.rb test/functionals/posts_controller_test.rb ln -s ../../../../test/integration/users_controller_test.rb test/functionals/users_controller_test.rb # Rails 3 cd fixtures/rails3 ln -s "../../ashared/models" app/models ln -s "../../ashared/views/" app/views ln -s "../../ashared/migrate" db/migrate ln -s ../../../../test/integration/posts_controller_test.rb test/functional/posts_controller_test.rb ln -s ../../../../test/integration/users_controller_test.rb test/functional/users_controller_test.rb # Rails 3.2 cd fixtures/rails3_2 ln -s "../../ashared/models" app/models ln -s "../../ashared/views_rails_3/" app/views ln -s "../../ashared/migrate" db/migrate ln -s ../../../../test/integration/rails3_2/posts_controller_test.rb test/functional/posts_controller_test.rb ln -s ../../../../test/integration/rails3_2/users_controller_test.rb test/functional/users_controller_test.rb rabl-0.11.4/fixtures/ashared/models/0000755000004100000410000000000012432721713017312 5ustar www-datawww-datarabl-0.11.4/fixtures/ashared/models/post.rb0000644000004100000410000000006712432721713020627 0ustar www-datawww-dataclass Post < ActiveRecord::Base belongs_to :user end rabl-0.11.4/fixtures/ashared/models/phone_number.rb0000644000004100000410000000021512432721713022316 0ustar www-datawww-dataclass PhoneNumber < ActiveRecord::Base belongs_to :user def formatted "(#{self.area_code}) #{self.prefix}-#{self.suffix}" end end rabl-0.11.4/fixtures/ashared/models/user.rb0000644000004100000410000000007612432721713020620 0ustar www-datawww-dataclass User < ActiveRecord::Base has_many :phone_numbers end rabl-0.11.4/fixtures/ashared/migrate/0000755000004100000410000000000012432721713017457 5ustar www-datawww-datarabl-0.11.4/fixtures/ashared/migrate/20111002092016_create_users.rb0000644000004100000410000000042012432721713024114 0ustar www-datawww-dataclass CreateUsers < ActiveRecord::Migration def self.up create_table :users do |t| t.string :username t.string :email t.string :location t.boolean :is_admin t.timestamps end end def self.down drop_table :users end end rabl-0.11.4/fixtures/ashared/migrate/20111002092019_create_posts.rb0000644000004100000410000000036112432721713024132 0ustar www-datawww-dataclass CreatePosts < ActiveRecord::Migration def self.up create_table :posts do |t| t.integer :user_id t.string :title t.text :body t.timestamps end end def self.down drop_table :posts end end rabl-0.11.4/fixtures/ashared/migrate/20111002092024_create_phone_numbers.rb0000644000004100000410000000050112432721713025616 0ustar www-datawww-dataclass CreatePhoneNumbers < ActiveRecord::Migration def self.up create_table :phone_numbers do |t| t.integer :user_id t.boolean :is_primary t.string :area_code t.string :prefix t.string :suffix t.string :name end end def self.down drop_table :phone_numbers end end rabl-0.11.4/fixtures/rails4/0000755000004100000410000000000012432721713015616 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/Rakefile0000644000004100000410000000056012432721713017264 0ustar www-datawww-data# Add your own tasks in files placed in lib/tasks ending in .rake, # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. require File.expand_path('../config/application', __FILE__) Rails4::Application.load_tasks Rake::TestTask.new("test:rabl") do |test| test.pattern = "test/functional/**/*_test.rb" test.verbose = true end rabl-0.11.4/fixtures/rails4/bin/0000755000004100000410000000000012432721713016366 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/bin/rake0000755000004100000410000000013212432721713017232 0ustar www-datawww-data#!/usr/bin/env ruby require_relative '../config/boot' require 'rake' Rake.application.run rabl-0.11.4/fixtures/rails4/bin/rails0000755000004100000410000000022212432721713017422 0ustar www-datawww-data#!/usr/bin/env ruby APP_PATH = File.expand_path('../../config/application', __FILE__) require_relative '../config/boot' require 'rails/commands' rabl-0.11.4/fixtures/rails4/bin/bundle0000755000004100000410000000020112432721713017556 0ustar www-datawww-data#!/usr/bin/env ruby ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) load Gem.bin_path('bundler', 'bundle') rabl-0.11.4/fixtures/rails4/Gemfile0000644000004100000410000000242512432721713017114 0ustar www-datawww-datasource 'https://rubygems.org' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '4.0.0' # Use sqlite3 as the database for Active Record gem 'sqlite3' gem 'rabl', :path => File.expand_path(File.dirname(__FILE__) + "/../../") gem 'riot', :group => "test" gem "oj" # Use SCSS for stylesheets gem 'sass-rails', '~> 4.0.0' # Use Uglifier as compressor for JavaScript assets gem 'uglifier', '>= 1.3.0' # Use CoffeeScript for .js.coffee assets and views gem 'coffee-rails', '~> 4.0.0' # See https://github.com/sstephenson/execjs#readme for more supported runtimes # gem 'therubyracer', platforms: :ruby # Use jquery as the JavaScript library gem 'jquery-rails' # Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks # gem 'turbolinks' # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder # gem 'jbuilder', '~> 1.0.1' # group :doc do # # bundle exec rake doc:rails generates the API under doc/api. # gem 'sdoc', require: false # end # Use ActiveModel has_secure_password # gem 'bcrypt-ruby', '~> 3.0.0' # Use unicorn as the app server # gem 'unicorn' # Use Capistrano for deployment # gem 'capistrano', group: :development # Use debugger gem 'debugger', group: [:development, :test] rabl-0.11.4/fixtures/rails4/log/0000755000004100000410000000000012432721713016377 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/log/.keep0000644000004100000410000000000012432721713017312 0ustar www-datawww-datarabl-0.11.4/fixtures/rails4/db/0000755000004100000410000000000012432721713016203 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/db/seeds.rb0000644000004100000410000000052712432721713017637 0ustar www-datawww-data# This file should contain all the record creation needed to seed the database with its default values. # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). # # Examples: # # cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }]) # Mayor.create(name: 'Emanuel', city: cities.first) rabl-0.11.4/fixtures/rails4/vendor/0000755000004100000410000000000012432721713017113 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/vendor/assets/0000755000004100000410000000000012432721713020415 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/vendor/assets/javascripts/0000755000004100000410000000000012432721713022746 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/vendor/assets/javascripts/.keep0000644000004100000410000000000012432721713023661 0ustar www-datawww-datarabl-0.11.4/fixtures/rails4/vendor/assets/stylesheets/0000755000004100000410000000000012432721713022771 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/vendor/assets/stylesheets/.keep0000644000004100000410000000000012432721713023704 0ustar www-datawww-datarabl-0.11.4/fixtures/rails4/public/0000755000004100000410000000000012432721713017074 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/public/422.html0000644000004100000410000000246612432721713020301 0ustar www-datawww-data The change you wanted was rejected (422)

The change you wanted was rejected.

Maybe you tried to change something you didn't have access to.

If you are the application owner check the logs for more information.

rabl-0.11.4/fixtures/rails4/public/favicon.ico0000644000004100000410000000000012432721713021203 0ustar www-datawww-datarabl-0.11.4/fixtures/rails4/public/robots.txt0000644000004100000410000000031412432721713021143 0ustar www-datawww-data# See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file # # To ban all spiders from the entire site uncomment the next two lines: # User-agent: * # Disallow: / rabl-0.11.4/fixtures/rails4/public/404.html0000644000004100000410000000250712432721713020275 0ustar www-datawww-data The page you were looking for doesn't exist (404)

The page you were looking for doesn't exist.

You may have mistyped the address or the page may have moved.

If you are the application owner check the logs for more information.

rabl-0.11.4/fixtures/rails4/public/500.html0000644000004100000410000000236212432721713020271 0ustar www-datawww-data We're sorry, but something went wrong (500)

We're sorry, but something went wrong.

If you are the application owner check the logs for more information.

rabl-0.11.4/fixtures/rails4/README.rdoc0000644000004100000410000000073612432721713017432 0ustar www-datawww-data== README This README would normally document whatever steps are necessary to get the application up and running. Things you may want to cover: * Ruby version * System dependencies * Configuration * Database creation * Database initialization * How to run the test suite * Services (job queues, cache servers, search engines, etc.) * Deployment instructions * ... Please feel free to use a different markup language if you do not plan to run rake doc:app. rabl-0.11.4/fixtures/rails4/lib/0000755000004100000410000000000012432721713016364 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/lib/assets/0000755000004100000410000000000012432721713017666 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/lib/assets/.keep0000644000004100000410000000000012432721713020601 0ustar www-datawww-datarabl-0.11.4/fixtures/rails4/lib/tasks/0000755000004100000410000000000012432721713017511 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/lib/tasks/.keep0000644000004100000410000000000012432721713020424 0ustar www-datawww-datarabl-0.11.4/fixtures/rails4/test/0000755000004100000410000000000012432721713016575 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/test/controllers/0000755000004100000410000000000012432721713021143 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/test/controllers/.keep0000644000004100000410000000000012432721713022056 0ustar www-datawww-datarabl-0.11.4/fixtures/rails4/test/mailers/0000755000004100000410000000000012432721713020231 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/test/mailers/.keep0000644000004100000410000000000012432721713021144 0ustar www-datawww-datarabl-0.11.4/fixtures/rails4/test/fixtures/0000755000004100000410000000000012432721713020446 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/test/fixtures/.keep0000644000004100000410000000000012432721713021361 0ustar www-datawww-datarabl-0.11.4/fixtures/rails4/test/test_helper.rb0000644000004100000410000000140412432721713021437 0ustar www-datawww-data# Load Silence Functionality require File.expand_path(File.dirname(__FILE__) + "/../../../test/silence.rb") # Load Environment silence_warnings do ENV["RAILS_ENV"] = "test" require File.expand_path('../../config/environment', __FILE__) require 'rails/test_help' end # Load Riot Test Environment require File.expand_path(File.dirname(__FILE__) + "/../../../test/integration/test_init.rb") # Run Migrations silence_stream(STDOUT) do dbconf = YAML::load(File.open('config/database.yml'))[Rails.env] ActiveRecord::Base.establish_connection(dbconf) ActiveRecord::Base.logger = Logger.new(File.open('log/database.log', 'a')) silence_stream(STDOUT) { ActiveRecord::Migrator.up('db/migrate') } end class Riot::Situation def app Rails.application end end rabl-0.11.4/fixtures/rails4/test/integration/0000755000004100000410000000000012432721713021120 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/test/integration/.keep0000644000004100000410000000000012432721713022033 0ustar www-datawww-datarabl-0.11.4/fixtures/rails4/test/models/0000755000004100000410000000000012432721713020060 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/test/models/.keep0000644000004100000410000000000012432721713020773 0ustar www-datawww-datarabl-0.11.4/fixtures/rails4/test/helpers/0000755000004100000410000000000012432721713020237 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/test/helpers/.keep0000644000004100000410000000000012432721713021152 0ustar www-datawww-datarabl-0.11.4/fixtures/rails4/test/functional/0000755000004100000410000000000012432721713020737 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/test/functional/users_controller_test.rb0000644000004100000410000000643412432721713025736 0ustar www-datawww-data# Lives in /test/integration/users_controller_test.rb # Symlinked to fixture applications begin # Sinatra require File.expand_path(File.dirname(__FILE__) + '/../../test_config.rb') rescue LoadError # Rails require File.expand_path(File.dirname(__FILE__) + '/../test_helper.rb') end context "UsersController" do helper(:json_output) { JSON.parse(last_response.body) } setup do create_users! end context "for index action" do # Tests `collection @users` extending from 'show' template setup do get "/users", format: :json end # Attributes (regular) asserts("contains user usernames") do json_output.map { |u| u["user"]["username"] } end.equals { @users.map(&:username) } asserts("contains email") do json_output.map { |u| u["user"]["email"] } end.equals { @users.map(&:email) } asserts("contains location") do json_output.map { |u| u["user"]["location"] } end.equals { @users.map(&:location) } # Attributes (custom name) asserts("contains registered_at") do json_output.map { |u| u["user"]["registered_at"] } end.equals { @users.map(&:created_at).map { |t| t.iso8601(3) } } # Node (renders based on attribute) asserts("contains role") do json_output.map { |u| u["user"]["role"] } end.equals ['normal', 'normal', 'admin'] # Child (custom collection name) asserts("contains formatted phone numbers") do json_output.map { |u| u["user"]["pnumbers"].map { |n| n["pnumber"]["formatted"] } } end.equals { @users.map { |u| u.phone_numbers.map(&:formatted) } } # Node (renders collection partial) asserts("contains reversed node numbers") do json_output.map { |u| u["user"]["node_numbers"].map { |n| n["reversed"] } } end.equals { @users.map { |u| u.phone_numbers.map(&:formatted).map(&:reverse) } } end # index context "for show action" do # Tests `object :user => :person` custom parent node name setup do get "/users/#{@user1.id}", format: :json end # Attributes (regular) asserts("contains username") { json_output["person"]["username"] }.equals { @user1.username } asserts("contains email") { json_output["person"]["email"] }.equals { @user1.email } asserts("contains location") { json_output["person"]["location"] }.equals { @user1.location } # Attributes (custom name) asserts("contains registered_at") { json_output["person"]["registered_at"] }.equals { @user1.created_at.iso8601(3) } # Node (renders based on attribute) asserts("contains role node") { json_output["person"]["role"] }.equals "normal" # Child (custom collection name) asserts("contains first phone number") { json_output["person"]["pnumbers"][0]["pnumber"]["formatted"] }.equals { @user1.phone_numbers[0].formatted } asserts("contains second phone number") { json_output["person"]["pnumbers"][1]["pnumber"]["formatted"] }.equals { @user1.phone_numbers[1].formatted } # Node (renders collection partial) asserts("contains first node number") { json_output["person"]["node_numbers"][0]["formatted"] }.equals { @user1.phone_numbers[0].formatted } asserts("contains second node number") { json_output["person"]["node_numbers"][1]["formatted"] }.equals { @user1.phone_numbers[1].formatted } end # show end rabl-0.11.4/fixtures/rails4/test/functional/posts_controller_test.rb0000755000004100000410000002155312432721713025747 0ustar www-datawww-data# Lives in /test/integration/posts_controller_test.rb # Symlinked to fixture applications begin # Padrino require File.expand_path(File.dirname(__FILE__) + '/../../test_config.rb') rescue LoadError # Rails require File.expand_path(File.dirname(__FILE__) + '/../test_helper.rb') end require 'rexml/document' context "PostsController" do helper(:json_output) { JSON.parse(last_response.body) } setup do create_users! Post.delete_all @post1 = Post.create(:title => "Foo", :body => "Bar", :user_id => @user1.id) @post2 = Post.create(:title => "Baz", :body => "Bah", :user_id => @user2.id) @post3 = Post.create(:title => "Kaz", :body => "", :user_id => @user3.id) @posts = [@post1, @post2, @post3] end context "for index action" do setup do get "/posts", format: :json end # Attributes (regular) asserts("contains post titles") do json_output['articles'].map { |o| o["article"]["title"] } end.equals { @posts.map(&:title) } asserts("contains post bodies") do json_output['articles'].map { |o| o["article"]["body"] } end.equals { @posts.map(&:body) } # Attributes (custom name) asserts("contains post posted_at") do json_output['articles'].map { |o| o["article"]["posted_at"] } end.equals { @posts.map(&:created_at).map{ |t| t.iso8601(3) } } # Child asserts("contains post user child username") do json_output['articles'].map { |o| o["article"]["user"]["username"] } end.equals { @posts.map(&:user).map(&:username) } asserts("contains post user child role") do json_output['articles'].map { |o| o["article"]["user"]["role"] } end.equals { ["normal", "normal", "admin"] } # Child Numbers of the Child User asserts("contains post user child numbers") do json_output['articles'].map { |o| o["article"]["user"]["pnumbers"][0]["pnumber"]["formatted"] } end.equals { @posts.map(&:user).map(&:phone_numbers).map(&:first).map(&:formatted) } # Glue (username to article) asserts("contains glued usernames") do json_output['articles'].map { |o| o["article"]["author_name"] } end.equals { @posts.map(&:user).map(&:username) } # Conditional Child (admin) asserts("contains admin child only for admins") do json_output['articles'].map { |o| o["article"]["admin"]["username"] if o["article"].has_key?("admin") }.compact end.equals { [@user3.username] } # Conditional Node (created_by_admin) asserts("contains created_by_admin node for admins") do json_output['articles'].last['article']['created_by_admin'] end.equals { true } denies("contains no created_by_admin node for non-admins") do json_output['articles'].first['article'] end.includes(:created_by_admin) end # index action, json context "escaping output in index action" do context "for first post" do setup do Rabl.configuration.escape_all_output = true get "/posts/#{@post1.id}", format: :json json_output['post'] end # Attributes (regular) asserts("contains post title") { topic['title'] }.equals { @post1.title } asserts("contains post body") { topic['body'] }.equals { @post1.body } end context "for third post with script tags" do setup do Rabl.configuration.escape_all_output = true get "/posts/#{@post3.id}", format: :json json_output['post'] end # Attributes (regular) asserts("contains post title") { topic['title'] }.equals { @post3.title } asserts("contains escaped post body") { topic['body'] }.equals { ERB::Util.h(@post3.body) } end end # escaping output context "for show action" do setup do get "/posts/#{@post1.id}", format: :json json_output['post'] end # Attributes (regular) asserts("contains post title") { topic['title'] }.equals { @post1.title } asserts("contains post body") { topic['body'] }.equals { @post1.body } # Attributes (custom name) asserts("contains post posted_at") { topic['posted_at'] }.equals { @post1.created_at.iso8601(3) } # Child asserts("contains post user child username") { topic["user"]["username"] }.equals { @post1.user.username } asserts("contains post user child role") { topic["user"]["role"] }.equals { "normal" } # Child Numbers of the Child User asserts("contains post user child numbers") do topic["user"]["pnumbers"][0]["pnumber"]["formatted"] end.equals { @post1.user.phone_numbers[0].formatted } # Glue (username to article) asserts("contains glued username") { topic["author_name"] }.equals { @post1.user.username } # Non-ORM Date Node Partial context "for date node" do setup { json_output['post']['created_date'] } asserts("contains date partial with day") { topic['day'] }.equals { @post1.created_at.day } asserts("contains date partial with hour") { topic['hour'] }.equals { @post1.created_at.hour } asserts("contains date partial with full") { topic['full'] }.equals { @post1.created_at.iso8601 } end # date node asserts("contains helper action") { topic["foo"] }.equals { "BAR!" } denies("contains helper action") { topic["created_at_in_words"] }.nil asserts("contains post attributes via node") { topic["post"] }.equals { [@post1.title, @post1.body] } end # show action, json context "renderer" do setup do mock(ActionController::Base).perform_caching.any_number_of_times { true } get "/posts/#{@post1.id}/renderer" json_output['post'] end # Attributes (regular) asserts("contains post title") { topic['title'] }.equals { @post1.title } asserts("contains post body") { topic['body'] }.equals { @post1.body } # Attributes (partial) asserts("contains post partial title") { topic['partial']['title'] }.equals { @post1.title } asserts("contains post partial body") { topic['partial']['body'] }.equals { @post1.body } end # renderer action, json context "for index action rendering JSON within HTML" do setup do get "/posts", format: :html end asserts(:body).includes { "" } end # index action, html context "for show action rendering JSON within HTML" do setup do get "/posts/#{@post1.id}", format: :html end asserts(:body).includes { "" } end # show action, html context "mime_type" do setup do get "/posts/#{@post1.id}", format: :rabl_test_v1 end asserts("contains post title") { json_output['post']['title_v1'] }.equals { @post1.title } asserts("contains username") { json_output['post']['user']['username_v1'] }.equals { @post1.user.username } end context "caching" do helper(:cache_hit) do |key| Rails.cache.read(ActiveSupport::Cache.expand_cache_key(key, :rabl)) end setup do mock(ActionController::Base).perform_caching.any_number_of_times { true } Rails.cache.clear end context "for index action with caching in json" do setup do get "/posts", format: :json end asserts("contains post titles") do json_output['articles'].map { |o| o['article']['title'] } end.equals { @posts.map(&:title) } asserts(:body).equals { cache_hit ['kittens!', @posts, nil, 'json', 'e83f65eee5ffb454c418a59105f222c4'] } asserts("contains cache hits per object (posts by title)") do json_output['articles'].map { |o| o['article']['title'] } end.equals { @posts.map { |p| cache_hit([p, nil, 'hash', 'e373525f49a3b3b044af05255e84839d'])[:title] } } end # index action, caching, json context "for index action with caching in xml" do setup do get "/posts", format: :xml end asserts("contains post titles") do doc = REXML::Document.new topic.body doc.elements.inject('articles/article/title', []) {|arr, ele| arr << ele.text} end.equals { @posts.map(&:title) } asserts(:body).equals { cache_hit ['kittens!', @posts, nil, 'xml', 'e83f65eee5ffb454c418a59105f222c4'] } end # index action, caching, xml context "for show action with caching" do setup do get "/posts/#{@post1.id}", format: :json end asserts("contains post title") { json_output['post']['title'] }.equals { @post1.title } asserts(:body).equals { cache_hit [@post1, nil, 'json', 'e373525f49a3b3b044af05255e84839d'] } end # show action, caching, json context "cache_all_output" do helper(:cache_hit) do |key| Rails.cache.read(ActiveSupport::Cache.expand_cache_key([key, 'article', 'json'], :rabl)) end setup do Rabl.configuration.cache_all_output = true get "/posts", format: :json end asserts("contains cache hits per object (posts by title)") do json_output['articles'].map { |o| o['article']['title'] } end.equals { @posts.map{ |p| cache_hit(p)['article'][:title] } } end # index action, cache_all_output end end rabl-0.11.4/fixtures/rails4/.gitignore0000644000004100000410000000070712432721713017612 0ustar www-datawww-data# See http://help.github.com/ignore-files/ for more about ignoring files. # # If you find yourself ignoring temporary files generated by your text editor # or operating system, you probably want to add a global ignore instead: # git config --global core.excludesfile '~/.gitignore_global' # Ignore bundler config. /.bundle # Ignore the default SQLite database. /db/*.sqlite3 /db/*.sqlite3-journal # Ignore all logfiles and tempfiles. /log/*.log /tmp rabl-0.11.4/fixtures/rails4/config/0000755000004100000410000000000012432721713017063 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/config/application.rb0000644000004100000410000000172712432721713021722 0ustar www-datawww-datarequire File.expand_path('../boot', __FILE__) require 'rails/all' # Require the gems listed in Gemfile, including any gems # you've limited to :test, :development, or :production. Bundler.require(:default, Rails.env) module Rails4 class Application < Rails::Application # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers # -- all .rb files in that directory are automatically loaded. # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. # config.time_zone = 'Central Time (US & Canada)' # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] # config.i18n.default_locale = :de end end rabl-0.11.4/fixtures/rails4/config/initializers/0000755000004100000410000000000012432721713021571 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/config/initializers/secret_token.rb0000644000004100000410000000122412432721713024602 0ustar www-datawww-data# Be sure to restart your server when you modify this file. # Your secret key is used for verifying the integrity of signed cookies. # If you change this key, all old signed cookies will become invalid! # Make sure the secret is at least 30 characters and all random, # no regular words or you'll be exposed to dictionary attacks. # You can use `rake secret` to generate a secure secret key. # Make sure your secret_key_base is kept private # if you're sharing your code publicly. Rails4::Application.config.secret_key_base = '6e92b4aa4cb4e4f8c4dbb3874d83a205a8821fe0e30311aaf306aa3897e89c78b2ab84fad6905ce0a9c42e7b6ae860603eed6e20f4d3e3361cf599261fadd408' rabl-0.11.4/fixtures/rails4/config/initializers/session_store.rb0000644000004100000410000000021412432721713025012 0ustar www-datawww-data# Be sure to restart your server when you modify this file. Rails4::Application.config.session_store :cookie_store, key: '_rails4_session' rabl-0.11.4/fixtures/rails4/config/initializers/mime_types.rb0000644000004100000410000000042512432721713024272 0ustar www-datawww-data# Be sure to restart your server when you modify this file. # Add new mime types for use in respond_to blocks: # Mime::Type.register "text/richtext", :rtf # Mime::Type.register_alias "text/html", :iphone Mime::Type.register 'application/vnd.rabl-test_v1+json', :rabl_test_v1 rabl-0.11.4/fixtures/rails4/config/initializers/filter_parameter_logging.rb0000644000004100000410000000030212432721713027144 0ustar www-datawww-data# Be sure to restart your server when you modify this file. # Configure sensitive parameters which will be filtered from the log file. Rails.application.config.filter_parameters += [:password] rabl-0.11.4/fixtures/rails4/config/initializers/wrap_parameters.rb0000644000004100000410000000100512432721713025306 0ustar www-datawww-data# Be sure to restart your server when you modify this file. # This file contains settings for ActionController::ParamsWrapper which # is enabled by default. # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. ActiveSupport.on_load(:action_controller) do wrap_parameters format: [:json] if respond_to?(:wrap_parameters) end # To enable root element in JSON for ActiveRecord objects. # ActiveSupport.on_load(:active_record) do # self.include_root_in_json = true # end rabl-0.11.4/fixtures/rails4/config/initializers/backtrace_silencers.rb0000644000004100000410000000062412432721713026106 0ustar www-datawww-data# Be sure to restart your server when you modify this file. # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. # Rails.backtrace_cleaner.remove_silencers! rabl-0.11.4/fixtures/rails4/config/initializers/inflections.rb0000644000004100000410000000120712432721713024433 0ustar www-datawww-data# Be sure to restart your server when you modify this file. # Add new inflection rules using the following format. Inflections # are locale specific, and you may define rules for as many different # locales as you wish. All of these examples are active by default: # ActiveSupport::Inflector.inflections(:en) do |inflect| # inflect.plural /^(ox)$/i, '\1en' # inflect.singular /^(ox)en/i, '\1' # inflect.irregular 'person', 'people' # inflect.uncountable %w( fish sheep ) # end # These inflection rules are supported but not enabled by default: # ActiveSupport::Inflector.inflections(:en) do |inflect| # inflect.acronym 'RESTful' # end rabl-0.11.4/fixtures/rails4/config/boot.rb0000644000004100000410000000025312432721713020353 0ustar www-datawww-data# Set up gems listed in the Gemfile. ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE']) rabl-0.11.4/fixtures/rails4/config/environments/0000755000004100000410000000000012432721713021612 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/config/environments/test.rb0000644000004100000410000000303012432721713023112 0ustar www-datawww-dataRails4::Application.configure do # Settings specified here will take precedence over those in config/application.rb. # The test environment is used exclusively to run your application's # test suite. You never need to work with it otherwise. Remember that # your test database is "scratch space" for the test suite and is wiped # and recreated between test runs. Don't rely on the data there! config.cache_classes = true # Do not eager load code on boot. This avoids loading your whole application # just for the purpose of running a single test. If you are using a tool that # preloads Rails for running tests, you may have to set it to true. config.eager_load = false # Configure static asset server for tests with Cache-Control for performance. config.serve_static_assets = true config.static_cache_control = "public, max-age=3600" # Show full error reports and disable caching. config.consider_all_requests_local = true config.action_controller.perform_caching = false # Raise exceptions instead of rendering exception templates. config.action_dispatch.show_exceptions = false # Disable request forgery protection in test environment. config.action_controller.allow_forgery_protection = false # Tell Action Mailer not to deliver emails to the real world. # The :test delivery method accumulates sent emails in the # ActionMailer::Base.deliveries array. config.action_mailer.delivery_method = :test # Print deprecation notices to the stderr. config.active_support.deprecation = :stderr end rabl-0.11.4/fixtures/rails4/config/environments/production.rb0000644000004100000410000000626212432721713024333 0ustar www-datawww-dataRails4::Application.configure do # Settings specified here will take precedence over those in config/application.rb. # Code is not reloaded between requests. config.cache_classes = true # Eager load code on boot. This eager loads most of Rails and # your application in memory, allowing both thread web servers # and those relying on copy on write to perform better. # Rake tasks automatically ignore this option for performance. config.eager_load = true # Full error reports are disabled and caching is turned on. config.consider_all_requests_local = false config.action_controller.perform_caching = true # Enable Rack::Cache to put a simple HTTP cache in front of your application # Add `rack-cache` to your Gemfile before enabling this. # For large-scale production use, consider using a caching reverse proxy like nginx, varnish or squid. # config.action_dispatch.rack_cache = true # Disable Rails's static asset server (Apache or nginx will already do this). config.serve_static_assets = false # Compress JavaScripts and CSS. config.assets.js_compressor = :uglifier # config.assets.css_compressor = :sass # Do not fallback to assets pipeline if a precompiled asset is missed. config.assets.compile = false # Generate digests for assets URLs. config.assets.digest = true # Version of your assets, change this if you want to expire all your assets. config.assets.version = '1.0' # Specifies the header that your server uses for sending files. # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. # config.force_ssl = true # Set to :debug to see everything in the log. config.log_level = :info # Prepend all log lines with the following tags. # config.log_tags = [ :subdomain, :uuid ] # Use a different logger for distributed setups. # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) # Use a different cache store in production. # config.cache_store = :mem_cache_store # Enable serving of images, stylesheets, and JavaScripts from an asset server. # config.action_controller.asset_host = "http://assets.example.com" # Precompile additional assets. # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. # config.assets.precompile += %w( search.js ) # Ignore bad email addresses and do not raise email delivery errors. # Set this to true and configure the email server for immediate delivery to raise delivery errors. # config.action_mailer.raise_delivery_errors = false # Enable locale fallbacks for I18n (makes lookups for any locale fall back to # the I18n.default_locale when a translation can not be found). config.i18n.fallbacks = true # Send deprecation notices to registered listeners. config.active_support.deprecation = :notify # Disable automatic flushing of the log to improve performance. # config.autoflush_log = false # Use default logging formatter so that PID and timestamp are not suppressed. config.log_formatter = ::Logger::Formatter.new end rabl-0.11.4/fixtures/rails4/config/environments/development.rb0000644000004100000410000000213212432721713024457 0ustar www-datawww-dataRails4::Application.configure do # Settings specified here will take precedence over those in config/application.rb. # In the development environment your application's code is reloaded on # every request. This slows down response time but is perfect for development # since you don't have to restart the web server when you make code changes. config.cache_classes = false # Do not eager load code on boot. config.eager_load = false # Show full error reports and disable caching. config.consider_all_requests_local = true config.action_controller.perform_caching = false # Don't care if the mailer can't send. config.action_mailer.raise_delivery_errors = false # Print deprecation notices to the Rails logger. config.active_support.deprecation = :log # Raise an error on page load if there are pending migrations config.active_record.migration_error = :page_load # Debug mode disables concatenation and preprocessing of assets. # This option may cause significant delays in view rendering with a large # number of complex assets. config.assets.debug = true end rabl-0.11.4/fixtures/rails4/config/database.yml0000644000004100000410000000110012432721713021342 0ustar www-datawww-data# SQLite version 3.x # gem install sqlite3 # # Ensure the SQLite 3 gem is defined in your Gemfile # gem 'sqlite3' development: adapter: sqlite3 database: db/development.sqlite3 pool: 5 timeout: 5000 # Warning: The database defined as "test" will be erased and # re-generated from your development database when you run "rake". # Do not set this db to the same as development or production. test: adapter: sqlite3 database: db/test.sqlite3 pool: 5 timeout: 5000 production: adapter: sqlite3 database: db/production.sqlite3 pool: 5 timeout: 5000 rabl-0.11.4/fixtures/rails4/config/routes.rb0000644000004100000410000000273012432721713020733 0ustar www-datawww-dataRails4::Application.routes.draw do resources :users resources :posts do member do get 'renderer' end end # The priority is based upon order of creation: first created -> highest priority. # See how all your routes lay out with "rake routes". # You can have the root of your site routed with "root" # root 'welcome#index' # Example of regular route: # get 'products/:id' => 'catalog#view' # Example of named route that can be invoked with purchase_url(id: product.id) # get 'products/:id/purchase' => 'catalog#purchase', as: :purchase # Example resource route (maps HTTP verbs to controller actions automatically): # resources :products # Example resource route with options: # resources :products do # member do # get 'short' # post 'toggle' # end # # collection do # get 'sold' # end # end # Example resource route with sub-resources: # resources :products do # resources :comments, :sales # resource :seller # end # Example resource route with more complex sub-resources: # resources :products do # resources :comments # resources :sales do # get 'recent', on: :collection # end # end # Example resource route within a namespace: # namespace :admin do # # Directs /admin/products/* to Admin::ProductsController # # (app/controllers/admin/products_controller.rb) # resources :products # end end rabl-0.11.4/fixtures/rails4/config/environment.rb0000644000004100000410000000023012432721713021747 0ustar www-datawww-data# Load the rails application. require File.expand_path('../application', __FILE__) # Initialize the rails application. Rails4::Application.initialize! rabl-0.11.4/fixtures/rails4/config/locales/0000755000004100000410000000000012432721713020505 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/config/locales/en.yml0000644000004100000410000000117212432721713021633 0ustar www-datawww-data# Files in the config/locales directory are used for internationalization # and are automatically loaded by Rails. If you want to use locales other # than English, add the necessary files in this directory. # # To use the locales, use `I18n.t`: # # I18n.t 'hello' # # In views, this is aliased to just `t`: # # <%= t('hello') %> # # To use a different locale, set it with `I18n.locale`: # # I18n.locale = :es # # This would use the information in config/locales/es.yml. # # To learn more, please read the Rails Internationalization guide # available at http://guides.rubyonrails.org/i18n.html. en: hello: "Hello world" rabl-0.11.4/fixtures/rails4/app/0000755000004100000410000000000012432721713016376 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/app/controllers/0000755000004100000410000000000012432721713020744 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/app/controllers/posts_controller.rb0000644000004100000410000000057112432721713024707 0ustar www-datawww-dataclass PostsController < ApplicationController respond_to :json, :xml, :html, :rabl_test_v1 def index @posts = Post.order('id ASC').load end def show @post = Post.find(params[:id]) end def renderer post = Post.find(params[:id]) render json: Rabl.render(post, 'posts/renderer', view_path: 'app/views', format: :json, scope: view_context) end end rabl-0.11.4/fixtures/rails4/app/controllers/users_controller.rb0000644000004100000410000000027212432721713024676 0ustar www-datawww-dataclass UsersController < ApplicationController respond_to :json def index @users = User.order('username ASC').load end def show @user = User.find(params[:id]) end end rabl-0.11.4/fixtures/rails4/app/controllers/concerns/0000755000004100000410000000000012432721713022556 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/app/controllers/concerns/.keep0000644000004100000410000000000012432721713023471 0ustar www-datawww-datarabl-0.11.4/fixtures/rails4/app/controllers/application_controller.rb0000644000004100000410000000031412432721713026035 0ustar www-datawww-dataclass ApplicationController < ActionController::Base # Prevent CSRF attacks by raising an exception. # For APIs, you may want to use :null_session instead. protect_from_forgery with: :exception end rabl-0.11.4/fixtures/rails4/app/mailers/0000755000004100000410000000000012432721713020032 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/app/mailers/.keep0000644000004100000410000000000012432721713020745 0ustar www-datawww-datarabl-0.11.4/fixtures/rails4/app/assets/0000755000004100000410000000000012432721713017700 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/app/assets/javascripts/0000755000004100000410000000000012432721713022231 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/app/assets/javascripts/application.js0000644000004100000410000000122412432721713025071 0ustar www-datawww-data// This is a manifest file that'll be compiled into application.js, which will include all the files // listed below. // // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path. // // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the // compiled file. // // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD // GO AFTER THE REQUIRES BELOW. // //= require jquery //= require jquery_ujs //= require turbolinks //= require_tree . rabl-0.11.4/fixtures/rails4/app/assets/stylesheets/0000755000004100000410000000000012432721713022254 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/app/assets/stylesheets/application.css0000644000004100000410000000104212432721713025266 0ustar www-datawww-data/* * This is a manifest file that'll be compiled into application.css, which will include all the files * listed below. * * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path. * * You're free to add application-wide styles to this file and they'll appear at the top of the * compiled file, but it's generally better to create a new file per style scope. * *= require_self *= require_tree . */ rabl-0.11.4/fixtures/rails4/app/helpers/0000755000004100000410000000000012432721713020040 5ustar www-datawww-datarabl-0.11.4/fixtures/rails4/app/helpers/application_helper.rb0000644000004100000410000000007712432721713024233 0ustar www-datawww-datamodule ApplicationHelper def helper_foo "BAR!" end end rabl-0.11.4/fixtures/rails4/config.ru0000644000004100000410000000023212432721713017430 0ustar www-datawww-data# This file is used by Rack-based servers to start the application. require ::File.expand_path('../config/environment', __FILE__) run Rails.application rabl-0.11.4/metadata.yml0000644000004100000410000004215012432721713015054 0ustar www-datawww-data--- !ruby/object:Gem::Specification name: rabl version: !ruby/object:Gem::Version version: 0.11.4 platform: ruby authors: - Nathan Esquenazi autorequire: bindir: bin cert_chain: [] date: 2014-11-08 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: activesupport requirement: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: 2.3.14 type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: 2.3.14 - !ruby/object:Gem::Dependency name: riot requirement: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: 0.12.3 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: 0.12.3 - !ruby/object:Gem::Dependency name: rr requirement: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: 1.0.2 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: 1.0.2 - !ruby/object:Gem::Dependency name: rake requirement: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: tilt requirement: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: oj requirement: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: msgpack requirement: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: 0.4.5 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: 0.4.5 - !ruby/object:Gem::Dependency name: bson requirement: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: 1.7.0 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: 1.7.0 - !ruby/object:Gem::Dependency name: plist requirement: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: '0' description: General ruby templating with json, bson, xml and msgpack support email: - nesquena@gmail.com executables: [] extensions: [] extra_rdoc_files: [] files: - .gitignore - .travis.yml - CHANGELOG.md - CONTRIBUTING.md - Gemfile - Gemfile.ci - MIT-LICENSE - README.md - Rakefile - examples/base.json.rabl - examples/demo.json.rabl - examples/inherited.json.rabl - fixtures/ashared/NOTES - fixtures/ashared/README - fixtures/ashared/migrate/20111002092016_create_users.rb - fixtures/ashared/migrate/20111002092019_create_posts.rb - fixtures/ashared/migrate/20111002092024_create_phone_numbers.rb - fixtures/ashared/models/phone_number.rb - fixtures/ashared/models/post.rb - fixtures/ashared/models/user.rb - fixtures/ashared/views/layouts/application.html.erb - fixtures/ashared/views/posts/_show_footer_script.js.erb - fixtures/ashared/views/posts/date.rabl - fixtures/ashared/views/posts/index.rabl - fixtures/ashared/views/posts/show.rabl - fixtures/ashared/views/users/index.json.rabl - fixtures/ashared/views/users/phone_number.json.rabl - fixtures/ashared/views/users/show.json.rabl - fixtures/ashared/views_rails_3/layouts/application.html.erb - fixtures/ashared/views_rails_3/posts/_show_footer_script.js.erb - fixtures/ashared/views_rails_3/posts/date.rabl - fixtures/ashared/views_rails_3/posts/index.html.erb - fixtures/ashared/views_rails_3/posts/index.rabl - fixtures/ashared/views_rails_3/posts/renderer.rabl - fixtures/ashared/views_rails_3/posts/renderer_partial.rabl - fixtures/ashared/views_rails_3/posts/show.html.erb - fixtures/ashared/views_rails_3/posts/show.rabl - fixtures/ashared/views_rails_3/posts/show.rabl_test_v1.rabl - fixtures/ashared/views_rails_3/users/index.json.rabl - fixtures/ashared/views_rails_3/users/phone_number.json.rabl - fixtures/ashared/views_rails_3/users/phone_number.xml.rabl - fixtures/ashared/views_rails_3/users/show.json.rabl - fixtures/ashared/views_rails_3/users/show.rabl_test_v1.rabl - fixtures/padrino_test/.components - fixtures/padrino_test/.gitignore - fixtures/padrino_test/Gemfile - fixtures/padrino_test/Rakefile - fixtures/padrino_test/app/app.rb - fixtures/padrino_test/app/controllers/posts.rb - fixtures/padrino_test/app/controllers/users.rb - fixtures/padrino_test/app/helpers/posts_helper.rb - fixtures/padrino_test/app/helpers/users_helper.rb - fixtures/padrino_test/config.ru - fixtures/padrino_test/config/apps.rb - fixtures/padrino_test/config/boot.rb - fixtures/padrino_test/config/database.rb - fixtures/padrino_test/db/schema.rb - fixtures/padrino_test/public/favicon.ico - fixtures/padrino_test/test/app/controllers/posts_controller_test.rb - fixtures/padrino_test/test/app/controllers/users_controller_test.rb - fixtures/padrino_test/test/test.rake - fixtures/padrino_test/test/test_config.rb - fixtures/rails2/.gitignore - fixtures/rails2/Gemfile - fixtures/rails2/Rakefile - fixtures/rails2/app/controllers/application_controller.rb - fixtures/rails2/app/controllers/posts_controller.rb - fixtures/rails2/app/controllers/users_controller.rb - fixtures/rails2/app/helpers/application_helper.rb - fixtures/rails2/app/helpers/posts_helper.rb - fixtures/rails2/app/helpers/users_helper.rb - fixtures/rails2/config/boot.rb - fixtures/rails2/config/database.yml - fixtures/rails2/config/environment.rb - fixtures/rails2/config/environments/development.rb - fixtures/rails2/config/environments/production.rb - fixtures/rails2/config/environments/test.rb - fixtures/rails2/config/initializers/backtrace_silencers.rb - fixtures/rails2/config/initializers/cookie_verification_secret.rb - fixtures/rails2/config/initializers/inflections.rb - fixtures/rails2/config/initializers/mime_types.rb - fixtures/rails2/config/initializers/new_rails_defaults.rb - fixtures/rails2/config/initializers/session_store.rb - fixtures/rails2/config/locales/en.yml - fixtures/rails2/config/preinitializer.rb - fixtures/rails2/config/routes.rb - fixtures/rails2/db/schema.rb - fixtures/rails2/db/seeds.rb - fixtures/rails2/public/404.html - fixtures/rails2/public/422.html - fixtures/rails2/public/500.html - fixtures/rails2/public/favicon.ico - fixtures/rails2/public/images/rails.png - fixtures/rails2/public/index.html - fixtures/rails2/public/robots.txt - fixtures/rails2/script/about - fixtures/rails2/script/console - fixtures/rails2/script/dbconsole - fixtures/rails2/script/destroy - fixtures/rails2/script/generate - fixtures/rails2/script/performance/benchmarker - fixtures/rails2/script/performance/profiler - fixtures/rails2/script/plugin - fixtures/rails2/script/runner - fixtures/rails2/script/server - fixtures/rails2/test/functionals/posts_controller_test.rb - fixtures/rails2/test/functionals/users_controller_test.rb - fixtures/rails2/test/test_helper.rb - fixtures/rails3/.gitignore - fixtures/rails3/Gemfile - fixtures/rails3/Rakefile - fixtures/rails3/app/controllers/application_controller.rb - fixtures/rails3/app/controllers/posts_controller.rb - fixtures/rails3/app/controllers/users_controller.rb - fixtures/rails3/config.ru - fixtures/rails3/config/application.rb - fixtures/rails3/config/boot.rb - fixtures/rails3/config/database.yml - fixtures/rails3/config/environment.rb - fixtures/rails3/config/environments/development.rb - fixtures/rails3/config/environments/production.rb - fixtures/rails3/config/environments/test.rb - fixtures/rails3/config/initializers/backtrace_silencers.rb - fixtures/rails3/config/initializers/inflections.rb - fixtures/rails3/config/initializers/mime_types.rb - fixtures/rails3/config/initializers/secret_token.rb - fixtures/rails3/config/initializers/session_store.rb - fixtures/rails3/config/locales/en.yml - fixtures/rails3/config/routes.rb - fixtures/rails3/db/seeds.rb - fixtures/rails3/lib/tasks/.gitkeep - fixtures/rails3/public/404.html - fixtures/rails3/public/422.html - fixtures/rails3/public/500.html - fixtures/rails3/public/favicon.ico - fixtures/rails3/public/images/rails.png - fixtures/rails3/public/index.html - fixtures/rails3/public/robots.txt - fixtures/rails3/public/stylesheets/.gitkeep - fixtures/rails3/script/rails - fixtures/rails3/test/functional/posts_controller_test.rb - fixtures/rails3/test/functional/users_controller_test.rb - fixtures/rails3/test/test_helper.rb - fixtures/rails3_2/.gitignore - fixtures/rails3_2/Gemfile - fixtures/rails3_2/README.rdoc - fixtures/rails3_2/Rakefile - fixtures/rails3_2/app/assets/images/rails.png - fixtures/rails3_2/app/assets/javascripts/application.js - fixtures/rails3_2/app/assets/javascripts/posts.js.coffee - fixtures/rails3_2/app/assets/javascripts/users.js.coffee - fixtures/rails3_2/app/assets/stylesheets/application.css - fixtures/rails3_2/app/assets/stylesheets/posts.css.scss - fixtures/rails3_2/app/assets/stylesheets/users.css.scss - fixtures/rails3_2/app/controllers/application_controller.rb - fixtures/rails3_2/app/controllers/posts_controller.rb - fixtures/rails3_2/app/controllers/users_controller.rb - fixtures/rails3_2/app/helpers/application_helper.rb - fixtures/rails3_2/app/helpers/posts_helper.rb - fixtures/rails3_2/app/helpers/users_helper.rb - fixtures/rails3_2/app/mailers/.gitkeep - fixtures/rails3_2/config.ru - fixtures/rails3_2/config/application.rb - fixtures/rails3_2/config/boot.rb - fixtures/rails3_2/config/database.yml - fixtures/rails3_2/config/environment.rb - fixtures/rails3_2/config/environments/development.rb - fixtures/rails3_2/config/environments/production.rb - fixtures/rails3_2/config/environments/test.rb - fixtures/rails3_2/config/initializers/backtrace_silencers.rb - fixtures/rails3_2/config/initializers/inflections.rb - fixtures/rails3_2/config/initializers/mime_types.rb - fixtures/rails3_2/config/initializers/secret_token.rb - fixtures/rails3_2/config/initializers/session_store.rb - fixtures/rails3_2/config/initializers/wrap_parameters.rb - fixtures/rails3_2/config/locales/en.yml - fixtures/rails3_2/config/routes.rb - fixtures/rails3_2/db/schema.rb - fixtures/rails3_2/db/seeds.rb - fixtures/rails3_2/doc/README_FOR_APP - fixtures/rails3_2/lib/assets/.gitkeep - fixtures/rails3_2/lib/tasks/.gitkeep - fixtures/rails3_2/log/.gitkeep - fixtures/rails3_2/public/404.html - fixtures/rails3_2/public/422.html - fixtures/rails3_2/public/500.html - fixtures/rails3_2/public/favicon.ico - fixtures/rails3_2/public/index.html - fixtures/rails3_2/public/robots.txt - fixtures/rails3_2/script/rails - fixtures/rails3_2/test/fixtures/phone_numbers.yml - fixtures/rails3_2/test/fixtures/posts.yml - fixtures/rails3_2/test/fixtures/users.yml - fixtures/rails3_2/test/functional/posts_controller_test.rb - fixtures/rails3_2/test/functional/users_controller_test.rb - fixtures/rails3_2/test/integration/.gitkeep - fixtures/rails3_2/test/performance/browsing_test.rb - fixtures/rails3_2/test/test_helper.rb - fixtures/rails3_2/test/unit/helpers/posts_helper_test.rb - fixtures/rails3_2/test/unit/helpers/users_helper_test.rb - fixtures/rails3_2/test/unit/phone_number_test.rb - fixtures/rails3_2/test/unit/post_test.rb - fixtures/rails3_2/test/unit/user_test.rb - fixtures/rails3_2/vendor/assets/javascripts/.gitkeep - fixtures/rails3_2/vendor/assets/stylesheets/.gitkeep - fixtures/rails3_2/vendor/plugins/.gitkeep - fixtures/rails4/.gitignore - fixtures/rails4/Gemfile - fixtures/rails4/README.rdoc - fixtures/rails4/Rakefile - fixtures/rails4/app/assets/javascripts/application.js - fixtures/rails4/app/assets/stylesheets/application.css - fixtures/rails4/app/controllers/application_controller.rb - fixtures/rails4/app/controllers/concerns/.keep - fixtures/rails4/app/controllers/posts_controller.rb - fixtures/rails4/app/controllers/users_controller.rb - fixtures/rails4/app/helpers/application_helper.rb - fixtures/rails4/app/mailers/.keep - fixtures/rails4/bin/bundle - fixtures/rails4/bin/rails - fixtures/rails4/bin/rake - fixtures/rails4/config.ru - fixtures/rails4/config/application.rb - fixtures/rails4/config/boot.rb - fixtures/rails4/config/database.yml - fixtures/rails4/config/environment.rb - fixtures/rails4/config/environments/development.rb - fixtures/rails4/config/environments/production.rb - fixtures/rails4/config/environments/test.rb - fixtures/rails4/config/initializers/backtrace_silencers.rb - fixtures/rails4/config/initializers/filter_parameter_logging.rb - fixtures/rails4/config/initializers/inflections.rb - fixtures/rails4/config/initializers/mime_types.rb - fixtures/rails4/config/initializers/secret_token.rb - fixtures/rails4/config/initializers/session_store.rb - fixtures/rails4/config/initializers/wrap_parameters.rb - fixtures/rails4/config/locales/en.yml - fixtures/rails4/config/routes.rb - fixtures/rails4/db/seeds.rb - fixtures/rails4/lib/assets/.keep - fixtures/rails4/lib/tasks/.keep - fixtures/rails4/log/.keep - fixtures/rails4/public/404.html - fixtures/rails4/public/422.html - fixtures/rails4/public/500.html - fixtures/rails4/public/favicon.ico - fixtures/rails4/public/robots.txt - fixtures/rails4/test/controllers/.keep - fixtures/rails4/test/fixtures/.keep - fixtures/rails4/test/functional/posts_controller_test.rb - fixtures/rails4/test/functional/users_controller_test.rb - fixtures/rails4/test/helpers/.keep - fixtures/rails4/test/integration/.keep - fixtures/rails4/test/mailers/.keep - fixtures/rails4/test/models/.keep - fixtures/rails4/test/test_helper.rb - fixtures/rails4/vendor/assets/javascripts/.keep - fixtures/rails4/vendor/assets/stylesheets/.keep - fixtures/sinatra_test/Gemfile - fixtures/sinatra_test/Rakefile - fixtures/sinatra_test/app.rb - fixtures/sinatra_test/config.ru - fixtures/sinatra_test/test/functional/posts_controller_test.rb - fixtures/sinatra_test/test/functional/users_controller_test.rb - fixtures/sinatra_test/test/test_helper.rb - lib/rabl.rb - lib/rabl/builder.rb - lib/rabl/cache_engine.rb - lib/rabl/configuration.rb - lib/rabl/digestor.rb - lib/rabl/engine.rb - lib/rabl/helpers.rb - lib/rabl/multi_builder.rb - lib/rabl/partials.rb - lib/rabl/railtie.rb - lib/rabl/renderer.rb - lib/rabl/sources.rb - lib/rabl/template.rb - lib/rabl/tracker.rb - lib/rabl/version.rb - rabl.gemspec - test.watchr - test/bson_engine_test.rb - test/builder_test.rb - test/configuration_test.rb - test/engine_test.rb - test/helpers_test.rb - test/integration/posts_controller_test.rb - test/integration/rails3_2/posts_controller_test.rb - test/integration/rails3_2/users_controller_test.rb - test/integration/rails4/posts_controller_test.rb - test/integration/rails4/users_controller_test.rb - test/integration/test_init.rb - test/integration/users_controller_test.rb - test/models/ormless.rb - test/models/user.rb - test/msgpack_engine_test.rb - test/multi_builder_test.rb - test/partials_test.rb - test/plist_engine_test.rb - test/renderer_test.rb - test/silence.rb - test/template_test.rb - test/teststrap.rb - test/xml_test.rb homepage: https://github.com/nesquena/rabl licenses: - MIT metadata: {} post_install_message: rdoc_options: [] require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: '0' required_rubygems_version: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: rabl rubygems_version: 2.0.6 signing_key: specification_version: 4 summary: General ruby templating with json, bson, xml and msgpack support test_files: - test/bson_engine_test.rb - test/builder_test.rb - test/configuration_test.rb - test/engine_test.rb - test/helpers_test.rb - test/integration/posts_controller_test.rb - test/integration/rails3_2/posts_controller_test.rb - test/integration/rails3_2/users_controller_test.rb - test/integration/rails4/posts_controller_test.rb - test/integration/rails4/users_controller_test.rb - test/integration/test_init.rb - test/integration/users_controller_test.rb - test/models/ormless.rb - test/models/user.rb - test/msgpack_engine_test.rb - test/multi_builder_test.rb - test/partials_test.rb - test/plist_engine_test.rb - test/renderer_test.rb - test/silence.rb - test/template_test.rb - test/teststrap.rb - test/xml_test.rb has_rdoc: rabl-0.11.4/test/0000755000004100000410000000000012432721713013526 5ustar www-datawww-datarabl-0.11.4/test/bson_engine_test.rb0000644000004100000410000002615312432721713017407 0ustar www-datawww-datarequire File.expand_path('../teststrap', __FILE__) require 'rabl/template' context "Rabl::Engine" do helper(:rabl) { |t| RablTemplate.new("code", :format => 'bson') { t } } context "with bson defaults" do setup do Rabl.configure do |config| # Comment this line out because include_bson_root is default. #config.include_bson_root = true end end context "#object" do asserts "that it sets data source" do template = rabl %q{ object @user } scope = Object.new scope.instance_variable_set :@user, User.new template.render(scope) end.matches "\x10\x00\x00\x00\x03user\x00\x05\x00\x00\x00\x00\x00" asserts "that it can set root node" do template = rabl %q{ object @user => :person } scope = Object.new scope.instance_variable_set :@user, User.new template.render(scope).split("").sort end.equals "\x12\x00\x00\x00\x03person\x00\x05\x00\x00\x00\x00\x00".split("").sort end context "#collection" do asserts "that it sets object to be casted as a simple array" do template = rabl %{ collection @users } scope = Object.new scope.instance_variable_set :@users, [User.new, User.new] template.render(scope).split("").sort end.equals "7\x00\x00\x00\x04users\x00+\x00\x00\x00\x030\x00\x10\x00\x00\x00\x03user\x00\x05\x00\x00\x00\x00\x00\x031\x00\x10\x00\x00\x00\x03user\x00\x05\x00\x00\x00\x00\x00\x00\x00".split("").sort asserts "that it sets root node for objects" do template = rabl %{ collection @users => :people } scope = Object.new scope.instance_variable_set :@users, [User.new, User.new] template.render(scope).split("").sort end.equals "<\x00\x00\x00\x04people\x00/\x00\x00\x00\x030\x00\x12\x00\x00\x00\x03person\x00\x05\x00\x00\x00\x00\x00\x031\x00\x12\x00\x00\x00\x03person\x00\x05\x00\x00\x00\x00\x00\x00\x00".split("").sort end context "#attribute" do asserts "that it adds an attribute or method to be included in output" do template = rabl %{ object @user attribute :name } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') template.render(scope).split("").sort end.equals "!\x00\x00\x00\x03user\x00\x16\x00\x00\x00\x02name\x00\a\x00\x00\x00irvine\x00\x00\x00".split("").sort asserts "that it can add attribute under a different key name through :as" do template = rabl %{ object @user attribute :name, :as => 'city' } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') template.render(scope).split("").sort end.equals "!\x00\x00\x00\x03user\x00\x16\x00\x00\x00\x02city\x00\a\x00\x00\x00irvine\x00\x00\x00".split("").sort asserts "that it can add attribute under a different key name through hash" do template = rabl %{ object @user attribute :name => :city } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') template.render(scope).split("").sort end.equals "!\x00\x00\x00\x03user\x00\x16\x00\x00\x00\x02city\x00\a\x00\x00\x00irvine\x00\x00\x00".split("").sort end context "#code" do asserts "that it can create an arbitraty code node" do template = rabl %{ code(:foo) { 'bar' } } template.render(Object.new).split("").sort end.equals "\x12\x00\x00\x00\x02foo\x00\x04\x00\x00\x00bar\x00\x00".split("").sort asserts "that it can be passed conditionals" do template = rabl %{ code(:foo, :if => lambda { |i| false }) { 'bar' } } template.render(Object.new).split("").sort end.equals "\x05\x00\x00\x00\x00".split("").sort end context "#child" do asserts "that it can create a child node" do template = rabl %{ object @user attribute :name child(@user) { attribute :city } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA') template.render(scope).split("").sort end.equals "6\x00\x00\x00\x03user\x00+\x00\x00\x00\x02name\x00\x04\x00\x00\x00leo\x00\x03user\x00\x12\x00\x00\x00\x02city\x00\x03\x00\x00\x00LA\x00\x00\x00\x00".split("").sort asserts "that it can create a child node with different key" do template = rabl %{ object @user attribute :name child(@user => :person) { attribute :city } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA') template.render(scope).split("").sort end.equals "8\x00\x00\x00\x03user\x00-\x00\x00\x00\x02name\x00\x04\x00\x00\x00leo\x00\x03person\x00\x12\x00\x00\x00\x02city\x00\x03\x00\x00\x00LA\x00\x00\x00\x00".split("").sort end context "#glue" do asserts "that it glues data from a child node" do template = rabl %{ object @user attribute :name glue(@user) { attribute :city } glue(@user) { attribute :age } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA', :age => 12) template.render(scope).split("").sort end.equals "4\x00\x00\x00\x03user\x00)\x00\x00\x00\x02name\x00\x04\x00\x00\x00leo\x00\x02city\x00\x03\x00\x00\x00LA\x00\x10age\x00\f\x00\x00\x00\x00\x00".split("").sort end teardown do Rabl.reset_configuration! end end context "with bson_engine" do setup do class CustomEncodeEngine def self.serialize string 42 end end Rabl.configure do |config| config.bson_engine = CustomEncodeEngine end end asserts 'that it returns process by custom to_json' do template = rabl %q{ object @user } scope = Object.new scope.instance_variable_set :@user, User.new template.render(scope) end.equals "42" teardown do Rabl.reset_configuration! end end context "without bson root" do setup do Rabl.configure do |config| config.include_bson_root = false end end context "#object" do asserts "that it sets data source" do template = rabl %q{ object @user } scope = Object.new scope.instance_variable_set :@user, User.new template.render(scope) end.matches "\x05\x00\x00\x00\x00" asserts "that it can set root node" do template = rabl %q{ object @user => :person } scope = Object.new scope.instance_variable_set :@user, User.new template.render(scope) end.equals "\x05\x00\x00\x00\x00" end context "#collection" do asserts "that it sets object to be casted as a simple array" do template = rabl %{ collection @users } scope = Object.new scope.instance_variable_set :@users, [User.new, User.new] template.render(scope).split("").sort end.equals "!\x00\x00\x00\x04users\x00\x15\x00\x00\x00\x030\x00\x05\x00\x00\x00\x00\x031\x00\x05\x00\x00\x00\x00\x00\x00".split("").sort asserts "that it sets root node for objects" do template = rabl %{ collection @users => :person } scope = Object.new scope.instance_variable_set :@users, [User.new, User.new] template.render(scope).split("").sort end.equals "\"\x00\x00\x00\x04person\x00\x15\x00\x00\x00\x030\x00\x05\x00\x00\x00\x00\x031\x00\x05\x00\x00\x00\x00\x00\x00".split("").sort end context "#attribute" do asserts "that it adds an attribute or method to be included in output" do template = rabl %{ object @user attribute :name } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') template.render(scope).split("").sort end.equals "\x16\x00\x00\x00\x02name\x00\a\x00\x00\x00irvine\x00\x00".split("").sort asserts "that it can add attribute under a different key name through :as" do template = rabl %{ object @user attribute :name, :as => 'city' } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') template.render(scope).split("").sort end.equals "\x16\x00\x00\x00\x02city\x00\a\x00\x00\x00irvine\x00\x00".split("").sort asserts "that it can add attribute under a different key name through hash" do template = rabl %{ object @user attribute :name => :city } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') template.render(scope).split("").sort end.equals "\x16\x00\x00\x00\x02city\x00\a\x00\x00\x00irvine\x00\x00".split("").sort end context "#code" do asserts "that it can create an arbitraty code node" do template = rabl %{ code(:foo) { 'bar' } } template.render(Object.new).split("").sort end.equals "\x12\x00\x00\x00\x02foo\x00\x04\x00\x00\x00bar\x00\x00".split("").sort asserts "that it can be passed conditionals" do template = rabl %{ code(:foo, :if => lambda { |i| false }) { 'bar' } } template.render(Object.new).split("").sort end.equals "\x05\x00\x00\x00\x00".split("").sort end context "#child" do asserts "that it can create a child node" do template = rabl %{ object @user attribute :name child(@user) { attribute :city } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA') template.render(scope).split("").sort end.equals "+\x00\x00\x00\x02name\x00\x04\x00\x00\x00leo\x00\x03user\x00\x12\x00\x00\x00\x02city\x00\x03\x00\x00\x00LA\x00\x00\x00".split("").sort asserts "that it can create a child node with different key" do template = rabl %{ object @user attribute :name child(@user => :person) { attribute :city } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA') template.render(scope).split("").sort end.equals "-\x00\x00\x00\x02name\x00\x04\x00\x00\x00leo\x00\x03person\x00\x12\x00\x00\x00\x02city\x00\x03\x00\x00\x00LA\x00\x00\x00".split("").sort end context "#glue" do asserts "that it glues data from a child node" do template = rabl %{ object @user attribute :name glue(@user) { attribute :city } glue(@user) { attribute :age } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA', :age => 12) template.render(scope).split("").sort end.equals ")\x00\x00\x00\x02name\x00\x04\x00\x00\x00leo\x00\x02city\x00\x03\x00\x00\x00LA\x00\x10age\x00\f\x00\x00\x00\x00".split("").sort end teardown do Rabl.reset_configuration! end end end rabl-0.11.4/test/renderer_test.rb0000644000004100000410000002747012432721713016732 0ustar www-datawww-datarequire 'tmpdir' require 'pathname' require 'json' require File.expand_path('../teststrap', __FILE__) context "Rabl::Renderer" do helper(:tmp_path) { @tmp_path ||= Pathname.new(Dir.mktmpdir) } # context_scope 'users', [@user] helper(:context_scope) { |name, value| scope = Object.new stub(scope).controller { stub(Object).controller_name { name } } scope.instance_variable_set :"@#{name.pluralize}", nil scope.instance_variable_set :"@#{name}", value scope } context "#render" do asserts 'renders empty array' do source = %q{ collection @users attribute :name, :as => 'city' } scope = Object.new scope.instance_variable_set :@users, [] renderer = Rabl::Renderer.new(source, [], { :format => 'json', :root => true, :view_path => '/path/to/views', :scope => scope }) renderer.render end.equals "[]" asserts 'renders string as source' do source = %q{ object @user attribute :name, :as => 'city' } user = User.new(:name => 'irvine') renderer = Rabl::Renderer.new(source, user, { :format => 'json', :root => true, :view_path => '/path/to/views' }) JSON.parse(renderer.render) end.equals JSON.parse("{\"user\":{\"city\":\"irvine\"}}") asserts 'allows redirecting scope to another object' do source = %q{ object @user attribute :name, :as => 'city' } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') renderer = Rabl::Renderer.new(source, nil, { :format => 'json', :scope => scope }) JSON.parse(renderer.render) end.equals JSON.parse("{\"user\":{\"city\":\"irvine\"}}") asserts 'accepts scope on render' do source = %q{ object @user attribute :name, :as => 'city' } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') renderer = Rabl::Renderer.new(source) JSON.parse(renderer.render(scope)) end.equals JSON.parse("{\"user\":{\"city\":\"irvine\"}}") asserts 'passes :locals to render' do source = %q{ attribute :name, :as => 'city' node(:zipcode) { @zipcode } } user = User.new(:name => 'irvine') renderer = Rabl::Renderer.new(source, nil, { :format => 'json', :locals => {:object => user, :zipcode => "92602"} }) JSON.parse(renderer.render) end.equals JSON.parse("{\"user\":{\"city\":\"irvine\",\"zipcode\":\"92602\"}}") asserts 'loads source from file' do File.open(tmp_path + "test.json.rabl", "w") do |f| f.puts %q{ object @user attributes :age, :name } end user = User.new(:name => 'irvine') renderer = Rabl::Renderer.new('test', user, :view_path => tmp_path) JSON.parse(renderer.render) end.equals JSON.parse("{\"user\":{\"age\":24,\"name\":\"irvine\"}}") asserts 'uses globally configured view paths' do Rabl.configure do |config| config.view_paths << tmp_path end File.open(tmp_path + "test.rabl", "w") do |f| f.puts %q{ attributes :age } end user = User.new(:name => 'irvine') renderer = Rabl::Renderer.new('test', user) JSON.parse(renderer.render) end.equals JSON.parse("{\"user\":{\"age\":24,\"name\":\"irvine\"}}") asserts 'handles paths for extends' do File.open(tmp_path + "test.json.rabl", "w") do |f| f.puts %q{ attributes :age } end File.open(tmp_path + "user.json.rabl", "w") do |f| f.puts %( object @user attribute :name extends 'test' ) end user = User.new(:name => 'irvine') renderer = Rabl::Renderer.new('user', user, :view_path => tmp_path) JSON.parse(renderer.render) end.equals JSON.parse("{\"user\":{\"age\":24,\"name\":\"irvine\"}}") asserts 'handles extends with child as nil' do File.open(tmp_path + "foo.json.rabl", "w") do |f| f.puts %q{ object @foo node(:test) do |foo| { test: "#{foo.attribute}" } end } end File.open(tmp_path + "bar.json.rabl", "w") do |f| f.puts %q{ object false node do { test_attribute: 'test_value' } end child(@foos => :foo_collection) do extends 'foo' end } end sc = Object.new sc.instance_variable_set :@foos, nil renderer = Rabl::Renderer.new('bar', false, :view_path => tmp_path, :scope => sc) JSON.parse(renderer.render) end.equals JSON.parse("{\"test_attribute\":\"test_value\", \"foo_collection\":null}") asserts 'handles extends with custom node and object set false' do File.open(tmp_path + "test.json.rabl", "w") do |f| f.puts %q{ node(:foo) { 'baz' } } end File.open(tmp_path + "user.json.rabl", "w") do |f| f.puts %( object false node(:baz) { "bar" } extends 'test' ) end scope = context_scope('users', [User.new, User.new, User.new]) renderer = Rabl::Renderer.new('user', false, :view_path => tmp_path, :scope => scope) JSON.parse(renderer.render) end.equals(JSON.parse(%Q^{"foo":"baz", "baz":"bar" }^)) asserts 'handles extends with attributes and object set false' do File.open(tmp_path + "test.json.rabl", "w") do |f| f.puts %q{ attributes :foo, :bar, :baz node(:test) { |bar| bar.demo if bar } } end File.open(tmp_path + "user.json.rabl", "w") do |f| f.puts %( object false extends 'test' ) end renderer = Rabl::Renderer.new('user', false, :view_path => tmp_path) JSON.parse(renderer.render) end.equals(JSON.parse(%Q^{"test": null}^)) # FIXME template is found and rendered but not included in final results # asserts 'handles paths for partial' do # File.open(tmp_path + "test.json.rabl", "w") do |f| # f.puts %q{ # attributes :age # } # end # File.open(tmp_path + "user.json.rabl", "w") do |f| # f.puts %( # object @user # attribute :name # partial 'test', :object => @user # ) # end # user = User.new(:name => 'irvine') # renderer = Rabl::Renderer.new('user', user, :view_path => tmp_path) # JSON.parse(renderer.render) # end.equals JSON.parse("{\"user\":{\"age\":24,\"name\":\"irvine\"}}") asserts 'Rabl.render calls Renderer' do File.open(tmp_path + "test.json.rabl", "w") do |f| f.puts %q{ object @user attributes :age, :name } end user = User.new(:name => 'irvine') JSON.parse(Rabl.render(user, 'test', :view_path => tmp_path)) end.equals JSON.parse("{\"user\":{\"age\":24,\"name\":\"irvine\"}}") asserts 'it renders collections' do File.open(tmp_path + "test.json.rabl", "w") do |f| f.puts %q{ collection @users => :users attributes :age, :name } end sc = Object.new sc.instance_variable_set :@users, nil Rabl.render([], 'test', :view_path => tmp_path, :scope => sc) end.equals "{\"users\":[]}" asserts 'it renders an array when given an empty collection' do File.open(tmp_path + "test.json.rabl", "w") do |f| f.puts %q{ collection @users attribute :name, :age } end scope = Object.new scope.instance_variable_set :@users, nil Rabl.render([], 'test', :view_path => tmp_path, :root => false, :scope => scope) end.equals "[]" asserts 'handles view path for when it specified and config is empty' do Rabl.configuration.view_paths = [] File.open(tmp_path + "profile.json.rabl", "w") do |f| f.puts %q{ attributes :gender } end File.open(tmp_path + "user.json.rabl", "w") do |f| f.puts %( object @user attribute :name glue(:profile) do extends 'profile' end child(:profile) do extends 'profile' end ) end user = User.new(:name => 'irvine') stub(user).profile { stub!.gender { "male" } } renderer = Rabl::Renderer.new('user', user, :view_path => tmp_path) JSON.parse(renderer.render) end.equals JSON.parse("{\"user\":{\"name\":\"irvine\",\"object\":{\"gender\":\"male\"},\"gender\":\"male\"}}") asserts "it renders for object false" do File.open(tmp_path + "test2.rabl", "w") do |f| f.puts %q{ object false node(:foo) { 'bar' } } end user = User.new(:name => 'ivan') JSON.parse(Rabl.render(user, 'test2', :view_path => tmp_path)) end.equals JSON.parse("{\"foo\":\"bar\"}") asserts "it renders for object key specified in template" do File.open(tmp_path + "test3.rabl", "w") do |f| f.puts %q{ object @user => :person attributes :age, :name } end user = User.new(:name => 'ivan') JSON.parse(Rabl.render(user, 'test3', :view_path => tmp_path)) end.equals JSON.parse("{\"person\":{\"age\":24,\"name\":\"ivan\"} }") asserts "it renders for overwriting object key specified in render" do File.open(tmp_path + "test4.rabl", "w") do |f| f.puts %q{ object @user => :person attributes :age, :name } end sc = Object.new sc.instance_variable_set :@user, nil user = User.new(:name => 'ivan') JSON.parse(Rabl.render({ user => :human }, 'test4', :view_path => tmp_path, :scope => sc)) end.equals JSON.parse("{\"human\":{\"age\":24,\"name\":\"ivan\"} }") asserts "it renders for specific object key passed to render" do File.open(tmp_path + "test5.rabl", "w") do |f| f.puts %q{ object @user attributes :age, :name } end sc = Object.new sc.instance_variable_set :@user, nil user = User.new(:name => 'ivan') JSON.parse(Rabl.render({ user => :person }, 'test5', :view_path => tmp_path, :scope => sc)) end.equals JSON.parse("{\"person\":{\"age\":24,\"name\":\"ivan\"} }") end # render context '.json' do asserts 'it renders json' do File.open(tmp_path + "test.rabl", "w") do |f| f.puts %q{ object @user attributes :age, :name, :float } end user = User.new(:name => 'ivan') JSON.parse(Rabl::Renderer.json(user, 'test', :view_path => tmp_path)) end.equals JSON.parse("{\"user\":{\"age\":24,\"name\":\"ivan\",\"float\":1234.56}}") end # json context '.msgpack' do asserts 'it renders msgpack' do File.open(tmp_path + "test.rabl", "w") do |f| f.puts %q{ object @user attributes :age, :name, :float } end user = User.new(:name => 'ivan') char_split Rabl::Renderer.msgpack(user, 'test', :view_path => tmp_path) end.equals char_split("\x81\xA4user\x83\xA3age\x18\xA4name\xA4ivan\xA5float\xCB@\x93J=p\xA3\xD7\n") end context '.plist' do asserts 'it renders xml' do File.open(tmp_path + "test.rabl", "w") do |f| f.puts %q{ object @user attributes :age, :name, :float } end user = User.new(:name => 'ivan') Rabl::Renderer.plist(user, 'test', :view_path => tmp_path) end.equals "\n\n\n\n\tuser\n\t\n\t\tage\n\t\t24\n\t\tfloat\n\t\t1234.56\n\t\tname\n\t\tivan\n\t\n\n\n" end end rabl-0.11.4/test/partials_test.rb0000644000004100000410000001156312432721713016737 0ustar www-datawww-datarequire 'tmpdir' require 'pathname' require File.expand_path('../teststrap', __FILE__) class TestPartial include Rabl::Partials end context "Rabl::Partials" do context "fetch_source with json" do helper(:tmp_path) { @tmp_path ||= Pathname.new(Dir.mktmpdir) } setup do ::Sinatra = stub(Class.new) File.open(tmp_path + "test.json.rabl", "w") do |f| f.puts "content" end File.open(tmp_path + "test_v1.json.rabl", "w") do |f| f.puts "content_v1" end FileUtils.touch tmp_path + "test_v2.json.rabl" [TestPartial.new.fetch_source('test', :view_path => tmp_path.to_s), TestPartial.new.fetch_source('test_v1', :view_path => tmp_path.to_s)] end asserts(:first).equals {["content\n", (tmp_path + "test.json.rabl").to_s ]} asserts(:last).equals {["content_v1\n", (tmp_path + "test_v1.json.rabl").to_s ]} teardown { Object.send(:remove_const, :Sinatra) } end context "fetch_source with rabl" do helper(:tmp_path) { @tmp_path ||= Pathname.new(Dir.mktmpdir) } setup do ::Sinatra = stub(Class.new) File.open(tmp_path + "test.rabl", "w") do |f| f.puts "content" end TestPartial.new.fetch_source('test', :view_path => tmp_path.to_s) end asserts('detects file.rabl') { topic }.equals do ["content\n", (tmp_path + 'test.rabl').to_s] end teardown { Object.send(:remove_const, :Sinatra) } end context "fetch_source with view_path" do helper(:tmp_path) { @tmp_path ||= Pathname.new(Dir.mktmpdir) } setup do ::Sinatra = stub(Class.new) File.open(tmp_path + "test.rabl", "w") do |f| f.puts "content" end File.open(tmp_path + "test.json.rabl", "w") do |f| f.puts "content2" end TestPartial.new.fetch_source('test', :view_path => tmp_path.to_s) end asserts('detects file.json.rabl first') { topic }.equals do ["content2\n", (tmp_path + 'test.json.rabl').to_s] end teardown { Object.send(:remove_const, :Sinatra) } end context "fetch source using configured view paths" do helper(:tmp_path) { @tmp_path ||= Pathname.new(Dir.mktmpdir) } setup do Rabl.configure do |config| config.view_paths = tmp_path end ::Sinatra = stub(Class.new) File.open(tmp_path + "test.rabl", "w") do |f| f.puts "content" end File.open(tmp_path + "test.json.rabl", "w") do |f| f.puts "content2" end TestPartial.new.fetch_source('test') end asserts('detects file.json.rabl first') { topic }.equals do ["content2\n", (tmp_path + 'test.json.rabl').to_s] end teardown do Object.send(:remove_const, :Sinatra) Rabl.configuration.view_paths = [] end end context "fetch source with custom scope" do context "when Padrino is defined" do helper(:tmp_path) { @tmp_path ||= Pathname.new(Dir.mktmpdir) } setup do ::Padrino = stub(Class.new) Rabl.configuration.cache_sources = false @it = TestPartial.new def @it.context_scope; @context_scope ||= Object.new; end context_scope = @it.context_scope def context_scope.settings; end File.open(tmp_path + "test.json.rabl", "w") { |f| f.puts "content" } end asserts('Padrino constant dont break manual lookup') do @it.fetch_source('test', :view_path => tmp_path.to_s) end.equals do ["content\n", (tmp_path + "test.json.rabl").to_s ] end teardown { Object.send(:remove_const, :Padrino) } end end context "fetch source with Rails" do context "and :view_path" do helper(:tmp_path) { @tmp_path ||= Pathname.new(Dir.mktmpdir) } setup do ::Rails = stub(Class.new) ::ActionPack = Module.new ::ActionPack::VERSION = Module.new ::ActionPack::VERSION::MAJOR = 3 ::ActionPack::VERSION::MINOR = 2 @it = TestPartial.new def @it.context_scope; @context_scope ||= Object.new; end def @it.request_format; :json; end context_scope = @it.context_scope def context_scope.view_paths; []; end def context_scope.lookup_context; @lookup_context ||= Object.new; end lookup_context = context_scope.lookup_context def lookup_context.rendered_format; :json; end def lookup_context.find(*args) raise RuntimeError, 'Something happen with Rails lookup' end File.open(tmp_path + "test.json.rabl", "w") { |f| f.puts "content" } @it end asserts('rails lookups dont break manual') do @it.fetch_source('test', :view_path => tmp_path.to_s) end.equals do ["content\n", (tmp_path + "test.json.rabl").to_s ] end teardown do Object.send(:remove_const, :Rails) Object.send(:remove_const, :ActionPack) Rabl.configuration.view_paths = [] end end end # Rails end # Rabl::Partials rabl-0.11.4/test/builder_test.rb0000644000004100000410000003136012432721713016543 0ustar www-datawww-datarequire File.expand_path('../teststrap', __FILE__) context "Rabl::Builder" do helper(:builder) { |*args| Rabl::Builder.new(*args) } helper(:build_hash) { |*args| builder(*args).to_hash } setup do @users = [User.new, User.new] @user = User.new builder(nil, nil, {:view_path => '/path/to/views'}) end context "#initialize" do asserts_topic.assigns :options asserts_topic.assigns :_view_path end context "#to_hash" do context "when given a simple object" do setup { builder(nil, { :attributes => [ { :name => :name } ] }) } asserts "that the object is set properly" do topic.to_hash(User.new, nil, :root_name => "user") end.equivalent_to({ "user" => { :name => "rabl" } }) end context "when given an object alias" do setup { builder(nil, { :attributes => [ { :name => :name, :options => { :as => :foo } } ] }) } asserts "that the object is set properly" do topic.to_hash(User.new, nil, :root_name => "person") end.equivalent_to({ "person" => { :foo => "rabl" } }) end context "when specified with no root" do setup { builder(nil, { :attributes => [ { :name => :name, :options => { :as => :name } } ] }) } asserts "that the object is set properly" do topic.to_hash(User.new, nil, :root => false) end.equivalent_to({ :name => "rabl" }) end context "when nil values are replaced with empty strings" do setup do Rabl.configuration.replace_nil_values_with_empty_strings = true builder(nil, { :attributes => [ { :name => :name } ], :node => [{ :name => :extra, :options => {}, :block => lambda { |u| { :twitter => u.twitter } } }] }) end asserts "that an empty string is returned as the value" do topic.to_hash(User.new(:name => nil, :twitter => nil)) end.equivalent_to({ :name => '', :extra => { :twitter => '' } }) asserts "that it handles existing non nil values correctly" do topic.to_hash(User.new(:name => 10, :twitter => 'twitter')) end.equivalent_to({ :name => 10, :extra => { :twitter => 'twitter' } }) teardown do Rabl.configuration.replace_nil_values_with_empty_strings = false end end context "when empty string values are replaced with nil values" do setup do Rabl.configuration.replace_empty_string_values_with_nil_values = true builder(nil, { :attributes => [ { :name => :name } ], :node => [{ :name => :extra, :options => {}, :block => lambda { |u| { :twitter => u.twitter } } }] }) end asserts "that nil is returned as the value" do topic.to_hash(User.new(:name => "", :twitter => '')) end.equivalent_to({ :name => nil, :extra => { :twitter => nil } }) asserts "that it handles existing nil values correctly" do topic.to_hash(User.new(:name => nil, :twitter => nil)) end.equivalent_to({ :name => nil, :extra => { :twitter => nil } }) asserts "that it handles existing non nil values correctly" do topic.to_hash(User.new(:name => 10, :twitter => 'twitter')) end.equivalent_to({ :name => 10, :extra => { :twitter => 'twitter' } }) teardown do Rabl.configuration.replace_empty_string_values_with_nil_values = false end end context "when nil values are excluded" do setup do Rabl.configuration.exclude_nil_values = true builder(nil, { :attributes => [ { :name => :name } ] }) end asserts "that an nil attribute is not returned" do topic.to_hash(User.new(:name => nil)) end.equivalent_to({ }) teardown do Rabl.configuration.exclude_nil_values = false end end end context "#attribute" do asserts "that the node" do build_hash @user, :attributes => [ { :name => :name }, { :name => :city, :options => { :as => :city } } ] end.equivalent_to({:name => 'rabl', :city => 'irvine'}) context "that with a non-existent attribute" do context "when non-existent attributes are allowed by the configuration" do setup { stub(Rabl.configuration).raise_on_missing_attribute { false } } asserts "the node" do build_hash @user, :attributes => [ { :name => :fake } ] end.equals({}) end context "when non-existent attributes are forbidden by the configuration" do setup { stub(Rabl.configuration).raise_on_missing_attribute { true } } asserts "the node" do build_hash @user, :attributes => [ { :name => :fake } ] end.raises(RuntimeError) end end context "that with a string key" do setup { builder(nil, { :attributes => [ { :name => "name" } ] }) } asserts "the node name is converted to a symbol" do topic.to_hash(User.new, :name => "user") end.equivalent_to({ :name => "rabl" }) end context "that with the same node names as strings and symbols" do setup { builder(nil, { :attributes => [ { :name => "name" }, { :name => :name } ] }) } asserts "the nodes aren't duplicated" do topic.to_hash(User.new, :name => "user") end.equivalent_to({ :name => "rabl" }) end end context "#node" do asserts "that it has node :foo" do build_hash @user, :node => [{ :name => :foo, :options => {}, :block => lambda { |u| "bar" } }] end.equivalent_to({:foo => 'bar'}) asserts "that using object it has node :boo" do build_hash @user, :node => [ { :name => :foo, :options => {}, :block => lambda { |u| "bar" } }, { :name => :baz, :options => {}, :block => lambda { |u| u.city } } ] end.equivalent_to({:foo => 'bar', :baz => 'irvine'}) asserts "that it converts the node name to a symbol" do build_hash @user, :node => [{ :name => "foo", :options => {}, :block => lambda { |u| "bar" } }] end.equivalent_to({:foo => 'bar'}) asserts "that the same node names as a string and symbol aren't duplicated" do build_hash @user, :node => [ { :name => "foo", :options => {}, :block => lambda { |u| "bar" } }, { :name => :foo, :options => {}, :block => lambda { |u| "bar" } } ] end.equivalent_to({:foo => 'bar'}) end context "#child" do asserts "that it generates if no data present" do builder(nil, :child => []).to_hash(@user) end.equals({}) asserts "that it generates with a hash" do b = builder(nil, :child => [ { :data => { @user => :user }, :options => { }, :block => lambda { |u| attribute :name } } ]) b.to_hash(@user) end.equivalent_to({ :user => { :name => "rabl" } }) asserts "that it generates with a hash alias" do b = builder nil, :child => [{ :data => { @user => :person }, :options => {}, :block => lambda { |u| attribute :name } }] b.to_hash(@user) end.equivalent_to({ :person => { :name => "rabl" } }) asserts "that it generates with an object" do b = builder nil, :child => [{ :data => @user, :options => {}, :block => lambda { |u| attribute :name } }] e = Rabl::Engine.new('') mock(b).data_name(@user) { :user } mock(e).render.returns('xyz') mock(b).object_to_engine(@user, { :root => false }).returns(e).subject b.to_hash(@user) end.equivalent_to({ :user => 'xyz'}) asserts "that it generates with an collection and child_root" do b = builder nil, { :child => [{ :data => @users, :options => {}, :block => lambda { |u| attribute :name } }] }, { :child_root => true } e = Rabl::Engine.new('') mock(b).data_name(@users) { :users } mock(e).render.returns('xyz') mock(b).object_to_engine(@users, { :root => true, :child_root => true }).returns(e).subject b.to_hash(@user) end.equivalent_to({ :users => 'xyz'}) asserts "that it generates with an collection and no child root" do b = builder nil, { :child => [{ :data => @users, :options => {}, :block => lambda { |u| attribute :name } }] }, { :child_root => false } e = Rabl::Engine.new('') mock(b).data_name(@users) { :users } mock(e).render.returns('xyz') mock(b).object_to_engine(@users, { :root => false, :child_root => false }).returns(e).subject b.to_hash(@user) end.equivalent_to({ :users => 'xyz'}) asserts "that it generates with an collection and a specified object_root_name and root" do ops = { :object_root => "person", :root => :people } b = builder nil, { :child => [{ :data => @users, :options => ops, :block => lambda { |u| attribute :name } }] }, { :child_root => true } e = Rabl::Engine.new('') mock(e).render.returns('xyz') mock(b).object_to_engine(@users, { :root => "person", :object_root_name => "person", :child_root => true }).returns(e).subject b.to_hash(@user) end.equivalent_to({ :people => 'xyz'}) asserts "that it converts the child name to a symbol" do b = builder(nil, :child => [ { :data => { @user => "user" }, :options => { }, :block => lambda { |u| attribute :name } } ]) b.to_hash(@user) end.equivalent_to({ :user => { :name => "rabl" } }) asserts "that it does't duplicate childs with the same name as a string and symbol" do b = builder(nil, :child => [ { :data => { @user => "user" }, :options => { }, :block => lambda { |u| attribute :name } }, { :data => { @user => :user }, :options => { }, :block => lambda { |u| attribute :name } } ]) b.to_hash(@user) end.equivalent_to({ :user => { :name => "rabl" } }) end context "#glue" do asserts "that it generates if no data present" do builder(nil, :glue => []).to_hash(@user) end.equals({}) asserts "that it generates the glue attributes" do b = builder nil, :glue => [{ :data => @user, :options => {}, :block => lambda { |u| attribute :name }}] e = Rabl::Engine.new('') mock(e).render.returns({:user => 'xyz'}) mock(b).object_to_engine(@user, { :root => false }).returns(e).subject b.to_hash(@user) end.equivalent_to({ :user => 'xyz' }) asserts "that it appends the glue attributes to result" do b = builder nil, :glue => [{ :data => @user, :options => {}, :block => lambda { |u| attribute :name => :user_name }}] b.to_hash(@user) end.equivalent_to({ :user_name => 'rabl' }) asserts "that it does not generate new attributes if no glue attributes are present" do b = builder nil, :glue => [{ :data => @user, :options => {}, :block => lambda { |u| attribute :name }}] e = Rabl::Engine.new('') mock(e).render.returns({}) mock(b).object_to_engine(@user,{ :root => false }).returns(e).subject b.to_hash(@user) end.equals({}) end context "#extends" do asserts "that it does not generate if no data is present" do b = builder nil, :extends => [{ :file => 'users/show', :options => {}, :block => lambda { |u| attribute :name }}] e = Rabl::Engine.new('users/show') mock(b).partial_as_engine('users/show',{ :object => @user}).returns(e) mock(e).render.returns({}).subject b.to_hash(@user) end.equals({}) asserts "that it generates if data is present" do b = builder nil, :extends => [{ :file => 'users/show', :options => {}, :block => lambda { |u| attribute :name }}] e = Rabl::Engine.new('users/show') mock(b).partial_as_engine('users/show',{ :object => @user}).returns(e) mock(e).render.returns({:user => 'xyz'}).subject b.to_hash(@user) end.equivalent_to({:user => 'xyz'}) asserts "that it generates if local data is present but object is false" do b = builder nil, :extends => [{ :file => 'users/show', :options => { :object => @user }, :block => lambda { |u| attribute :name }}] e = Rabl::Engine.new('users/show') mock(b).partial_as_engine('users/show',{ :object => @user}).returns(e) mock(e).render.returns({:user => 'xyz'}).subject b.to_hash(false) end.equivalent_to({:user => 'xyz'}) end context "#resolve_conditionals" do class ArbObj def cool? false end def smooth? true end end asserts "that it can use symbols on if condition and return false if method returns false" do scope = Rabl::Builder.new(ArbObj.new) scope.send(:resolve_condition, { :if => :cool? }) end.equals(false) asserts "that it can use symbols on if condition and return true if method returns true" do scope = Rabl::Builder.new(ArbObj.new) scope.send :resolve_condition, { :if => :smooth? } end.equals(true) asserts "that it can use symbols as unless condition and return true if method returns false" do scope = Rabl::Builder.new(ArbObj.new) scope.send :resolve_condition, { :unless => :cool? } end.equals(true) asserts "that it can use symbols as unmless condition and return false if method returns true" do scope = Rabl::Builder.new(ArbObj.new) scope.send :resolve_condition, { :unless => :smooth? } end.equals(false) end end rabl-0.11.4/test/multi_builder_test.rb0000644000004100000410000000416412432721713017757 0ustar www-datawww-datarequire 'json' require File.expand_path('../teststrap', __FILE__) require 'rabl/template' require File.expand_path('../models/ormless', __FILE__) context "Rabl::MultiBuilder" do helper(:multi_builder) { |objects, options| Rabl::MultiBuilder.new(objects, options) } helper(:builder) { Rabl::Builder.new(nil, {}) } helper(:engine) { |object| Rabl::Engine.new("").apply(nil, :object => object) } context "#initialize" do setup do Rabl::MultiBuilder.new([], {}) end asserts_topic.assigns :options asserts_topic.assigns :data asserts_topic.assigns :engine_to_builder asserts_topic.assigns :cache_key_to_engine end context "#to_a" do setup do Rabl::MultiBuilder.new([], {}) end asserts "returns an array" do topic.to_a end.is_a?(Array) end context "#map_cache_key_to_engine" do asserts "maps the cache keys to the engines" do mb = multi_builder [], {} e = engine User.new mock(e).cache_key.returns(['cache key']) mb.send(:map_cache_key_to_engine, e) mb.instance_variable_get('@cache_key_to_engine').values.include?(e) end.equals(true) end context "#read_cache_results" do setup do mb = multi_builder [], {} mb.instance_variable_set('@cache_key_to_engine', { 'cache_key' => engine(User.new) }) mb end asserts "uses read_multi to find all of the cached values with keys" do mock(Rabl.configuration.cache_engine).read_multi('cache_key').returns({}) topic.send(:read_cache_results) end end context "replace_engines_with_cache_results" do asserts "replaces the builders' engines with the cache results" do mb = multi_builder [], {} e = engine User.new b = builder mb.instance_variable_set('@cache_key_to_engine', { 'cache_key' => e }) mb.instance_variable_set('@engine_to_builder', { e => b }) b.instance_variable_set('@_engines', [e]) mb.instance_variable_set('@cache_results', { 'cache_key' => '{}' }) mock(b).replace_engine(e, '{}') mb.send(:replace_engines_with_cache_results) end end end rabl-0.11.4/test/plist_engine_test.rb0000644000004100000410000003666512432721713017612 0ustar www-datawww-datarequire File.expand_path('../teststrap', __FILE__) require 'rabl/template' context "Rabl::Engine" do helper(:rabl) { |t| RablTemplate.new("code", :format => 'plist') { t } } context "with plist defaults" do setup do Rabl.configure do |config| # Comment this line out because include_plist_root is default. #config.include_plist_root = true end end context "#object" do asserts "that it sets data source" do template = rabl %q{ object @user } scope = Object.new scope.instance_variable_set :@user, User.new template.render(scope) end.matches "\n\n\n\n\tuser\n\t\n\n\n" asserts "that it can set root node" do template = rabl %q{ object @user => :person } scope = Object.new scope.instance_variable_set :@user, User.new template.render(scope).split("").sort end.equals "\n\n\n\n\tperson\n\t\n\n\n".split("").sort end context "#collection" do asserts "that it sets object to be casted as a simple array" do template = rabl %{ collection @users } scope = Object.new scope.instance_variable_set :@users, [User.new, User.new] template.render(scope).split("").sort end.equals "\n\n\n\n\t\n\t\tuser\n\t\t\n\t\n\t\n\t\tuser\n\t\t\n\t\n\n\n".split("").sort asserts "that it sets root node for objects" do template = rabl %{ collection @users => :person } scope = Object.new scope.instance_variable_set :@users, [User.new, User.new] template.render(scope).split("").sort end.equals "\n\n\n\n\tperson\n\t\n\t\t\n\t\t\tperson\n\t\t\t\n\t\t\n\t\t\n\t\t\tperson\n\t\t\t\n\t\t\n\t\n\n\n".split("").sort end context "#attribute" do asserts "that it adds an attribute or method to be included in output" do template = rabl %{ object @user attribute :name } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') template.render(scope).split("").sort end.equals "\n\n\n\n\tuser\n\t\n\t\tname\n\t\tirvine\n\t\n\n\n".split("").sort asserts "that it can add attribute under a different key name through :as" do template = rabl %{ object @user attribute :name, :as => 'city' } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') template.render(scope).split("").sort end.equals "\n\n\n\n\tuser\n\t\n\t\tcity\n\t\tirvine\n\t\n\n\n".split("").sort asserts "that it can add attribute under a different key name through hash" do template = rabl %{ object @user attribute :name => :city } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') template.render(scope).split("").sort end.equals "\n\n\n\n\tuser\n\t\n\t\tcity\n\t\tirvine\n\t\n\n\n".split("").sort end context "#code" do asserts "that it can create an arbitraty code node" do template = rabl %{ code(:foo) { 'bar' } } template.render(Object.new).split("").sort end.equals "\n\n\n\n\tfoo\n\tbar\n\n\n".split("").sort asserts "that it can be passed conditionals" do template = rabl %{ code(:foo, :if => lambda { |i| false }) { 'bar' } } template.render(Object.new).split("").sort end.equals "\n\n\n\n\n".split("").sort end context "#child" do asserts "that it can create a child node" do template = rabl %{ object @user child(@user) { attribute :city } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA') template.render(scope).split("").sort end.equals "\n\n\n\n\tuser\n\t\n\t\tuser\n\t\t\n\t\t\tcity\n\t\t\tLA\n\t\t\n\t\n\n\n".split("").sort asserts "that it can create a child node with different key" do template = rabl %{ object @user attribute :name child(@user => :person) { attribute :city } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA') template.render(scope) end.equals "\n\n\n\n\tuser\n\t\n\t\tname\n\t\tleo\n\t\tperson\n\t\t\n\t\t\tcity\n\t\t\tLA\n\t\t\n\t\n\n\n" end context "#glue" do asserts "that it glues data from a child node" do template = rabl %{ object @user attribute :name glue(@user) { attribute :city } glue(@user) { attribute :age } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA', :age => 12) template.render(scope) end.equals "\n\n\n\n\tuser\n\t\n\t\tage\n\t\t12\n\t\tcity\n\t\tLA\n\t\tname\n\t\tleo\n\t\n\n\n" end teardown do Rabl.reset_configuration! end end context "with plist_engine" do setup do class CustomPlistEncodeEngine def self.dump string 42 end end Rabl.configure do |config| config.plist_engine = CustomPlistEncodeEngine end end asserts 'that it returns process by custom to_json' do template = rabl %q{ object @user } scope = Object.new scope.instance_variable_set :@user, User.new template.render(scope) end.equals 42 teardown do Rabl.reset_configuration! end end context "without plist root" do setup do Rabl.configure do |config| config.include_plist_root = false end end context "#object" do asserts "that it sets data source" do template = rabl %q{ object @user } scope = Object.new scope.instance_variable_set :@user, User.new template.render(scope) end.matches "\n\n\n\n\n" asserts "that it can set root node" do template = rabl %q{ object @user => :person } scope = Object.new scope.instance_variable_set :@user, User.new template.render(scope) end.equals "\n\n\n\n\n" end context "#collection" do asserts "that it sets object to be casted as a simple array" do template = rabl %{ collection @users } scope = Object.new scope.instance_variable_set :@users, [User.new, User.new] template.render(scope) end.equals "\n\n\n\n\t\n\t\n\n\n" asserts "that it sets root node for objects" do template = rabl %{ collection @users => :person } scope = Object.new scope.instance_variable_set :@users, [User.new, User.new] template.render(scope) end.equals "\n\n\n\n\tperson\n\t\n\t\t\n\t\t\n\t\n\n\n" end context "#attribute" do asserts "that it adds an attribute or method to be included in output" do template = rabl %{ object @user attribute :name } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') template.render(scope) end.equals "\n\n\n\n\tname\n\tirvine\n\n\n" asserts "that it can add attribute under a different key name through :as" do template = rabl %{ object @user attribute :name, :as => 'city' } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') template.render(scope) end.equals "\n\n\n\n\tcity\n\tirvine\n\n\n" asserts "that it can add attribute under a different key name through hash" do template = rabl %{ object @user attribute :name => :city } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') template.render(scope) end.equals "\n\n\n\n\tcity\n\tirvine\n\n\n" end context "#code" do asserts "that it can create an arbitrary code node" do template = rabl %{ code(:foo) { 'bar' } } template.render(Object.new) end.equals "\n\n\n\n\tfoo\n\tbar\n\n\n" asserts "that it can be passed conditionals" do template = rabl %{ code(:foo, :if => lambda { |i| false }) { 'bar' } } template.render(Object.new) end.equals "\n\n\n\n\n" end context "#child" do asserts "that it can create a child node" do template = rabl %{ object @user child(@user) { attribute :city } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA') template.render(scope).split("").sort end.equals "\n\n\n\n\tuser\n\t\n\t\tcity\n\t\tLA\n\t\n\n\n".split("").sort asserts "that it can create a child node with different key" do template = rabl %{ object @user attribute :name child(@user => :person) { attribute :city } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA') template.render(scope) end.equals "\n\n\n\n\tname\n\tleo\n\tperson\n\t\n\t\tcity\n\t\tLA\n\t\n\n\n" end context "#glue" do asserts "that it glues data from a child node" do template = rabl %{ object @user attribute :name glue(@user) { attribute :city } glue(@user) { attribute :age } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA', :age => 12) template.render(scope) end.equals "\n\n\n\n\tage\n\t12\n\tcity\n\tLA\n\tname\n\tleo\n\n\n" end teardown do Rabl.reset_configuration! end end end rabl-0.11.4/test/xml_test.rb0000644000004100000410000002616112432721713015720 0ustar www-datawww-datarequire 'active_support/core_ext/hash/conversions' require File.expand_path('../teststrap', __FILE__) require 'rabl/template' context "Rabl::Engine" do helper(:rabl) { |t| RablTemplate.new("code", :format => 'xml') { t } } # TODO fix annoying warnings in this file: # gems/builder-3.0.3/lib/builder/xmlbase.rb:181: warning: method redefined; discarding old user setup { @old_verbose, $VERBOSE = $VERBOSE, nil } teardown { $VERBOSE = @old_verbose } context "with xml defaults" do setup do Rabl.configure do |config| # Comment this line out because include_xml_root to false is default. #config.include_xml_root = false end end context "#object" do asserts "that it sets data source" do template = rabl %q{ object @user } scope = Object.new scope.instance_variable_set :@user, User.new template.render(scope) end.matches "" asserts "that it can set root node" do template = rabl %q{ object @user => :person } scope = Object.new scope.instance_variable_set :@user, User.new template.render(scope) end.equals "\n\n\n" end context "#collection" do asserts "that it sets object to be casted as a simple array" do template = rabl %{ collection @users } scope = Object.new scope.instance_variable_set :@users, [User.new, User.new] template.render(scope) end.equals "\n\n \n \n \n \n\n" asserts "that it sets root node for objects" do template = rabl %{ collection @users => :smors } scope = Object.new scope.instance_variable_set :@users, [User.new, User.new] template.render(scope) end.equals "\n\n \n \n \n \n\n" end context "#attribute" do asserts "that it adds an attribute or method to be included in output" do template = rabl %{ object @user attribute :name } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') template.render(scope) end.equals "\n\n irvine\n\n" asserts "that it can add attribute under a different key name through :as" do template = rabl %{ object @user attribute :name, :as => 'city' } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') template.render(scope) end.equals "\n\n irvine\n\n" asserts "that it can add attribute under a different key name through hash" do template = rabl %{ object @user attribute :name => :city } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') template.render(scope) end.equals "\n\n irvine\n\n" end context "#code" do asserts "that it can create an arbitraty code node" do template = rabl %{ code(:foo) { 'bar' } } template.render(Object.new) end.equals "\n\n bar\n\n" asserts "that it can be passed conditionals" do template = rabl %{ code(:foo, :if => lambda { |i| false }) { 'bar' } } template.render(Object.new) end.equals "\n\n\n" end context "#child" do asserts "that it can create a child node" do template = rabl %{ object @user child(@user) { attribute :city } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA') template.render(scope) end.equals "\n\n \n LA\n \n\n" asserts "that it can create a child node with different key" do template = rabl %{ object @user attribute :name child(@user => :person) { attribute :city } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA') template.render(scope) end.equals "\n\n leo\n \n LA\n \n\n" end context "#glue" do asserts "that it glues data from a child node" do template = rabl %{ object @user attribute :name glue(@user) { attribute :city } glue(@user) { attribute :age } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA', :age => 12) template.render(scope) end.equals "\n\n leo\n LA\n 12\n\n" end teardown do Rabl.reset_configuration! end end context "with xml root" do setup do Rabl.configure do |config| config.include_xml_root = true end end context "#object" do asserts "that it sets data source" do template = rabl %q{ object @user } scope = Object.new scope.instance_variable_set :@user, User.new template.render(scope) end.matches "\n\n \n \n\n" asserts "that it can set root node" do template = rabl %q{ object @user => :person } scope = Object.new scope.instance_variable_set :@user, User.new template.render(scope) end.equals "\n\n \n \n\n" end context "#collection" do asserts "that it sets object to be casted as a simple array" do template = rabl %{ collection @users } scope = Object.new scope.instance_variable_set :@users, [User.new, User.new] template.render(scope) end.equals "\n\n \n \n \n \n \n \n \n \n\n" asserts "that it sets root node for objects" do template = rabl %{ collection @users => :people } scope = Object.new scope.instance_variable_set :@users, [User.new, User.new] template.render(scope) end.equals "\n\n \n \n \n \n \n \n \n \n\n" asserts "that it sets root node for objects with :root parameter" do template = rabl %{ collection @users, :root => :people, :object_root => :person } scope = Object.new scope.instance_variable_set :@users, [User.new, User.new] template.render(scope) end.equals "\n\n \n \n \n \n \n \n \n \n\n" end context "#attribute" do asserts "that it adds an attribute or method to be included in output" do template = rabl %{ object @user attribute :name } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') template.render(scope) end.equals "\n\n \n irvine\n \n\n" asserts "that it can add attribute under a different key name through :as" do template = rabl %{ object @user attribute :name, :as => 'city' } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') template.render(scope) end.equals "\n\n \n irvine\n \n\n" asserts "that it can add attribute under a different key name through hash" do template = rabl %{ object @user attribute :name => :city } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') template.render(scope) end.equals "\n\n \n irvine\n \n\n" end context "#code" do asserts "that it can create an arbitrary code node" do template = rabl %{ code(:foo) { 'bar' } } template.render(Object.new) end.equals "\n\n bar\n\n" asserts "that it can be passed conditionals" do template = rabl %{ code(:foo, :if => lambda { |i| false }) { 'bar' } } template.render(Object.new) end.equals "\n\n\n" end context "#child" do asserts "that it can create a child node" do template = rabl %{ object @user child(@user) { attribute :city } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA') template.render(scope) end.equals "\n\n \n \n LA\n \n \n\n" asserts "that it can create a child node with different key" do template = rabl %{ object @user attribute :name child(@user => :person) { attribute :city } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA') template.render(scope) end.equals "\n\n \n leo\n \n LA\n \n \n\n" end context "#glue" do asserts "that it glues data from a child node" do template = rabl %{ object @user attribute :name glue(@user) { attribute :city } glue(@user) { attribute :age } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA', :age => 12) template.render(scope) end.equals "\n\n \n leo\n LA\n 12\n \n\n" end teardown do Rabl.reset_configuration! end end end rabl-0.11.4/test/helpers_test.rb0000644000004100000410000000743112432721713016561 0ustar www-datawww-datarequire 'tmpdir' require 'pathname' require File.expand_path('../teststrap', __FILE__) class TestHelperMethods include Rabl::Helpers end context "Rabl::Helpers" do setup do @helper_class = TestHelperMethods.new @user = User.new end # determine_object_root(@user, :user, true) => "user" # determine_object_root(@user, :person) => "person" # determine_object_root([@user, @user]) => "user" # def determine_object_root(data_token, data_name=nil, include_root=true) context "for determine_object_root method" do asserts "returns nil if include_root is false" do @helper_class.determine_object_root(@user, :user, false) end.equals(nil) asserts "returns user root name if include_root is true" do @helper_class.determine_object_root(@user, :user, true) end.equals("user") asserts "returns explicit alias if specified" do @helper_class.determine_object_root(@user, :person) end.equals("person") asserts "returns explicit alias if object is nil" do @helper_class.determine_object_root(nil, :person) end.equals("person") end context "for data_name method" do asserts "returns nil if no data" do @helper_class.data_name(nil) end.equals(nil) asserts "returns symbol if symbol with empty children" do @helper_class.data_name(:user) end.equals(:user) asserts "returns alias if hash with symbol is passed" do @helper_class.data_name(@user => :user) end.equals(:user) asserts "returns name of first object of a collection" do @helper_class.data_name([@user, @user]) end.equals('users') asserts "returns name of an object" do @helper_class.data_name(@user) end.equals('user') asserts "returns table_name of collection if responds" do @coll = [@user, @user] mock(@coll).table_name { "people" } @helper_class.data_name(@coll) end.equals('people') end # data_name method context "for is_object method" do asserts "returns nil if no data" do @helper_class.is_object?(nil) end.equals(nil) asserts "returns true for an object" do @helper_class.is_object?(@user) end.equals(true) asserts "returns true for an object with each" do obj = Class.new { def each; end } @helper_class.is_object?(obj.new) end.equals(true) asserts "returns true for a hash alias" do @helper_class.is_object?(@user => :user) end.equals(true) asserts "returns true for a struct" do obj = Struct.new(:name) @helper_class.is_object?(obj.new('foo')) end.equals(true) asserts "returns true for a Hashie::Mash" do obj = Hashie::Mash.new({:name => 'hello'}) @helper_class.is_object?(obj) end.equals(true) asserts "returns false for an array" do @helper_class.is_object?([@user]) end.equals(false) end # is_object method context "for is_collection method" do asserts "returns nil if no data" do @helper_class.is_collection?(nil) end.equals(nil) asserts "returns false for a struct" do obj = Struct.new(:name) @helper_class.is_collection?(obj.new('foo')) end.equals(false) asserts "returns false for an object" do @helper_class.is_collection?(@user) end.equals(false) asserts "returns false for an object with each" do obj = Class.new { def each; end } @helper_class.is_collection?(obj.new) end.equals(false) asserts "returns false for a hash alias" do @helper_class.is_collection?(@user => :user) end.equals(false) asserts "returns true for an array" do @helper_class.is_collection?([@user]) end.equals(true) asserts "returns true for an array" do obj = Hashie::Mash.new({:name => 'hello'}) @helper_class.is_collection?(obj) end.equals(false) end # is_collection method end rabl-0.11.4/test/teststrap.rb0000644000004100000410000000130312432721713016101 0ustar www-datawww-data$LOAD_PATH.unshift(File.expand_path("../../lib", __FILE__)) module Kernel def silence_warnings with_warnings(nil) { yield } end def with_warnings(flag) old_verbose, $VERBOSE = $VERBOSE, flag yield ensure $VERBOSE = old_verbose end end unless Kernel.respond_to? :silence_warnings silence_warnings do require 'riot' require 'riot/rr' require 'tilt' require 'rabl' require 'hashie' require File.expand_path('../models/user', __FILE__) end Riot.pretty_dots class Riot::Situation def char_split(str) str.force_encoding("iso-8859-1").split("").sort end end class Riot::Context def char_split(str) str.force_encoding("iso-8859-1").split("").sort end end rabl-0.11.4/test/engine_test.rb0000644000004100000410000006770412432721713016375 0ustar www-datawww-datarequire 'json' require File.expand_path('../teststrap', __FILE__) require 'rabl/template' require File.expand_path('../models/ormless', __FILE__) context "Rabl::Engine" do helper(:rabl) { |t| RablTemplate.new { t } } # context_scope 'users', [@user] helper(:context_scope) { |name, value| scope = Object.new stub(scope).controller { stub(Object).controller_name { name } } scope.instance_variable_set :"@#{name}", value scope } context "#initialize" do setup do Rabl::Engine.new("...source...", { :format => 'xml', :root => true, :view_path => '/path/to/views' }) end asserts_topic.assigns :_source asserts_topic.assigns :_options asserts_topic.assigns :_view_path end context "#request_format" do context "is json by default" do setup do template = RablTemplate.new("code") { "" } template.render(Object.new) engine = template.instance_eval('@engine') engine.instance_eval('@_options')[:format] end asserts_topic.equals('json') end context "with a specified format" do setup do template = RablTemplate.new("code", :format => 'xml') { "" } template.render(Object.new) engine = template.instance_eval('@engine') engine.instance_eval('@_options')[:format] end asserts_topic.equals('xml') end end context "#cache" do context "with cache" do setup do template = rabl %q{ cache 'foo' } template.render(Object.new) template.instance_eval('@engine') end asserts_topic.assigns(:_cache_key) { 'foo' } end context "with cache and options" do setup do template = rabl %q{ cache 'foo', :expires_in => 'bar' } template.render(Object.new) template.instance_eval('@engine') end asserts_topic.assigns(:_cache_key) { 'foo' } asserts_topic.assigns(:_cache_options) { { :expires_in => 'bar' } } end context "without cache" do setup do template = RablTemplate.new {} template.render(Object.new) template.instance_eval('@engine') end denies(:instance_variable_defined?, :@_cache_key) end end context "with defaults" do setup do Rabl.configure do |config| config.include_json_root = true config.include_xml_root = false config.enable_json_callbacks = false end end context "#cache" do asserts "does not modify output" do template = rabl %q{ object @user cache @user } scope = Object.new scope.instance_variable_set :@user, User.new template.render(scope) end.matches "{\"user\":{}}" end context "#object" do asserts "that it sets data source" do template = rabl %q{ object @user } scope = Object.new scope.instance_variable_set :@user, User.new template.render(scope) end.matches "{\"user\":{}}" asserts "that it can set root node" do template = rabl %q{ object @user => :person } scope = Object.new scope.instance_variable_set :@user, User.new template.render(scope) end.equals "{\"person\":{}}" asserts "that it can set root node with a nil object and explicit name" do template = rabl %q{ object @user => :person } scope = Object.new scope.instance_variable_set :@user, nil template.render(scope) end.equals "{\"person\":{}}" asserts "that it can set false root node" do template = rabl %q{ object @user => false } scope = Object.new scope.instance_variable_set :@user, User.new template.render(scope) end.equals "{}" asserts "that it can set false root node and correctly render object without root node" do template = rabl %q{ object @user => false attribute :name } user = User.new(:name => "John Doe") scope = Object.new scope.instance_variable_set :@user, user template.render(scope) end.equals "{\"name\":\"John Doe\"}" asserts "that it can use non-ORM objects" do template = rabl %q{ object @other } scope = Object.new scope.instance_variable_set :@other, Ormless.new template.render(scope) end.equals "{\"ormless\":{}}" asserts "that it works with nested controllers" do template = rabl "" scope = NestedScope::User.new scope.instance_variable_set :@user, User.new template.render(scope) end.matches "{}" end context "#collection" do asserts "that it sets object to be blank array" do template = rabl %{ collection [] } scope = Object.new template.render(scope) end.equals "[]" asserts "that it sets object to be casted as a simple array" do template = rabl %{ collection @users } scope = Object.new scope.instance_variable_set :@users, [User.new, User.new] template.render(scope) end.equals "[{\"user\":{}},{\"user\":{}}]" asserts "that it sets root node for objects" do template = rabl %{ collection @users => :people } scope = Object.new scope.instance_variable_set :@users, [User.new, User.new] template.render(scope) end.equals "{\"people\":[{\"person\":{}},{\"person\":{}}]}" asserts "that it doesn't set root node for objects when specified" do template = rabl %{ collection @users, :root => :people, :object_root => false } scope = Object.new scope.instance_variable_set :@users, [User.new, User.new] template.render(scope) end.equals "{\"people\":[{},{}]}" asserts "that it sets proper object and root names when specified" do template = rabl %{ collection @users, :root => :people, :object_root => :user } scope = Object.new scope.instance_variable_set :@users, [User.new, User.new] template.render(scope) end.equals "{\"people\":[{\"user\":{}},{\"user\":{}}]}" asserts "that it can use non-ORM objects" do template = rabl %q{ object @others } scope = Object.new scope.instance_variable_set :@others, [Ormless.new, Ormless.new] template.render(scope) end.equals "[{\"ormless\":{}},{\"ormless\":{}}]" end context "#attribute" do asserts "that it adds an attribute or method to be included in output" do template = rabl %{ object @user attribute :name } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') JSON.parse(template.render(scope)) end.equals JSON.parse("{\"user\":{\"name\":\"irvine\"}}") asserts "that it can add attribute under a different key name through :as" do template = rabl %{ object @user attribute :name, :as => 'city' } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') JSON.parse(template.render(scope)) end.equals JSON.parse("{\"user\":{\"city\":\"irvine\"}}") asserts "that it can add attribute under a different key name through hash" do template = rabl %{ object @user attribute :name => :city } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') JSON.parse(template.render(scope)) end.equals JSON.parse("{\"user\":{\"city\":\"irvine\"}}") end context "#code" do asserts "that it can create an arbitraty code node" do template = rabl %{ code(:foo) { 'bar' } } template.render(Object.new) end.equals "{\"foo\":\"bar\"}" asserts "that it can be passed conditionals" do template = rabl %{ code(:foo, :if => lambda { |i| false }) { 'bar' } } template.render(Object.new) end.equals "{}" asserts "that it can merge the result with a collection element given no name" do template = rabl %{ collection @users code do |user| {:name => user.name} end } scope = Object.new scope.instance_variable_set :@users, [User.new(:name => 'a'), User.new(:name => 'b')] JSON.parse(template.render(scope)) end.equals JSON.parse("[{\"user\":{\"name\":\"a\"}},{\"user\":{\"name\":\"b\"}}]") asserts "that it can merge the result on a child node given no name" do template = rabl %{ object @user attribute :name child(@user) do code do |user| {:city => user.city} end end } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA') JSON.parse(template.render(scope)) end.equals JSON.parse("{\"user\":{\"name\":\"leo\",\"user\":{\"city\":\"LA\"}}}") end context "#child" do asserts "that it can create a child node" do template = rabl %{ object @user attribute :name child(@user) { attribute :city } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA') JSON.parse(template.render(scope)) end.equals JSON.parse("{\"user\":{\"name\":\"leo\",\"user\":{\"city\":\"LA\"}}}") asserts "that it can create a child node with different key" do template = rabl %{ object @user attribute :name child(@user => :person) { attribute :city } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA') JSON.parse(template.render(scope)) end.equals JSON.parse("{\"user\":{\"name\":\"leo\",\"person\":{\"city\":\"LA\"}}}") asserts "that it passes the data object to the block" do template = rabl %{ object @user child(@user => :person) do |user| attribute :name if user.name == 'leo' end } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo') template.render(scope) end.equals "{\"user\":{\"person\":{\"name\":\"leo\"}}}" asserts "it sets root node for child collection" do template = rabl %{ object @user attribute :name child(@users) { attribute :city } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA') scope.instance_variable_set :@users, [User.new(:name => 'one', :city => 'UNO'), User.new(:name => 'two', :city => 'DOS')] template.render(scope) end.equals "{\"user\":{\"name\":\"leo\",\"users\":[{\"user\":{\"city\":\"UNO\"}},{\"user\":{\"city\":\"DOS\"}}]}}" asserts "that it chooses a name based on symbol if no elements" do template = rabl %{ object @bar => :bar child(:foos) { attribute :city } } scope = Object.new bar = Object.new stub(bar).foos { [] } scope.instance_variable_set :@bar, bar template.render(scope) end.equals "{\"bar\":{\"foos\":[]}}" asserts "that it chooses a name based on symbol if nil" do template = rabl %{ object @bar => :bar child(:foos) { attribute :city } } scope = Object.new bar = Object.new stub(bar).foos { nil } scope.instance_variable_set :@bar, bar template.render(scope) end.equals "{\"bar\":{\"foos\":null}}" asserts "it allows suppression of root node for child collection" do template = rabl %{ object @user attribute :name child(@users, :object_root => false) { attribute :city } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA') scope.instance_variable_set :@users, [User.new(:name => 'one', :city => 'UNO'), User.new(:name => 'two', :city => 'DOS')] template.render(scope) end.equals "{\"user\":{\"name\":\"leo\",\"users\":[{\"city\":\"UNO\"},{\"city\":\"DOS\"}]}}" asserts "it allows modification of object root node for child collection" do template = rabl %{ object @user attribute :name child(@users, :object_root => 'person') { attribute :city } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA') scope.instance_variable_set :@users, [User.new(:name => 'one', :city => 'UNO'), User.new(:name => 'two', :city => 'DOS')] template.render(scope) end.equals "{\"user\":{\"name\":\"leo\",\"users\":[{\"person\":{\"city\":\"UNO\"}},{\"person\":{\"city\":\"DOS\"}}]}}" asserts "it allows modification of both labels for a child collection" do template = rabl %{ object @user attribute :name child(@users, :root => "people", :object_root => 'item') { attribute :city } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA') scope.instance_variable_set :@users, [User.new(:name => 'one', :city => 'UNO'), User.new(:name => 'two', :city => 'DOS')] template.render(scope) end.equals "{\"user\":{\"name\":\"leo\",\"people\":[{\"item\":{\"city\":\"UNO\"}},{\"item\":{\"city\":\"DOS\"}}]}}" end context "#glue" do asserts "that it glues data from a child node" do template = rabl %{ object @user attribute :name glue(@user) { attribute :city } glue(@user) { attribute :age } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA', :age => 12) JSON.parse(template.render(scope)) end.equals JSON.parse("{\"user\":{\"name\":\"leo\",\"city\":\"LA\",\"age\":12}}") asserts "that it passes the data object to the block" do template = rabl %{ object @user glue(@user) {|user| attribute :age if user.name == 'leo' } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :age => 12) template.render(scope) end.equals "{\"user\":{\"age\":12}}" end context "#partial" do asserts "that it creates object from partial and passes local" do template = rabl %{ object false node :foo do partial("foo/bar", :object => @user, :locals => { :foo => "bar" }) end } scope = Object.new @user = User.new(:name => 'leo', :city => 'LA', :age => 12) scope.instance_variable_set :@user, @user e = Rabl::Engine.new(nil) mock(e).render.returns({ :name => 'leo', :city => 'LA', :age => 12 }) any_instance_of(Rabl::Engine) do |b| mock(b).fetch_source("foo/bar", :view_path => nil).once mock(b).object_to_engine(@user, :locals => { :foo => "bar" }, :source => nil, :source_location => nil, :template => 'foo/bar').returns(e) end JSON.parse(template.render(scope)) end.equals JSON.parse("{ \"foo\" : {\"name\":\"leo\",\"city\":\"LA\",\"age\":12} }") end teardown do Rabl.reset_configuration! end end # with json root context "without json root" do setup do Rabl.configure do |config| config.include_json_root = false config.include_xml_root = false config.enable_json_callbacks = false end end context "#object" do asserts "that it sets default object" do template = rabl %{ attribute :name } scope = context_scope('user', User.new) template.render(scope).split end.equals "{\"name\":\"rabl\"}".split asserts "that it does not set a collection as default object" do template = rabl %{ attribute :name } scope = context_scope('user', []) template.render(scope).split end.equals "{}".split asserts "that it sets data source" do template = rabl %q{ object @user } scope = Object.new scope.instance_variable_set :@user, User.new template.render(scope) end.matches "{}" asserts "that it can set root node" do template = rabl %q{ object @user => :person } scope = Object.new scope.instance_variable_set :@user, User.new template.render(scope) end.equals "{}" asserts "that it can set root node with a nil object and explicit name" do template = rabl %q{ object @user => :person attributes :name } scope = Object.new scope.instance_variable_set :@user, nil template.render(scope) end.equals "{}" end context "#collection" do asserts "that it sets object to be casted as a simple array" do template = rabl %{ collection @users } scope = Object.new scope.instance_variable_set :@users, [User.new, User.new] template.render(scope) end.equals "[{},{}]" asserts "that it sets root node for objects using hash" do template = rabl %{ collection @users => :people } scope = Object.new scope.instance_variable_set :@users, [User.new, User.new] template.render(scope) end.equals "{\"people\":[{},{}]}" asserts "that it sets root node for objects using root option" do template = rabl %{ collection @users, :root => :people } scope = Object.new scope.instance_variable_set :@users, [User.new, User.new] template.render(scope) end.equals "{\"people\":[{},{}]}" asserts "that it sets root node for objects using object_root option" do template = rabl %{ collection @users, :root => :humans, :object_root => :person } scope = Object.new scope.instance_variable_set :@users, [User.new, User.new] template.render(scope) end.equals %Q^{"humans":[{"person":{}},{"person":{}}]}^ end context "#attribute" do asserts "that it adds an attribute or method to be included in output" do template = rabl %{ object @user attribute :name } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') template.render(scope) end.equals "{\"name\":\"irvine\"}" asserts "that it can add attribute under a different key name through :as" do template = rabl %{ object @user attribute :name, :as => 'city' } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') template.render(scope) end.equals "{\"city\":\"irvine\"}" asserts "that it exposes root_object" do template = rabl %q{ object @user attribute :name, :as => root_object.city } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') template.render(scope) end.equals "{\"irvine\":\"irvine\"}" asserts "that it can add attribute under a different key name through hash" do template = rabl %{ object @user attribute :name => :city } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') template.render(scope) end.equals "{\"city\":\"irvine\"}" asserts "that it handle structs correctly as child elements" do template = rabl %{ object @user child(:city) do attributes :name end } City = Struct.new(:name) scope = Object.new scope.instance_variable_set :@user, User.new(:city => City.new('San Francisco')) template.render(scope) end.equals "{\"city\":{\"name\":\"San Francisco\"}}" asserts "that it can be passed an if cond for single real attr" do template = rabl %{ object @user attribute :name attributes :age, :first, :if => lambda { |i| i.name != 'irvine' } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') JSON.parse(template.render(scope)) end.equals JSON.parse("{\"name\":\"irvine\"}") asserts "that it can be passed an if cond for aliased attrs" do template = rabl %{ object @user attributes :name => :title, :age => :year, :if => lambda { |i| i.name == 'irvine' } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') JSON.parse(template.render(scope)) end.equals JSON.parse("{\"title\":\"irvine\",\"year\":24}") asserts "that it can be passed an unless cond to hide attrs" do template = rabl %{ object @user attribute :name attributes :age, :unless => lambda { |i| i.name == 'irvine' } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') JSON.parse(template.render(scope)) end.equals JSON.parse("{\"name\":\"irvine\"}") asserts "that it can be passed an unless cond for aliased attrs" do template = rabl %{ object @user attributes :name => :title, :age => :year, :unless => lambda { |i| i.name == 'irvine' } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') JSON.parse(template.render(scope)) end.equals JSON.parse("{}") end # attribute context "#code" do asserts "that it can create an arbitraty code node" do template = rabl %{ code(:foo) { 'bar' } } template.render(Object.new) end.equals "{\"foo\":\"bar\"}" asserts "that it can be passed conditionals" do template = rabl %{ code(:foo, :if => lambda { |i| false }) { 'bar' } } template.render(Object.new) end.equals "{}" end context "#child" do asserts "that it can create a singular child node" do template = rabl %{ object @user attribute :name child(@user) { attribute :city } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA') JSON.parse(template.render(scope)) end.equals JSON.parse("{\"name\":\"leo\",\"user\":{\"city\":\"LA\"}}") asserts "that it can create a singular child node with different key" do template = rabl %{ object @user attribute :name child(@user => :person) { attribute :city } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA') JSON.parse(template.render(scope)) end.equals JSON.parse("{\"name\":\"leo\",\"person\":{\"city\":\"LA\"}}") asserts "that it can create a many child node" do template = rabl %{ object @user attribute :name child(:hobbies) { attribute :name } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA') JSON.parse(template.render(scope)) end.equals JSON.parse(%q^{"name":"leo", "hobbies":[{"hobby":{"name":"Photography"}}]}^) asserts "that it can create a many child node with different key" do template = rabl %{ object @user attribute :name child(:hobbies => :interests) { attribute :name } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA') JSON.parse(template.render(scope)) end.equals JSON.parse(%q^{"name":"leo", "interests":[{"interest":{"name":"Photography"}}]}^) asserts "that it can create a many child node with no data" do template = rabl %{ object @user attribute :name child(:hobbies) { attribute :name } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA', :hobbies => []) JSON.parse(template.render(scope)) end.equals JSON.parse(%q^{"name":"leo", "hobbies":[]}^) asserts "that it can be passed conditionals" do template = rabl %{ object @user attribute :name child({:children => :children}, {:if => lambda { |user| user.respond_to?('children') }}) { attribute :test } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA') template.render(scope) end.equals "{\"name\":\"leo\"}" end context "#glue" do asserts "that it glues data from a child node" do template = rabl %{ object @user attribute :name glue(@user) { attribute :city } glue(@user) { attribute :age } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA', :age => 12) JSON.parse(template.render(scope)) end.equals JSON.parse("{\"name\":\"leo\",\"city\":\"LA\",\"age\":12}") asserts "that it can be passed conditionals" do template = rabl %{ object @user attribute :name glue(@user, {:if => lambda { |i| false }}) { attribute :age } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA', :age => 12) JSON.parse(template.render(scope)) end.equals JSON.parse("{\"name\":\"leo\"}") end context "#extends" do helper(:tmp_path) { @tmp_path ||= Pathname.new(Dir.mktmpdir) } setup do Rabl.configure do |config| config.view_paths = tmp_path end File.open(tmp_path + "test.json.rabl", "w") do |f| f.puts %q{ attributes :age node(:city) { "Gotham" } if locals[:show_city] } end end asserts "that it extends the template with attributes from the file" do template = rabl %{ object @user attribute :name extends 'test' } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :age => 12) JSON.parse(template.render(scope)) end.equals JSON.parse("{\"name\":\"leo\",\"age\":12}") asserts "that it can be passed locals" do template = rabl %{ object @user attribute :name extends 'test', :locals => { :show_city => true } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :age => 12) JSON.parse(template.render(scope)) end.equals JSON.parse("{\"name\":\"leo\",\"age\":12,\"city\":\"Gotham\"}") asserts "that it can be passed conditionals" do template = rabl %{ object @user attribute :name extends('test', {:if => lambda { |i| false }}) } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :age => 12) JSON.parse(template.render(scope)) end.equals JSON.parse("{\"name\":\"leo\"}") end teardown do Rabl.reset_configuration! end end # without json root context "without child root" do setup do Rabl.configure do |config| config.include_child_root = false config.include_xml_root = false config.enable_json_callbacks = false end end context "#child" do asserts "that it can create a child node without child root" do template = rabl %{ child @users } scope = Object.new scope.instance_variable_set :@users, [User.new, User.new] template.render(scope) end.equals "{\"users\":[{},{}]}" end teardown do Rabl.reset_configuration! end end end rabl-0.11.4/test/integration/0000755000004100000410000000000012432721713016051 5ustar www-datawww-datarabl-0.11.4/test/integration/rails3_2/0000755000004100000410000000000012432721713017467 5ustar www-datawww-datarabl-0.11.4/test/integration/rails3_2/users_controller_test.rb0000644000004100000410000000636712432721713024473 0ustar www-datawww-data# Lives in /test/integration/users_controller_test.rb # Symlinked to fixture applications begin # Sinatra require File.expand_path(File.dirname(__FILE__) + '/../../test_config.rb') rescue LoadError # Rails require File.expand_path(File.dirname(__FILE__) + '/../test_helper.rb') end context "UsersController" do helper(:json_output) { JSON.parse(last_response.body) } setup do create_users! end context "for index action" do # Tests `collection @users` extending from 'show' template setup do get "/users" end # Attributes (regular) asserts("contains user usernames") do json_output.map { |u| u["user"]["username"] } end.equals { @users.map(&:username) } asserts("contains email") do json_output.map { |u| u["user"]["email"] } end.equals { @users.map(&:email) } asserts("contains location") do json_output.map { |u| u["user"]["location"] } end.equals { @users.map(&:location) } # Attributes (custom name) asserts("contains registered_at") do json_output.map { |u| u["user"]["registered_at"] } end.equals { @users.map(&:created_at).map { |t| t.iso8601 } } # Node (renders based on attribute) asserts("contains role") do json_output.map { |u| u["user"]["role"] } end.equals ['normal', 'normal', 'admin'] # Child (custom collection name) asserts("contains formatted phone numbers") do json_output.map { |u| u["user"]["pnumbers"].map { |n| n["pnumber"]["formatted"] } } end.equals { @users.map { |u| u.phone_numbers.map(&:formatted) } } # Node (renders collection partial) asserts("contains reversed node numbers") do json_output.map { |u| u["user"]["node_numbers"].map { |n| n["reversed"] } } end.equals { @users.map { |u| u.phone_numbers.map(&:formatted).map(&:reverse) } } end # index context "for show action" do # Tests `object :user => :person` custom parent node name setup do get "/users/#{@user1.id}" end # Attributes (regular) asserts("contains username") { json_output["person"]["username"] }.equals { @user1.username } asserts("contains email") { json_output["person"]["email"] }.equals { @user1.email } asserts("contains location") { json_output["person"]["location"] }.equals { @user1.location } # Attributes (custom name) asserts("contains registered_at") { json_output["person"]["registered_at"] }.equals { @user1.created_at.iso8601 } # Node (renders based on attribute) asserts("contains role node") { json_output["person"]["role"] }.equals "normal" # Child (custom collection name) asserts("contains first phone number") { json_output["person"]["pnumbers"][0]["pnumber"]["formatted"] }.equals { @user1.phone_numbers[0].formatted } asserts("contains second phone number") { json_output["person"]["pnumbers"][1]["pnumber"]["formatted"] }.equals { @user1.phone_numbers[1].formatted } # Node (renders collection partial) asserts("contains first node number") { json_output["person"]["node_numbers"][0]["formatted"] }.equals { @user1.phone_numbers[0].formatted } asserts("contains second node number") { json_output["person"]["node_numbers"][1]["formatted"] }.equals { @user1.phone_numbers[1].formatted } end # show endrabl-0.11.4/test/integration/rails3_2/posts_controller_test.rb0000755000004100000410000002205712432721713024477 0ustar www-datawww-data# Lives in /test/integration/posts_controller_test.rb # Symlinked to fixture applications begin # Padrino require File.expand_path(File.dirname(__FILE__) + '/../../test_config.rb') rescue LoadError # Rails require File.expand_path(File.dirname(__FILE__) + '/../test_helper.rb') end require 'rexml/document' context "PostsController" do helper(:json_output) { JSON.parse(last_response.body) } setup do create_users! Post.delete_all @post1 = Post.create(:title => "Foo", :body => "Bar", :user_id => @user1.id) @post2 = Post.create(:title => "Baz", :body => "Bah", :user_id => @user2.id) @post3 = Post.create(:title => "Kaz", :body => "", :user_id => @user3.id) @posts = [@post1, @post2, @post3] end context "for index action" do setup do get "/posts", format: :json end # Attributes (regular) asserts("contains post titles") do json_output['articles'].map { |o| o["article"]["title"] } end.equals { @posts.map(&:title) } asserts("contains post bodies") do json_output['articles'].map { |o| o["article"]["body"] } end.equals { @posts.map(&:body) } # Attributes (custom name) asserts("contains post posted_at") do json_output['articles'].map { |o| o["article"]["posted_at"] } end.equals { @posts.map(&:created_at).map(&:iso8601) } # Child asserts("contains post user child username") do json_output['articles'].map { |o| o["article"]["user"]["username"] } end.equals { @posts.map(&:user).map(&:username) } asserts("contains post user child role") do json_output['articles'].map { |o| o["article"]["user"]["role"] } end.equals { ["normal", "normal", "admin"] } # Child Numbers of the Child User asserts("contains post user child numbers") do json_output['articles'].map { |o| o["article"]["user"]["pnumbers"][0]["pnumber"]["formatted"] } end.equals { @posts.map(&:user).map(&:phone_numbers).map(&:first).map(&:formatted) } # Glue (username to article) asserts("contains glued usernames") do json_output['articles'].map { |o| o["article"]["author_name"] } end.equals { @posts.map(&:user).map(&:username) } # Conditional Child (admin) asserts("contains admin child only for admins") do json_output['articles'].map { |o| o["article"]["admin"]["username"] if o["article"].has_key?("admin") }.compact end.equals { [@user3.username] } # Conditional Node (created_by_admin) asserts("contains created_by_admin node for admins") do json_output['articles'].last['article']['created_by_admin'] end.equals { true } denies("contains no created_by_admin node for non-admins") do json_output['articles'].first['article'] end.includes(:created_by_admin) context "mime types" do setup do get "/posts", format: :rabl_test_v1 end asserts("contains post title") do json_output['articles'].first['article'] end.includes("title_v1") asserts("contains post user child username") do json_output['articles'].first['article']["user"] end.includes("username_v1") end end context "escaping output in index action" do context "for first post" do setup do Rabl.configuration.escape_all_output = true get "/posts/#{@post1.id}", format: :json json_output['post'] end # Attributes (regular) asserts("contains post title") { topic['title'] }.equals { @post1.title } asserts("contains post body") { topic['body'] }.equals { @post1.body } end context "for third post with script tags" do setup do Rabl.configuration.escape_all_output = true get "/posts/#{@post3.id}", format: :json json_output['post'] end # Attributes (regular) asserts("contains post title") { topic['title'] }.equals { @post3.title } asserts("contains escaped post body") { topic['body'] }.equals { ERB::Util.h(@post3.body) } end end # escaping output context "for show action" do setup do get "/posts/#{@post1.id}", format: :json json_output['post'] end # Attributes (regular) asserts("contains post title") { topic['title'] }.equals { @post1.title } asserts("contains post body") { topic['body'] }.equals { @post1.body } # Attributes (custom name) asserts("contains post posted_at") { topic['posted_at'] }.equals { @post1.created_at.iso8601 } # Child asserts("contains post user child username") { topic["user"]["username"] }.equals { @post1.user.username } asserts("contains post user child role") { topic["user"]["role"] }.equals { "normal" } # Child Numbers of the Child User asserts("contains post user child numbers") do topic["user"]["pnumbers"][0]["pnumber"]["formatted"] end.equals { @post1.user.phone_numbers[0].formatted } # Glue (username to article) asserts("contains glued username") { topic["author_name"] }.equals { @post1.user.username } # Non-ORM Date Node Partial context "for date node" do setup { json_output['post']['created_date'] } asserts("contains date partial with day") { topic['day'] }.equals { @post1.created_at.day } asserts("contains date partial with hour") { topic['hour'] }.equals { @post1.created_at.hour } asserts("contains date partial with full") { topic['full'] }.equals { @post1.created_at.iso8601 } end # date node asserts("contains helper action") { topic["foo"] }.equals { "BAR!" } denies("contains helper action") { topic["created_at_in_words"] }.nil asserts("contains post attributes via node") { topic["post"] }.equals { [@post1.title, @post1.body] } end # show action, json context "renderer" do setup do mock(ActionController::Base).perform_caching.any_number_of_times { true } get "/posts/#{@post1.id}/renderer" json_output['post'] end # Attributes (regular) asserts("contains post title") { topic['title'] }.equals { @post1.title } asserts("contains post body") { topic['body'] }.equals { @post1.body } # Attributes (partial) asserts("contains post partial title") { topic['partial']['title'] }.equals { @post1.title } asserts("contains post partial body") { topic['partial']['body'] }.equals { @post1.body } end # renderer action, json context "for index action rendering JSON within HTML" do setup do get "/posts", format: :html end asserts(:body).includes { "" } end # index action, html context "for show action rendering JSON within HTML" do setup do get "/posts/#{@post1.id}", format: :html end asserts(:body).includes { "" } end # show action, html context "mime_type" do setup do get "/posts/#{@post1.id}", format: :rabl_test_v1 end asserts("contains post title") { json_output['post']['title_v1'] }.equals { @post1.title } asserts("contains username") { json_output['post']['user']['username_v1'] }.equals { @post1.user.username } end context "caching" do helper(:cache_hit) do |key| Rails.cache.read(ActiveSupport::Cache.expand_cache_key(key, :rabl)) end setup do mock(ActionController::Base).perform_caching.any_number_of_times { true } Rails.cache.clear end context "for index action with caching in json" do setup do get "/posts", format: :json end asserts("contains post titles") do json_output['articles'].map { |o| o['article']['title'] } end.equals { @posts.map(&:title) } asserts(:body).equals { cache_hit ['kittens!', @posts, nil, 'json'] } asserts("contains cache hits per object (posts by title)") do json_output['articles'].map { |o| o['article']['title'] } end.equals { @posts.map{ |p| cache_hit([p, nil, 'hash'])[:title] } } end # index action, caching, json context "for index action with caching in xml" do setup do get "/posts", format: :xml end asserts("contains post titles") do doc = REXML::Document.new topic.body doc.elements.inject('articles/article/title', []) {|arr, ele| arr << ele.text} end.equals { @posts.map(&:title) } asserts(:body).equals { cache_hit ['kittens!', @posts, nil, 'xml'] } end # index action, caching, xml context "for show action with caching" do setup do get "/posts/#{@post1.id}", format: :json end asserts("contains post title") { json_output['post']['title'] }.equals { @post1.title } asserts(:body).equals { cache_hit [@post1, nil, 'json'] } end # show action, caching, json context "cache_all_output" do helper(:cache_hit) do |key| Rails.cache.read(ActiveSupport::Cache.expand_cache_key([key, 'article', 'json'], :rabl)) end setup do Rabl.configuration.cache_all_output = true get "/posts", format: :json end asserts("contains cache hits per object (posts by title)") do json_output['articles'].map { |o| o['article']['title'] } end.equals { @posts.map{ |p| cache_hit(p)['article'][:title] } } end # index action, cache_all_output end end rabl-0.11.4/test/integration/users_controller_test.rb0000644000004100000410000000634312432721713023047 0ustar www-datawww-data# Lives in /test/integration/users_controller_test.rb # Symlinked to fixture applications begin # Sinatra require File.expand_path(File.dirname(__FILE__) + '/../../test_config.rb') rescue LoadError # Rails require File.expand_path(File.dirname(__FILE__) + '/../test_helper.rb') end context "UsersController" do helper(:json_output) { JSON.parse(last_response.body) } setup do create_users! end context "for index action" do # Tests `collection @users` extending from 'show' template setup do get "/users" end # Attributes (regular) asserts("contains user usernames") do json_output.map { |u| u["user"]["username"] } end.equals { @users.map(&:username) } asserts("contains email") do json_output.map { |u| u["user"]["email"] } end.equals { @users.map(&:email) } asserts("contains location") do json_output.map { |u| u["user"]["location"] } end.equals { @users.map(&:location) } # Attributes (custom name) asserts("contains registered_at") do json_output.map { |u| u["user"]["registered_at"] } end.equals { @users.map(&:created_at).map(&:iso8601) } # Node (renders based on attribute) asserts("contains role") do json_output.map { |u| u["user"]["role"] } end.equals ['normal', 'normal', 'admin'] # Child (custom collection name) asserts("contains formatted phone numbers") do json_output.map { |u| u["user"]["pnumbers"].map { |n| n["pnumber"]["formatted"] } } end.equals { @users.map { |u| u.phone_numbers.map(&:formatted) } } # Node (renders collection partial) asserts("contains formatted node numbers") do json_output.map { |u| u["user"]["node_numbers"].map { |n| n["formatted"] } } end.equals { @users.map { |u| u.phone_numbers.map(&:formatted) } } end # index context "for show action" do # Tests `object :user => :person` custom parent node name setup do get "/users/#{@user1.id}" end # Attributes (regular) asserts("contains username") { json_output["person"]["username"] }.equals { @user1.username } asserts("contains email") { json_output["person"]["email"] }.equals { @user1.email } asserts("contains location") { json_output["person"]["location"] }.equals { @user1.location } # Attributes (custom name) asserts("contains registered_at") { json_output["person"]["registered_at"] }.equals { @user1.created_at.iso8601 } # Node (renders based on attribute) asserts("contains role node") { json_output["person"]["role"] }.equals "normal" # Child (custom collection name) asserts("contains first phone number") { json_output["person"]["pnumbers"][0]["pnumber"]["formatted"] }.equals { @user1.phone_numbers[0].formatted } asserts("contains second phone number") { json_output["person"]["pnumbers"][1]["pnumber"]["formatted"] }.equals { @user1.phone_numbers[1].formatted } # Node (renders collection partial) asserts("contains first node number") { json_output["person"]["node_numbers"][0]["formatted"] }.equals { @user1.phone_numbers[0].formatted } asserts("contains second node number") { json_output["person"]["node_numbers"][1]["formatted"] }.equals { @user1.phone_numbers[1].formatted } end # show endrabl-0.11.4/test/integration/posts_controller_test.rb0000644000004100000410000001021312432721713023045 0ustar www-datawww-data# Lives in /test/integration/posts_controller_test.rb # Symlinked to fixture applications begin # Padrino require File.expand_path(File.dirname(__FILE__) + '/../../test_config.rb') rescue LoadError # Rails require File.expand_path(File.dirname(__FILE__) + '/../test_helper.rb') end context "PostsController" do helper(:json_output) { JSON.parse(last_response.body) } setup do create_users! Post.delete_all @post1 = Post.create(:title => "Foo", :body => "Bar", :user_id => @user1.id) @post2 = Post.create(:title => "Baz", :body => "Bah", :user_id => @user2.id) @post3 = Post.create(:title => "Kaz", :body => "Paz", :user_id => @user3.id) @posts = [@post1, @post2, @post3] end context "for index action" do setup do get "/posts", :format => :json end # Attributes (regular) asserts("contains post titles") do json_output['articles'].map { |o| o["article"]["title"] } end.equals { @posts.map(&:title) } asserts("contains post bodies") do json_output['articles'].map { |o| o["article"]["body"] } end.equals { @posts.map(&:body) } # Attributes (custom name) asserts("contains post posted_at") do json_output['articles'].map { |o| o["article"]["posted_at"] } end.equals { @posts.map(&:created_at).map(&:iso8601) } # Child asserts("contains post user child username") do json_output['articles'].map { |o| o["article"]["user"]["username"] } end.equals { @posts.map(&:user).map(&:username) } asserts("contains post user child role") do json_output['articles'].map { |o| o["article"]["user"]["role"] } end.equals { ["normal", "normal", "admin"] } # Child Numbers of the Child User asserts("contains post user child numbers") do json_output['articles'].map { |o| o["article"]["user"]["pnumbers"][0]["pnumber"]["formatted"] } end.equals { @posts.map(&:user).map(&:phone_numbers).map(&:first).map(&:formatted) } # Glue (username to article) asserts("contains glued usernames") do json_output['articles'].map { |o| o["article"]["author_name"] } end.equals { @posts.map(&:user).map(&:username) } # Conditional Child (admin) asserts("contains admin child only for admins") do json_output['articles'].map { |o| o["article"]["admin"]["username"] if o["article"].has_key?("admin") }.compact end.equals { [@user3.username] } # Conditional Node (created_by_admin) asserts("contains created_by_admin node for admins") do json_output['articles'].last['article']['created_by_admin'] end.equals { true } denies("contains no created_by_admin node for non-admins") do json_output['articles'].first['article'] end.includes(:created_by_admin) end # index action context "for show action" do setup do get "/posts/#{@post1.id}", :format => :json json_output['post'] end # Attributes (regular) asserts("contains post title") { topic['title'] }.equals { @post1.title } asserts("contains post body") { topic['body'] }.equals { @post1.body } # Attributes (custom name) asserts("contains post posted_at") { topic['posted_at'] }.equals { @post1.created_at.iso8601 } # Child asserts("contains post user child username") { topic["user"]["username"] }.equals { @post1.user.username } asserts("contains post user child role") { topic["user"]["role"] }.equals { "normal" } # Child Numbers of the Child User asserts("contains post user child numbers") do topic["user"]["pnumbers"][0]["pnumber"]["formatted"] end.equals { @post1.user.phone_numbers[0].formatted } # Glue (username to article) asserts("contains glued username") { topic["author_name"] }.equals { @post1.user.username } # Non-ORM Date Node Partial context "for date node" do setup { json_output['post']['created_date'] } asserts("contains date partial with day") { topic['day'] }.equals { @post1.created_at.day } asserts("contains date partial with hour") { topic['hour'] }.equals { @post1.created_at.hour } asserts("contains date partial with full") { topic['full'] }.equals { @post1.created_at.iso8601 } end # date node end # show action end rabl-0.11.4/test/integration/test_init.rb0000644000004100000410000000262212432721713020402 0ustar www-datawww-datarequire 'rack/test' require 'riot' require 'riot/rr' Riot.pretty_dots class Riot::Situation include Rack::Test::Methods # Construct all the users needed for testing def create_users! User.delete_all; PhoneNumber.delete_all @user1 = User.create!(:username => "billybob", :email => "billy@bob.com", :location => "SF", :is_admin => false) @user2 = User.create!(:username => "joefrank", :email => "joe@frank.com", :location => "LA", :is_admin => false) @user3 = User.create!(:username => "suziesmith", :email => "suzie@smith.com", :location => "NYC", :is_admin => true) @users = [@user1, @user2, @user3] pn_ops = { :area_code => "#{rand(9).to_s*3}", :prefix => "#{rand(9).to_s*3}", :suffix => "#{rand(9).to_s*4}"} PhoneNumber.create(pn_ops.merge(:is_primary => true, :name => "Home", :user_id => @user1.id)) PhoneNumber.create(pn_ops.merge(:is_primary => false, :name => "Work", :user_id => @user1.id)) PhoneNumber.create(pn_ops.merge(:is_primary => true, :name => "Home", :user_id => @user2.id)) PhoneNumber.create(pn_ops.merge(:is_primary => true, :name => "Home", :user_id => @user3.id)) end end class Riot::Context # Set the Rack app which is to be tested. # # context "MyApp" do # app { [200, {}, "Hello!"] } # setup { get '/' } # asserts(:status).equals(200) # end def app(app=nil, &block) setup { @app = (app || block.call) } end endrabl-0.11.4/test/integration/rails4/0000755000004100000410000000000012432721713017247 5ustar www-datawww-datarabl-0.11.4/test/integration/rails4/users_controller_test.rb0000644000004100000410000000643412432721713024246 0ustar www-datawww-data# Lives in /test/integration/users_controller_test.rb # Symlinked to fixture applications begin # Sinatra require File.expand_path(File.dirname(__FILE__) + '/../../test_config.rb') rescue LoadError # Rails require File.expand_path(File.dirname(__FILE__) + '/../test_helper.rb') end context "UsersController" do helper(:json_output) { JSON.parse(last_response.body) } setup do create_users! end context "for index action" do # Tests `collection @users` extending from 'show' template setup do get "/users", format: :json end # Attributes (regular) asserts("contains user usernames") do json_output.map { |u| u["user"]["username"] } end.equals { @users.map(&:username) } asserts("contains email") do json_output.map { |u| u["user"]["email"] } end.equals { @users.map(&:email) } asserts("contains location") do json_output.map { |u| u["user"]["location"] } end.equals { @users.map(&:location) } # Attributes (custom name) asserts("contains registered_at") do json_output.map { |u| u["user"]["registered_at"] } end.equals { @users.map(&:created_at).map { |t| t.iso8601(3) } } # Node (renders based on attribute) asserts("contains role") do json_output.map { |u| u["user"]["role"] } end.equals ['normal', 'normal', 'admin'] # Child (custom collection name) asserts("contains formatted phone numbers") do json_output.map { |u| u["user"]["pnumbers"].map { |n| n["pnumber"]["formatted"] } } end.equals { @users.map { |u| u.phone_numbers.map(&:formatted) } } # Node (renders collection partial) asserts("contains reversed node numbers") do json_output.map { |u| u["user"]["node_numbers"].map { |n| n["reversed"] } } end.equals { @users.map { |u| u.phone_numbers.map(&:formatted).map(&:reverse) } } end # index context "for show action" do # Tests `object :user => :person` custom parent node name setup do get "/users/#{@user1.id}", format: :json end # Attributes (regular) asserts("contains username") { json_output["person"]["username"] }.equals { @user1.username } asserts("contains email") { json_output["person"]["email"] }.equals { @user1.email } asserts("contains location") { json_output["person"]["location"] }.equals { @user1.location } # Attributes (custom name) asserts("contains registered_at") { json_output["person"]["registered_at"] }.equals { @user1.created_at.iso8601(3) } # Node (renders based on attribute) asserts("contains role node") { json_output["person"]["role"] }.equals "normal" # Child (custom collection name) asserts("contains first phone number") { json_output["person"]["pnumbers"][0]["pnumber"]["formatted"] }.equals { @user1.phone_numbers[0].formatted } asserts("contains second phone number") { json_output["person"]["pnumbers"][1]["pnumber"]["formatted"] }.equals { @user1.phone_numbers[1].formatted } # Node (renders collection partial) asserts("contains first node number") { json_output["person"]["node_numbers"][0]["formatted"] }.equals { @user1.phone_numbers[0].formatted } asserts("contains second node number") { json_output["person"]["node_numbers"][1]["formatted"] }.equals { @user1.phone_numbers[1].formatted } end # show end rabl-0.11.4/test/integration/rails4/posts_controller_test.rb0000755000004100000410000002155312432721713024257 0ustar www-datawww-data# Lives in /test/integration/posts_controller_test.rb # Symlinked to fixture applications begin # Padrino require File.expand_path(File.dirname(__FILE__) + '/../../test_config.rb') rescue LoadError # Rails require File.expand_path(File.dirname(__FILE__) + '/../test_helper.rb') end require 'rexml/document' context "PostsController" do helper(:json_output) { JSON.parse(last_response.body) } setup do create_users! Post.delete_all @post1 = Post.create(:title => "Foo", :body => "Bar", :user_id => @user1.id) @post2 = Post.create(:title => "Baz", :body => "Bah", :user_id => @user2.id) @post3 = Post.create(:title => "Kaz", :body => "", :user_id => @user3.id) @posts = [@post1, @post2, @post3] end context "for index action" do setup do get "/posts", format: :json end # Attributes (regular) asserts("contains post titles") do json_output['articles'].map { |o| o["article"]["title"] } end.equals { @posts.map(&:title) } asserts("contains post bodies") do json_output['articles'].map { |o| o["article"]["body"] } end.equals { @posts.map(&:body) } # Attributes (custom name) asserts("contains post posted_at") do json_output['articles'].map { |o| o["article"]["posted_at"] } end.equals { @posts.map(&:created_at).map{ |t| t.iso8601(3) } } # Child asserts("contains post user child username") do json_output['articles'].map { |o| o["article"]["user"]["username"] } end.equals { @posts.map(&:user).map(&:username) } asserts("contains post user child role") do json_output['articles'].map { |o| o["article"]["user"]["role"] } end.equals { ["normal", "normal", "admin"] } # Child Numbers of the Child User asserts("contains post user child numbers") do json_output['articles'].map { |o| o["article"]["user"]["pnumbers"][0]["pnumber"]["formatted"] } end.equals { @posts.map(&:user).map(&:phone_numbers).map(&:first).map(&:formatted) } # Glue (username to article) asserts("contains glued usernames") do json_output['articles'].map { |o| o["article"]["author_name"] } end.equals { @posts.map(&:user).map(&:username) } # Conditional Child (admin) asserts("contains admin child only for admins") do json_output['articles'].map { |o| o["article"]["admin"]["username"] if o["article"].has_key?("admin") }.compact end.equals { [@user3.username] } # Conditional Node (created_by_admin) asserts("contains created_by_admin node for admins") do json_output['articles'].last['article']['created_by_admin'] end.equals { true } denies("contains no created_by_admin node for non-admins") do json_output['articles'].first['article'] end.includes(:created_by_admin) end # index action, json context "escaping output in index action" do context "for first post" do setup do Rabl.configuration.escape_all_output = true get "/posts/#{@post1.id}", format: :json json_output['post'] end # Attributes (regular) asserts("contains post title") { topic['title'] }.equals { @post1.title } asserts("contains post body") { topic['body'] }.equals { @post1.body } end context "for third post with script tags" do setup do Rabl.configuration.escape_all_output = true get "/posts/#{@post3.id}", format: :json json_output['post'] end # Attributes (regular) asserts("contains post title") { topic['title'] }.equals { @post3.title } asserts("contains escaped post body") { topic['body'] }.equals { ERB::Util.h(@post3.body) } end end # escaping output context "for show action" do setup do get "/posts/#{@post1.id}", format: :json json_output['post'] end # Attributes (regular) asserts("contains post title") { topic['title'] }.equals { @post1.title } asserts("contains post body") { topic['body'] }.equals { @post1.body } # Attributes (custom name) asserts("contains post posted_at") { topic['posted_at'] }.equals { @post1.created_at.iso8601(3) } # Child asserts("contains post user child username") { topic["user"]["username"] }.equals { @post1.user.username } asserts("contains post user child role") { topic["user"]["role"] }.equals { "normal" } # Child Numbers of the Child User asserts("contains post user child numbers") do topic["user"]["pnumbers"][0]["pnumber"]["formatted"] end.equals { @post1.user.phone_numbers[0].formatted } # Glue (username to article) asserts("contains glued username") { topic["author_name"] }.equals { @post1.user.username } # Non-ORM Date Node Partial context "for date node" do setup { json_output['post']['created_date'] } asserts("contains date partial with day") { topic['day'] }.equals { @post1.created_at.day } asserts("contains date partial with hour") { topic['hour'] }.equals { @post1.created_at.hour } asserts("contains date partial with full") { topic['full'] }.equals { @post1.created_at.iso8601 } end # date node asserts("contains helper action") { topic["foo"] }.equals { "BAR!" } denies("contains helper action") { topic["created_at_in_words"] }.nil asserts("contains post attributes via node") { topic["post"] }.equals { [@post1.title, @post1.body] } end # show action, json context "renderer" do setup do mock(ActionController::Base).perform_caching.any_number_of_times { true } get "/posts/#{@post1.id}/renderer" json_output['post'] end # Attributes (regular) asserts("contains post title") { topic['title'] }.equals { @post1.title } asserts("contains post body") { topic['body'] }.equals { @post1.body } # Attributes (partial) asserts("contains post partial title") { topic['partial']['title'] }.equals { @post1.title } asserts("contains post partial body") { topic['partial']['body'] }.equals { @post1.body } end # renderer action, json context "for index action rendering JSON within HTML" do setup do get "/posts", format: :html end asserts(:body).includes { "" } end # index action, html context "for show action rendering JSON within HTML" do setup do get "/posts/#{@post1.id}", format: :html end asserts(:body).includes { "" } end # show action, html context "mime_type" do setup do get "/posts/#{@post1.id}", format: :rabl_test_v1 end asserts("contains post title") { json_output['post']['title_v1'] }.equals { @post1.title } asserts("contains username") { json_output['post']['user']['username_v1'] }.equals { @post1.user.username } end context "caching" do helper(:cache_hit) do |key| Rails.cache.read(ActiveSupport::Cache.expand_cache_key(key, :rabl)) end setup do mock(ActionController::Base).perform_caching.any_number_of_times { true } Rails.cache.clear end context "for index action with caching in json" do setup do get "/posts", format: :json end asserts("contains post titles") do json_output['articles'].map { |o| o['article']['title'] } end.equals { @posts.map(&:title) } asserts(:body).equals { cache_hit ['kittens!', @posts, nil, 'json', 'e83f65eee5ffb454c418a59105f222c4'] } asserts("contains cache hits per object (posts by title)") do json_output['articles'].map { |o| o['article']['title'] } end.equals { @posts.map { |p| cache_hit([p, nil, 'hash', 'e373525f49a3b3b044af05255e84839d'])[:title] } } end # index action, caching, json context "for index action with caching in xml" do setup do get "/posts", format: :xml end asserts("contains post titles") do doc = REXML::Document.new topic.body doc.elements.inject('articles/article/title', []) {|arr, ele| arr << ele.text} end.equals { @posts.map(&:title) } asserts(:body).equals { cache_hit ['kittens!', @posts, nil, 'xml', 'e83f65eee5ffb454c418a59105f222c4'] } end # index action, caching, xml context "for show action with caching" do setup do get "/posts/#{@post1.id}", format: :json end asserts("contains post title") { json_output['post']['title'] }.equals { @post1.title } asserts(:body).equals { cache_hit [@post1, nil, 'json', 'e373525f49a3b3b044af05255e84839d'] } end # show action, caching, json context "cache_all_output" do helper(:cache_hit) do |key| Rails.cache.read(ActiveSupport::Cache.expand_cache_key([key, 'article', 'json'], :rabl)) end setup do Rabl.configuration.cache_all_output = true get "/posts", format: :json end asserts("contains cache hits per object (posts by title)") do json_output['articles'].map { |o| o['article']['title'] } end.equals { @posts.map{ |p| cache_hit(p)['article'][:title] } } end # index action, cache_all_output end end rabl-0.11.4/test/msgpack_engine_test.rb0000644000004100000410000002334312432721713020071 0ustar www-datawww-data# encoding: iso-8859-1 require File.expand_path('../teststrap', __FILE__) require 'rabl/template' context "Rabl::Engine" do helper(:rabl) { |t| RablTemplate.new("code", :format => 'msgpack') { t } } context "with msgpack defaults" do setup do Rabl.configure do |config| # Comment this line out because include_msgpack_root is default. #config.include_msgpack_root = true end end context "#object" do asserts "that it sets data source" do template = rabl %q{ object @user } scope = Object.new scope.instance_variable_set :@user, User.new char_split template.render(scope) end.equals char_split("\x81\xA4user\x80") asserts "that it can set root node" do template = rabl %q{ object @user => :person } scope = Object.new scope.instance_variable_set :@user, User.new char_split template.render(scope) end.equals char_split("\x81\xA6person\x80") end context "#collection" do asserts "that it sets object to be casted as a simple array" do template = rabl %{ collection @users } scope = Object.new scope.instance_variable_set :@users, [User.new, User.new] char_split template.render(scope) end.equals char_split("\x92\x81\xA4user\x80\x81\xA4user\x80") asserts "that it sets root node for objects" do template = rabl %{ collection @users => :person } scope = Object.new scope.instance_variable_set :@users, [User.new, User.new] char_split template.render(scope) end.equals char_split("\x81\xA6person\x92\x81\xA6person\x80\x81\xA6person\x80") end context "#attribute" do asserts "that it adds an attribute or method to be included in output" do template = rabl %{ object @user attribute :name } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') char_split template.render(scope) end.equals char_split("\x81\xA4user\x81\xA4name\xA6irvine") asserts "that it can add attribute under a different key name through :as" do template = rabl %{ object @user attribute :name, :as => 'city' } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') char_split template.render(scope) end.equals char_split("\x81\xA4user\x81\xA4city\xA6irvine") asserts "that it can add attribute under a different key name through hash" do template = rabl %{ object @user attribute :name => :city } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') char_split template.render(scope) end.equals char_split("\x81\xA4user\x81\xA4city\xA6irvine") end context "#code" do asserts "that it can create an arbitraty code node" do template = rabl %{ code(:foo) { 'bar' } } char_split template.render(Object.new) end.equals char_split("\x81\xA3foo\xA3bar") asserts "that it can be passed conditionals" do template = rabl %{ code(:foo, :if => lambda { |i| false }) { 'bar' } } char_split template.render(Object.new) end.equals char_split("\x80") end context "#child" do asserts "that it can create a child node" do template = rabl %{ object @user attribute :name child(@user) { attribute :city } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA') char_split template.render(scope) end.equals char_split("\x81\xA4user\x82\xA4name\xA3leo\xA4user\x81\xA4city\xA2LA") asserts "that it can create a child node with different key" do template = rabl %{ object @user attribute :name child(@user => :person) { attribute :city } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA') char_split template.render(scope) end.equals char_split("\x81\xA4user\x82\xA4name\xA3leo\xA6person\x81\xA4city\xA2LA") end context "#glue" do asserts "that it glues data from a child node" do template = rabl %{ object @user attribute :name glue(@user) { attribute :city } glue(@user) { attribute :age } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA', :age => 12) char_split template.render(scope) end.equals char_split("\x81\xA4user\x83\xA4name\xA3leo\xA4city\xA2LA\xA3age\f") end teardown do Rabl.reset_configuration! end end context "with msgpack_engine" do setup do class CustomEncodeEngine def self.pack string 42 end end Rabl.configure do |config| config.msgpack_engine = CustomEncodeEngine end end asserts 'that it returns process by custom to_json' do template = rabl %q{ object @user } scope = Object.new scope.instance_variable_set :@user, User.new template.render(scope) end.equals 42 teardown do Rabl.reset_configuration! end end context "without msgpack root" do setup do Rabl.configure do |config| config.include_msgpack_root = false end end context "#object" do asserts "that it sets data source" do template = rabl %q{ object @user } scope = Object.new scope.instance_variable_set :@user, User.new char_split template.render(scope) end.equals char_split("\x80") asserts "that it can set root node" do template = rabl %q{ object @user => :person } scope = Object.new scope.instance_variable_set :@user, User.new char_split template.render(scope) end.equals char_split("\x80") end context "#collection" do asserts "that it sets object to be casted as a simple array" do template = rabl %{ collection @users } scope = Object.new scope.instance_variable_set :@users, [User.new, User.new] char_split template.render(scope) end.equals char_split("\x92\x80\x80") asserts "that it sets root node for objects" do template = rabl %{ collection @users => :person } scope = Object.new scope.instance_variable_set :@users, [User.new, User.new] char_split template.render(scope) end.equals char_split("\x81\xA6person\x92\x80\x80") end context "#attribute" do asserts "that it adds an attribute or method to be included in output" do template = rabl %{ object @user attribute :name } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') char_split template.render(scope) end.equals char_split("\x81\xA4name\xA6irvine") asserts "that it can add attribute under a different key name through :as" do template = rabl %{ object @user attribute :name, :as => 'city' } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') char_split template.render(scope) end.equals char_split("\x81\xA4city\xA6irvine") asserts "that it can add attribute under a different key name through hash" do template = rabl %{ object @user attribute :name => :city } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'irvine') char_split template.render(scope) end.equals char_split("\x81\xA4city\xA6irvine") end context "#code" do asserts "that it can create an arbitraty code node" do template = rabl %{ code(:foo) { 'bar' } } char_split template.render(Object.new) end.equals char_split("\x81\xA3foo\xA3bar") asserts "that it can be passed conditionals" do template = rabl %{ code(:foo, :if => lambda { |i| false }) { 'bar' } } char_split template.render(Object.new) end.equals char_split("\x80") end context "#child" do asserts "that it can create a child node" do template = rabl %{ object @user attribute :name child(@user) { attribute :city } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA') char_split template.render(scope) end.equals char_split("\x82\xA4name\xA3leo\xA4user\x81\xA4city\xA2LA") asserts "that it can create a child node with different key" do template = rabl %{ object @user attribute :name child(@user => :person) { attribute :city } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA') char_split template.render(scope) end.equals char_split("\x82\xA4name\xA3leo\xA6person\x81\xA4city\xA2LA") end context "#glue" do asserts "that it glues data from a child node" do template = rabl %{ object @user attribute :name glue(@user) { attribute :city } glue(@user) { attribute :age } } scope = Object.new scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA', :age => 12) char_split template.render(scope) end.equals char_split("\x83\xA4name\xA3leo\xA4city\xA2LA\xA3age\f") end teardown do Rabl.reset_configuration! end end end rabl-0.11.4/test/configuration_test.rb0000644000004100000410000000504412432721713017764 0ustar www-datawww-datarequire File.expand_path('../teststrap', __FILE__) context 'Rabl::Configuration' do context 'defaults' do # multi_json compatibility TODO helper(:json_engine) { ::Oj } setup { Rabl.configuration } asserts(:include_json_root).equals true asserts(:include_child_root).equals true asserts(:include_xml_root).equals false asserts(:enable_json_callbacks).equals false asserts(:view_paths).equals [] asserts(:json_engine).equals { json_engine } asserts(:cache_engine).is_a?(Rabl::CacheEngine) asserts(:replace_nil_values_with_empty_strings).equals false asserts(:replace_empty_string_values_with_nil_values).equals false asserts(:exclude_nil_values).equals false asserts(:exclude_empty_values_in_collections).equals false end context 'custom JSON engine configured as Symbol' do setup do Rabl.configure do |c| c.json_engine = :oj end end asserts('uses a custom JSON engine') { topic.json_engine.to_s =~ /oj/i } end # custom json, symbol context 'custom JSON engine configured as Class' do setup do Rabl.configure do |c| c.json_engine = ActiveSupport::JSON end end asserts('uses a custom JSON engine') { topic.json_engine.to_s == 'ActiveSupport::JSON' } end # custom JSON, class context 'raise on missing attributes' do setup do Rabl.configure do |c| c.raise_on_missing_attribute = true end end asserts(:raise_on_missing_attribute).equals true end # raise on missing context 'replace nil values with empty strings' do setup do Rabl.configure do |c| c.replace_nil_values_with_empty_strings = true end end asserts(:replace_nil_values_with_empty_strings).equals true end # replace nil values with empty strings context 'replace empty string values with nil values' do setup do Rabl.configure do |c| c.replace_empty_string_values_with_nil_values = true end end asserts(:replace_empty_string_values_with_nil_values).equals true end # replace empty string values with nil values context 'exclude nil values' do setup do Rabl.configure do |c| c.exclude_nil_values = true end end asserts(:exclude_nil_values).equals true end # exclude nil values context 'exclude empty values in collections' do setup do Rabl.configure do |c| c.exclude_empty_values_in_collections = true end end asserts(:exclude_empty_values_in_collections).equals true end # exclude empty values in collections end rabl-0.11.4/test/template_test.rb0000644000004100000410000000357212432721713016734 0ustar www-datawww-datarequire File.expand_path('../teststrap',__FILE__) require 'rabl/template' class Scope end context "RablTemplate" do asserts "that it registers for .rabl files" do Tilt['test.rabl'] end.equals RablTemplate context "#render" do setup do RablTemplate.new { |t| "code(:lol) { 'wut' }" } end asserts "preparing and evaluating templates on #render" do topic.render end.matches %r{"lol":"wut"} 3.times do |n| asserts "can be rendered #{n} time(s)" do topic.render end.matches %r{"lol":"wut"} end # asserts "that it can be passed locals" do # template = RablTemplate.new { "code(:name) { @name }" } # template.render(Object.new, :object => 'Bob') # end.matches %r{"name":"Bob"} asserts "that it evaluates in object scope" do template = RablTemplate.new { "code(:lol) { @name }" } scope = Object.new scope.instance_variable_set :@name, 'Joe' template.render(scope) end.matches %r{"lol":"Joe"} asserts "that it can pass a block for yield" do template = RablTemplate.new { "code(:lol) { 'Hey ' + yield + '!' }" } template.render { 'Joe' } end.matches %r{"lol":"Hey Joe!"} end context "#render compiled" do # asserts "that it can be passed locals" do # template = RablTemplate.new { "code(:name) { @name }" } # template.render(Scope.new, :object => 'Bob') # end.matches %r{"name":"Bob"} asserts "that it evaluates in an object scope" do template = RablTemplate.new { "code(:lol) { @name }" } scope = Scope.new scope.instance_variable_set :@name, 'Joe' template.render(scope) end.matches %r{"lol":"Joe"} asserts "that it can pass a block for yield" do template = RablTemplate.new { "code(:lol) { 'Hey ' + yield + '!' }" } template.render(Scope.new) { 'Joe' } end.matches %r{"lol":"Hey Joe!"} end end rabl-0.11.4/test/models/0000755000004100000410000000000012432721713015011 5ustar www-datawww-datarabl-0.11.4/test/models/user.rb0000644000004100000410000000164012432721713016315 0ustar www-datawww-dataunless defined?(User) class User attr_accessor :age, :city, :name, :first, :float, :hobbies, :twitter DEFAULT_AGE = 24 DEFAULT_CITY = 'irvine' DEFAULT_NAME = 'rabl' DEFAULT_FIRST = 'bob' DEFAULT_FLOAT = 1234.56 DEFAULT_HOBBIES = ['Photography'] DEFAULT_TWITTER = 'rablgem' def initialize(attributes = {}) %w(age city name first float hobbies twitter).each do |attr| self.send "#{attr}=", (attributes.has_key?(attr.to_sym) ? attributes[attr.to_sym] : self.class.const_get("DEFAULT_#{attr.upcase}")) end self.hobbies = self.hobbies.map { |h| Hobby.new(h) } end end class Hobby attr_accessor :name def initialize(name); @name = name; end end end unless defined?(NestedScope::User) module NestedScope class User def controller; self; end def controller_name; self.class.name.downcase; end end end end rabl-0.11.4/test/models/ormless.rb0000644000004100000410000000004312432721713017017 0ustar www-datawww-dataclass Ormless # Nothing here end rabl-0.11.4/test/silence.rb0000644000004100000410000000072512432721713015501 0ustar www-datawww-datamodule Kernel def silence_warnings with_warnings(nil) { yield } end def silence_stream(stream) old_stream = stream.dup stream.reopen(RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ ? 'NUL:' : '/dev/null') stream.sync = true yield ensure stream.reopen(old_stream) end def with_warnings(flag) old_verbose, $VERBOSE = $VERBOSE, flag yield ensure $VERBOSE = old_verbose end end unless Kernel.respond_to? :silence_warnings rabl-0.11.4/Gemfile.ci0000644000004100000410000000030412432721713014431 0ustar www-datawww-datasource 'https://rubygems.org' # Specify your gem's dependencies in rabl.gemspec gemspec gem "rake" gem "i18n", '~> 0.6' platforms :mri_18 do gem 'SystemTimer' gem 'json' end gem 'builder' rabl-0.11.4/.gitignore0000644000004100000410000000011412432721713014533 0ustar www-datawww-data*.gem .bundle .rvmrc Gemfile.lock pkg/* fixtures/rails2/log/*.log tags .idearabl-0.11.4/CONTRIBUTING.md0000644000004100000410000000250612432721713015003 0ustar www-datawww-dataWe love pull requests. Here's a quick guide: 1. Fork the repo. 2. Run the tests. We only take pull requests with passing tests, and it's great to know that you have a clean slate: `bundle && rake test` 3. Add a test for your change. Only refactoring and documentation changes require no new tests. If you are adding functionality or fixing a bug, we need a test! 4. Make the test pass. 5. Push to your fork and submit a pull request. At this point you're waiting on us. We like to at least comment on, if not accept, pull requests within three business days (and, typically, one business day). We may suggest some changes or improvements or alternatives. Some things that will increase the chance that your pull request is accepted: * Use Rails idioms and helpers * Include tests that fail without your code, and pass with it * Update the documentation and README for anything affected by your contribution Syntax: * Two spaces, no tabs. * No trailing whitespace. Blank lines should not have any space. * Prefer &&/|| over and/or. * MyClass.my_method(my_arg) not my_method( my_arg ) or my_method my_arg. * a = b and not a=b. * Follow the conventions you see used in the source already. And in case we didn't emphasize it enough: we love tests! NOTE: Adapted from https://raw.github.com/thoughtbot/factory_girl_rails/master/CONTRIBUTING.mdrabl-0.11.4/rabl.gemspec0000644000004100000410000000247412432721713015043 0ustar www-datawww-data# -*- encoding: utf-8 -*- $:.push File.expand_path("../lib", __FILE__) require "rabl/version" Gem::Specification.new do |s| s.name = "rabl" s.version = Rabl::VERSION s.platform = Gem::Platform::RUBY s.authors = ["Nathan Esquenazi"] s.email = ["nesquena@gmail.com"] s.homepage = "https://github.com/nesquena/rabl" s.summary = %q{General ruby templating with json, bson, xml and msgpack support} s.description = %q{General ruby templating with json, bson, xml and msgpack support} s.license = 'MIT' s.rubyforge_project = "rabl" s.files = `git ls-files`.split("\n") s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } s.require_paths = ["lib"] if RUBY_VERSION < "1.9" s.add_dependency 'activesupport', '>= 2.3.14', '<= 4' else s.add_dependency "activesupport", '>= 2.3.14' end s.add_development_dependency 'riot', '~> 0.12.3' s.add_development_dependency 'rr', '~> 1.0.2' s.add_development_dependency 'rake' s.add_development_dependency 'tilt' s.add_development_dependency 'oj' s.add_development_dependency 'msgpack', '~> 0.4.5' s.add_development_dependency 'bson', '~> 1.7.0' s.add_development_dependency 'plist' end rabl-0.11.4/test.watchr0000644000004100000410000000165712432721713014751 0ustar www-datawww-dataENV["WATCHR"] = "1" system 'clear' def run(cmd) puts(cmd) system cmd end def run_test_file(file) system('clear') run(%Q(ruby -I"lib:test" -rubygems #{file})) end def run_all_tests system('clear') run('rake test') end def related_test_files(path) Dir['test/**/*.rb'].select { |file| file =~ /#{File.basename(path).split(".").first}_test.rb/ } end watch('test/teststrap\.rb') { run_all_tests } watch('test/(.*).*_test\.rb') { |m| run_test_file(m[0]) } watch('lib/.*/.*\.rb') { |m| related_test_files(m[0]).map {|tf| run_test_file(tf) } } # Ctrl-\ Signal.trap 'QUIT' do puts " --- Running all tests ---\n\n" run_all_tests end @interrupted = false # Ctrl-C Signal.trap 'INT' do if @interrupted then @wants_to_quit = true abort("\n") else puts "Interrupt a second time to quit" @interrupted = true Kernel.sleep 1.5 # raise Interrupt, nil # let the run loop catch it run_all_tests end end rabl-0.11.4/CHANGELOG.md0000644000004100000410000002325212432721713014364 0ustar www-datawww-data# CHANGELOG ## 0.11.4 (November 7th) * FIX Get MultiBuilder to behave properly around nil engines (@DouweM) ## 0.11.3 (November 3rd) * FIX error when attempting to cache empty child collections (@DouweM) * FIX bug causing Rails 4 cache digests never to be appended (@DouweM) ## 0.11.2 (October 26th) * FIX Don't put nil into builder engines when glueing nil object (@DouweM) ## 0.11.1 (October 19th) * NEW #417 Major rewrite caching layer to be much faster using read_multi (@ahlatimer, @DouweM) * FIX #589 Use set to speed up is_collection method check (@ccocchi) * FIX #584 Fix issues with newer releases of oj gem (@DouweM) ## 0.11.0 (August 16th) * Restore ruby 1.8 compatibility (@s01ipsist, @patrickdavey) * Fix Rabl::Tracker to match paths with numbers (@szimek) * Fix caching of a recursive template (@bonobos) * Fix cache for non-rails apps (@t-k) * Escape output all at once to properly escape content (@bholzer) * Add hashie mash to known object list (@nguyenmighty) * Remove root object when set to false value (@mrThe) ## 0.10.1 (May 28th) * Fix nasty formatting bug that broke XML (@bhicks) ## 0.10.0 (May 24th) * Fix typo in readme about new options (@PikachuEXE) * Use the request format for source lookup (@omgitsads) * Simplify rendering methods with refactor (@bhicks) * Reset format and scope options for each request (@bhicks) * Convert keys to ensure uniqueness (@swalkinshaw) * Add fallback for child name if its nil (@swalkinshaw) * Apply replace_xxx_values recursively within nested values (@igas) ## 0.9.4.pre1 (March 30th) * NEW #527 Add configuration excluding empty values in collections (@addbrick) * FIX #516 Set default root_object lazily (@DouweM) * FIX #540 Fix cache digest in Rails 4.1 (@huoxito) * FIX #534 Bug with management of empty string values (@nickkov89) * FIX #519 JSON in README (@shirish4you) * NEW #514 Add configuration to exclude nil values (@oharsta) ## 0.9.3 (December 5th) * FIX Send engine options through from render call (Thanks @bhicks) * FIX Cleanup compile_hash method through refactoring complexity (Thanks @bhicks) * FIX #503 handling render case with no lookup_context in Rails 4 * FIX #502 fix regression in render when object is nil with explicit root name ## 0.9.2 (November 21 2013) * FIX #508 by avoiding new proc syntax breaking 1.8.7 ## 0.9.1 (November 17 2013) * NEW #507 Resolve conditionals for extends (Thanks @micahcraig) * NEW #453 Support for symbol conditionals (Thanks @leoc) ## 0.9.0 (October 14 2013) * FIX #497 Renderer should support partial caching and a digestor bug fixed (Thanks @siong1987) ## 0.9.0.pre3 (Sept 22 2013) * FIX #495 Digest cache when rendering from controller (Thanks @siong1987) ## 0.9.0.pre2 (Sept 02 2013) * FIX #142 Better resource resolution for AR Scopes * Adds Rails 4 test fixture (Thanks @siong1987) * Adds Rails 4 cache digestor (Thanks @siong1987) * Child now supports `object_root` and `root` arguments like 'collection' * FIX #486 Prioritize to_hash options to allow setting root ## 0.8.6 * FIX #142 #467 Do not use a collection as the default object. (Thanks @mrbrdo) * NEW Options hash for glue function added (Thanks @sassysolutions) * FIX #470 Better template lookups when Padrino is defined (Thanks @LTe) ## 0.8.5 * FIX #386 Support disabling root on child calls (Thanks @digger69) ## 0.8.4 * NEW #411 Add "replace nil values with empty strings" option (Thanks @manuelmeurer) ## 0.8.3 * Closes #421 bug with locals in engine ## 0.8.2 * Passing locals when rendering templates via partials or inheritance (Thanks @simsalabim) ## 0.8.1 * Fix to respect @collection :root for xml output (Thanks @chinshr) ## 0.8.0 * Remove multi_json dependency, simpler JSON handling ## 0.7.10 * Add early support for Rails 4 (Thanks @jopotts) * Add configuration option for raising on missing attributes (Thanks @ReneB) * Allow caching outside the Rails environment (Thanks @flyerhzm) * Fix template lookup on Rails (Thanks @vimutter) ## 0.7.9 * Replace yajl with oj in docs and tests * Fix handling of empty children arrays with tests (Thanks @sethvargo) ## 0.7.8 * Additional fix for attribute conditional support ## 0.7.7 * Fix #344 to avoid: "warning: default `to_a' will be obsolete" * Fix #356 by adding 'known object classes' like struct to be recognized as objects. * Fix #354 by adding 'if' and 'unless' to `attribute` (Thanks @andrewhubbs) ## 0.7.6 * Fix render behavior by separating data_object and data_name in engine * Fix regression with 'child' behavior with nil on extends (with tests) ## 0.7.5 * Avoid incorrectly setting implicit objects for 'object false' partials ## 0.7.4 * Fix issue #347 with extends failing for custom object templates ## 0.7.3 * Fix issue #342 with nil case for format checking in engine `request_params` ## 0.7.2 * Set instance variables for locals in engine instead of renderer (Thanks @geehsien) * Changes default JSON engine for Rails, move logic to separate class (Thanks @shmeltex) ## 0.7.1 * Improved renderer interface (Thanks @siong1987) * Pass current object into blocks (Thanks @braddunbar) ## 0.7.0 * Use source_format when looking up partials (Thanks @databyte) * Add README note about render_views (Thanks @databyte) * Add support for Rails 3.2+ sending custom mime types (Thanks @databyte) * Add option to define his own cache_engine (Thanks @shingara) ## 0.6.14 * Fix RSpec under Rails 3, use render_views to test output (Thanks @agibralter) * Fix extends allows passing in local object when root object is specified ## 0.6.13 * Small tweak to is_collection detection (look for each and map) * Adds `include_child_root` configuration option (Thanks @yoon) ## 0.6.12 * Fix view_path options for renderer (Thanks @ivanvanderbyl and @route) * Only escape if data exists * Fix default object recognition for Rails 2.3.2 * Adds `root_object` method on engine (Thanks @OliverLetterer) ## 0.6.11 * Changes send to __send__ (Thanks @alindeman) * Change object/collection checks to :map instead of :each * Adds support for auto-escaping attribute configuration (Thanks @databyte) * Adds support for configuration of view_paths (Thanks @ivanvanderbyl) * Fix issue with helpers caching check ## 0.6.10 * Fixes expected behavior with nil and collection keyword * Fixes multi_json to support newer form syntax (Thanks @rajatvig) ## 0.6.9 * Adds support for generic template rendering (Thanks @ivanvanderbyl) * Allow cache to be called with an explicit key (Thanks @databyte) ## 0.6.8 * Fix Rails 3 resolution on Ruby < 1.9.2 ## 0.6.7 * Fix format to default to json in the event that it is a 'hash' (Thanks @databyte) * Support using cache keys within extended templates (Thanks @databyte) ## 0.6.6 * Even more improvements to Rails template resolution (Thanks @databyte) * Added fixture integration tests for rendering rabl inline from html (Thanks @databyte) * Added useful note to README about Padrino (Thanks @simonc) ## 0.6.5 * Fixed issue with multi_json version use ~> 1.0 (Thanks @sferik) ## 0.6.4 * Further improvements to template path resolution for Rails (Thanks @radar) * Change multi_json to be > 1.1.0 to support 1.2.0 with Oj support (Thanks @jherdman) ## 0.6.3 * Adds Rails 3.2 Integration Test * Much improved Rails template path resolution ## 0.6.2 * Adds template caching support for Rails (Thanks @databyte) ## 0.6.1 * Upgrade dependency to multi_json 1.1.0 (Thanks @geronimo) ## 0.6.0 * Change engine to only instantiate one builder when rendering a collection * Alias to\_msgpack to to\_mpac * Cache template sources for faster partial lookups (thanks @cj) * Adds BSON format support (thanks @Antiarchitect) * Use template lookup mechanism to find templates in Rails 3 (thanks @blakewatters) * Adds a 'object_root' option to collection (thanks @blakewatters) * Adds a 'root_name' option to collection * Adds PList format support (thanks @alzeih) * Fixes infinite recursion in edge case calculating object root name * Fixes issue with nameless node that has an array result * Adds support for `object_root => false` (Thanks @Lytol) ## 0.5.4 * Ensure ActionView is defined before registering Rails template handler (thanks cj) ## 0.5.2-0.5.3 * Add better support for conditionals for child (thanks gregory) * Fix issue introduced with 'node' and properly clear options (thanks joshbuddy) ## 0.5.1 * Use respond\_to? instead of checking Enumerable for is\_object * Performance optimization (thanks Eric Allen) ## 0.5.0 * Adds comprehensive fixture suite (padrino,rails2,rails3,sinatra) * Travis CI Integration Testing * Cleanup json configuration and related tests (Thanks mschulkind) * Adds CHANGELOG to track changes * Adds optional MessagePack format support (thanks byu) * Explicit requires for ActiveSupport now in gemspec and lib * Adds template support for regular (non-ORM) ruby objects (thanks plukevdh) * Fixes bug with the child root not properly appearing in all cases * Better stack traces by tracking source location in instance_eval (thanks skade) * Fix issue with controller object detection failing in namespaces (thanks alunny) * Fix ruby -w warnings (thanks achiu) * Better partial implementation which passes options * Better fetch_source implementation for Padrino (thanks skade) * Better fetch_source implementation for Rails * Added fetch_source implementation for Sinatra * Lots of test refactorings / cleanup / improvement * Code block name is now optional [Thanks brentmurphy] ## 0.3.0 * Use multi_json to handle JSON encoding (Thanks kossnocorp) * Fixes unit tests with hash order on 1.8.7 ## 0.2.8 * Fixes Rails 3.1 Compatibility (Thanks skyeagle) * Fixes Ruby 1.8.6 Compatibility (Thanks Don) * Adds much better riot unit testing (Thanks Achiu) rabl-0.11.4/README.md0000644000004100000410000006431612432721713014040 0ustar www-datawww-data# RABL # [![Continuous Integration status](https://secure.travis-ci.org/nesquena/rabl.png)](http://travis-ci.org/nesquena/rabl) [![Dependency Status](https://gemnasium.com/nesquena/rabl.png)](https://gemnasium.com/nesquena/rabl) [![Code Climate](https://codeclimate.com/github/nesquena/rabl.png)](https://codeclimate.com/github/nesquena/rabl) RABL (Ruby API Builder Language) is a Rails and [Padrino](http://padrinorb.com) ruby templating system for generating JSON, XML, MessagePack, PList and BSON. When using the ActiveRecord 'to_json' method, I find myself wanting a more expressive and powerful solution for generating APIs. This is especially true when the JSON representation is complex or doesn't match the exact schema defined within the database. In particular, I want to easily: * Create arbitrary nodes named based on combining data in an object * Pass arguments to methods and store the result as a child node * Render partial templates and inherit to reduce code duplication * Rename or alias attributes to change the name from the model * Append attributes from a child into a parent node * Include nodes only if a certain condition has been met Anyone who has tried the 'to_json' method used in ActiveRecord for generating a JSON response has felt the pain of this restrictive approach. RABL is a general templating system created to solve these problems by approaching API response generation in an entirely new way. RABL at the core is all about adhering to MVC principles by deferring API data representations to the **view** layer of your application. For a breakdown of common misconceptions about RABL, please check out our guide to [understanding RABL](https://github.com/nesquena/rabl/wiki/Understanding-RABL) which can help clear up any confusion about this project. ## Breaking Changes ## * v0.9.0 (released Oct 14, 2013) changes the [default node name for certain associations](https://github.com/nesquena/rabl/issues/505) especially around STI models. You might want to verify for any breakages as a result and be more explicit by specifying an alias i.e `@users => :users` * v0.8.0 (released Feb 14, 2013) removes multi_json dependency and relies on Oj (or JSON) as the json parser. Simplifies code, removes a dependency but you might want to remove any references to MultiJson. * v0.6.14 (released June 28, 2012) requires the use of render_views with RSpec to test templates. Otherwise, the controller will simply pass through the render command as it does with ERB templates. ## Installation ## Install RABL as a gem: ``` gem install rabl ``` or add to your Gemfile: ```ruby # Gemfile gem 'rabl' # Also add either `oj` or `yajl-ruby` as the JSON parser gem 'oj' ``` and run `bundle install` to install the dependency. If you are using **Rails 2.3.8 (and up), Rails 3.X or Padrino**, RABL works without configuration. **Important:** With Padrino, be sure that **the rabl gem is listed after the padrino gem in your Gemfile**, otherwise Rabl will not register properly as a template engine. With Sinatra, or any other tilt-based framework, simply register: ```ruby Rabl.register! ``` and RABL will be initialized and ready for use. For usage with Sinatra, check out the [Sinatra Usage](https://github.com/nesquena/rabl/wiki/Setup-for-Sinatra) guide. ## Overview ## You can use RABL to generate JSON and XML based APIs from any ruby object. With RABL, the data typically is derived primarily from models (ORM-agnostic) and the representation of the API output is described within a view template using a simple ruby DSL. This allows you to keep your data separated from the JSON or XML you wish to output. Once you have installed RABL (explained above), you can construct a RABL view template and then render the template from your Sinatra, Padrino or Rails applications from the controller (or route) very easily. Using [Padrino](http://padrinorb.com) as an example, assuming you have a `Post` model filled with blog posts, you can render an API representation (both JSON and XML) by creating a route: ```ruby # app/app.rb get "/posts", :provides => [:json, :xml] do @user = current_user @posts = Post.order("id DESC") render "posts/index" end ``` Then we can create the following RABL template to express the API output of `@posts`: ```ruby # app/views/posts/index.rabl collection @posts attributes :id, :title, :subject child(:user) { attributes :full_name } node(:read) { |post| post.read_by?(@user) } ``` Which would output the following JSON or XML when visiting `http://localhost:3000/posts.json` ```js [{ "post" : { "id" : 5, "title": "...", "subject": "...", "user" : { "full_name" : "..." }, "read" : true } }] ``` That's a basic overview but there is a lot more to see such as partials, inheritance, custom nodes, etc. Read the full details of RABL below. ## Configuration ## RABL is intended to require little to no configuration to get working. This is the case in most scenarios, but depending on your needs you may want to set the following global configurations in your application (this block is completely optional): ```ruby # config/initializers/rabl_init.rb require 'rabl' Rabl.configure do |config| # Commented as these are defaults # config.cache_all_output = false # config.cache_sources = Rails.env != 'development' # Defaults to false # config.cache_engine = Rabl::CacheEngine.new # Defaults to Rails cache # config.perform_caching = false # config.escape_all_output = false # config.json_engine = nil # Class with #dump class method (defaults JSON) # config.msgpack_engine = nil # Defaults to ::MessagePack # config.bson_engine = nil # Defaults to ::BSON # config.plist_engine = nil # Defaults to ::Plist::Emit # config.include_json_root = true # config.include_msgpack_root = true # config.include_bson_root = true # config.include_plist_root = true # config.include_xml_root = false # config.include_child_root = true # config.enable_json_callbacks = false # config.xml_options = { :dasherize => true, :skip_types => false } # config.view_paths = [] # config.raise_on_missing_attribute = true # Defaults to false # config.replace_nil_values_with_empty_strings = true # Defaults to false # config.replace_empty_string_values_with_nil_values = true # Defaults to false # config.exclude_nil_values = true # Defaults to false # config.exclude_empty_values_in_collections = true # Defaults to false end ``` Each option specifies behavior related to RABL's output. If `include_json_root` is disabled that removes the root node for each root object in the output, and `enable_json_callbacks` enables support for 'jsonp' style callback output if the incoming request has a 'callback' parameter. If `include_child_root` is set to false then child objects in the response will not include a root node by default. This allows you to further fine-tune your desired response structure. If `cache_engine` is set, you should assign it to a class with a `fetch` method. See the [default engine](https://github.com/nesquena/rabl/blob/master/lib/rabl/cache_engine.rb) for an example. If `perform_caching` is set to `true` then it will perform caching. You can ignore this option if you are using Rails, it's same to Rails `config.action_controller.perform_caching` If `cache_sources` is set to `true`, template lookups will be cached for improved performance. The cache can be reset manually by running `Rabl.reset_source_cache!` within your application. If `cache_all_output` is set to `true`, every template including each individual template used as part of a collection will be cached separately. Additionally, anything within child, glue and partial will also be cached separately. To cache just a single template, see the section titled 'Caching' below. If `escape_all_output` is set to `true` and ActiveSupport is available, attribute output will be escaped using [ERB::Util.html_escape](http://corelib.rubyonrails.org/classes/ERB/Util.html). If `view_paths` is set to a path, this view path will be checked for every rabl template within your application. Add to this path especially when including Rabl in an engine and using view paths within a another Rails app. If `raise_on_missing_attribute` is set to `true`, a RuntimeError will be raised whenever Rabl attempts to render an attribute that does not exist. Otherwise, the attribute will simply be omitted. Setting this to true during development may help increase the robustness of your code, but using `true` in production code is not recommended. If `replace_nil_values_with_empty_strings` is set to `true`, all values that are `nil` and would normally be displayed as `null` in the response are converted to empty strings. If `exclude_nil_values` is set to `true`, all values that are `nil` and would normally be displayed as `null` in the response are not included in the response. if `exclude_empty_values_in_collections` is set to `true`, all vaules in a collection that are `{}` and would normally be displayed as `{}` in the response are not included in the response. If you wish to use [oj](https://github.com/ohler55/oj) as the primary JSON encoding engine simply add that to your Gemfile: ```ruby # Gemfile gem 'oj' ``` and RABL will use that engine automatically for encoding your JSON responses. Set your own custom json_engine which define a `dump` or `encode` method for converting to JSON from ruby data: ```ruby config.json_engine = ActiveSupport::JSON ``` ### Format Configuration ### RABL supports configuration for MessagePack, BSON, and Plist. Check the [Format Configuration](https://github.com/nesquena/rabl/wiki/Configuring-Formats) page for more details. ## Usage ## ### Object Assignment ### To declare the data object for use in the template: ```ruby # app/views/users/show.json.rabl object @user ``` or specify an alias for the object: ```ruby object @user => :person # => { "person" : { ... } } ``` or pass a collection of objects: ```ruby collection @users # => [ { "user" : { ... } } ] ``` or specify a root node label for the collection: ```ruby collection @users => :people # => { "people" : [ { "person" : { ... } } ] } ``` or even specify both the child and root labels for a collection: ```ruby collection @users, :root => "people", :object_root => "user" # => { "people" : [ { "user" : { ... } } ] } ``` and this will be used as the default data for the rendering, or disable the object root explicitly: ```ruby collection @users, :root => "people", :object_root => false # => { "people" : [ { ... }, { ... } ] } ``` There can also be odd cases where the root-level of the response doesn't map directly to any object: ```ruby object false node(:some_count) { |m| @user.posts.count } child(@user) { attribute :name } ``` In those cases, object can be assigned to 'false' and nodes can be constructed free-form. ### Attributes ### Basic usage of the templater to define a few simple attributes for the response: ```ruby # app/views/users/show.json.rabl attributes :id, :foo, :bar ``` or use with aliased attributes: ```ruby # Take the value of model attribute `foo` and name the node `bar` attribute :foo => :bar # => { bar : 5 } ``` or even multiple aliased attributes: ```ruby attributes :bar => :baz, :dog => :animal # => # { baz : , animal : } ``` or show attributes only if a condition is true: ```ruby # m is the object being rendered, also supports :unless attributes :foo, :bar, :if => lambda { |m| m.condition? } ``` Named and aliased attributes can not be combined on the same line. This currently does not work: ```ruby attributes :foo, :bar => :baz # throws exception ``` ### Child Nodes ### Often a response requires including nested information from data associated with the parent model: ```ruby child :address do attributes :street, :city, :zip, :state end ``` You can also disable object root for child node: ```ruby child :posts, :object_root => false do attributes :id, :title end ``` You can also add child nodes from an arbitrary data source: ```ruby child @posts => :foobar do attributes :id, :title end ``` or use model associations with an alias: ```ruby # Renders all the 'posts' association # from the model into a node called 'foobar' child :posts => :foobar do attributes :id, :title end ``` You can also pass in the current object: ```ruby object @user child :posts do |user| attribute :title unless user.suspended? end ``` ### Gluing Attributes ### You can also append child attributes back to the root node: ```ruby # Appends post_id and post_name to parent json object glue @post do attributes :id => :post_id, :name => :post_name end ``` Use glue to add additional attributes to the parent object. You can also pass in the current object: ```ruby object @user glue(@post) {|user| attribute :title if user.active? } ``` ### Custom Nodes ### This will generate a json response based on the result of the `node` block: ```ruby # app/views/users/show.json.rabl node :full_name do |u| u.first_name + " " + u.last_name end ``` or don't pass a name and have the node block merged into the response: ```ruby node do |u| { :full_name => u.first_name + " " + u.last_name } # => { full_name : "Bob Johnson" } end ``` You can use custom nodes like these to create flexible representations of a value utilizing all the data from the model. ### Partials ### Often you need to access other data objects in order to construct custom nodes in more complex associations. You can get access to the rabl representation of another data object by rendering a RABL partial: ```ruby node :location do { :city => @city, :address => partial("users/address", :object => @address) } end ``` or even access an object associated with the parent model: ```ruby node :location do |m| { :city => m.city, :address => partial("users/address", :object => m.address) } end ``` You can use this method to construct arbitrarily complex nodes for your APIs. Note that you need to have RABL templates defined for each of the objects you wish to construct representations for in this manner. ### Inheritance ### Another common issue of many template builders is unnecessary code redundancy. Typically many representations of an object across multiple endpoints share common attributes or nodes. The nodes for a 'post' object are probably the same or similar in most references throughout the various endpoints. RABL has the ability to extend other "base" rabl templates and additional attributes: ```ruby # app/views/users/advanced.json.rabl extends "users/base" # another RABL template in "app/views/users/base.json.rabl" node :can_drink do |m| m.age > 21 end ``` You can also extend other rabl templates while constructing child nodes to reduce duplication: ```ruby # app/views/users/show.json.rabl child @address do extends "address/item" end ``` Using partials and inheritance can significantly reduce code duplication in your templates. You can see more examples on the [Reusing Templates wiki page](https://github.com/nesquena/rabl/wiki/Reusing-templates). ### Passing Locals in Partials ### You can pass an arbitrary set of locals when rendering partials or extending templates. For example, if we want to show on `posts/:id.json` any information regarding particular post and associated comments but in other cases we want to hide those comments. We can use locals to do this: ```ruby # app/views/posts/index.json.rabl collection @posts extends('posts/show', :locals => { :hide_comments => true }) # or using partial instead of extends # node(false) { |post| partial('posts/show', :object => :post, :locals => { :hide_comments => true })} ``` and then access locals in the sub-template: ```ruby # app/views/posts/show.json.rabl object @post attributes :id, :title, :body, :created_at node(:comments) { |post| post.comments } unless locals[:hide_comments] ``` This can be useful as an advanced tool when extending or rendering partials. ### Conditions ### You can provide conditions to all kinds of nodes, attributes, extends, etc. which includes a given element only if the specified condition is true. ```ruby collection @posts # m is the object being rendered, also supports :unless node(:coolness, :if => lambda { |m| m.coolness > 5 }) do |m| m.coolness end ``` Because attributes take conditional options as well, we could simplify the example with: ```ruby collection @posts # m is the object being rendered, also supports :unless attribute(:coolness, :if => lambda { |m| m.coolness > 5 }) ``` The value for the `:if` and `:unless` options may be a simple `Boolean`, `Proc` or a `Symbol`. If it is a `Symbol` and the specific `@object` responds to its, the method will be called. Thus the example above can be rewritten as: ```ruby class Post def cool? coolness > 5 end end ``` and then: ```ruby collection @posts attribute :coolness, if: :cool? ``` Using conditions allows for easy control over when certain elements render. ### Template Scope ### In RABL, you have access to everything you need to build an API response. Each RABL template has full access to the controllers instance variables as well as all view helpers and routing urls. ```ruby # app/some/template.rabl object @post # Access instance variables child(@user => :user) { ... } # or Rails helpers node(:formatted_body) { |post| simple_format(post.body) } ``` There should be no problem fetching the appropriate data to construct a response. ### Deep Nesting ### In APIs, you can often need to construct 2nd or 3rd level nodes. Let's suppose we have a 'quiz' model that has many 'questions' and then each question has many 'answers'. We can display this hierarchy in RABL quite easily: ```ruby # app/views/quizzes/show.json.rabl object @quiz attribute :title child :questions do attribute :caption child :answers do # Use inheritance to reduce duplication extends "answers/item" end end ``` This will display the quiz object with nested questions and answers as you would expect with a quiz node, and embedded questions and answers. Note that RABL can be nested arbitrarily deep within child nodes to allow for these representations to be defined. ### Caching ### RABL has built-in caching support for templates leveraging fragment caching strategies. Note that caching is currently **only available** for Rails but support for other frameworks is planned in a future release. Simplest caching usage is: ```ruby # app/views/users/show.json.rabl object @quiz cache @quiz # key = rabl/quiz/[cache_key] attribute :title ``` Caching can significantly speed up the rendering of RABL templates in production and is strongly recommended when possible. For more a more detailed look at caching, check out the [Caching](https://github.com/nesquena/rabl/wiki/Caching-in-RABL) guide on the wiki. ### Rendering Templates Directly ### There are situations where an application requires RABL templates to be rendered outside a traditional view context. For instance, to render RABL within a Rake task or to create message queue payloads. For this case, `Rabl.render` can be used as show below: ```ruby Rabl.render(object, template, :view_path => 'app/views', :format => :json) #=> "{...json...}" ``` You can use convenience methods on `Rabl::Renderer` to render the objects as well: ```ruby Rabl::Renderer.json(@post, 'posts/show') Rabl::Renderer.xml(@post, 'posts/show') ``` These methods allow RABL to be used for arbitrary conversions of an object into a desired format. ```ruby Rabl::Renderer.new('posts/show', @post, :view_path => 'app/views', :format => 'hash').render ``` You can also pass in other instance variables to be used in your template as: ```ruby Rabl::Renderer.new('posts/show', @post, :locals => { :custom_title => "Hello world!" }) ```` Then, in your template, you can use `@custom_title` as: ``` attribute :content node(:title) { @custom_title } ``` ### Content Type Headers ### Currently in RABL, the content-type of your response is not set automatically. This is because RABL is intended to work for any Rack-based framework and as agnostic to format as possible. Check [this issue](https://github.com/nesquena/rabl/issues/185#issuecomment-4501232) for more details, and if you have any ideas or patches please let me know. In the meantime, be sure to set the proper content-types if needed. This is usually pretty simple in both Rails and Padrino. I recommend a before_filter on that controller or directly specified in an action. ## Resources ## There are many resources available relating to RABL including the [RABL Wiki](https://github.com/nesquena/rabl/wiki), and many tutorials and guides detailed below. You can check out the [RABL Site](http://nesquena.github.com/rabl) as well. ### Advanced Usage ### Links to resources for advanced usage: * [Managing Complexity](https://github.com/nesquena/rabl/wiki/Managing-complexity-with-presenters) * [Production Optimizations](https://github.com/nesquena/rabl/wiki/Rabl-In-Production) * [Grape Integration](https://github.com/nesquena/rabl/wiki/Using-Rabl-with-Grape) * [Rendering JSON for a tree structure using RABL](https://github.com/nesquena/rabl/issues/70) * [Layouts (erb, haml and rabl) in RABL](https://github.com/nesquena/rabl/wiki/Using-Layouts) * [Backbone or Ember.js Integration](https://github.com/nesquena/rabl/wiki/Backbone-Integration) * [RABL with Rails Engines](https://github.com/nesquena/rabl/wiki/Setup-rabl-with-rails-engines) Please add your own usages and let me know so we can add them here! Also be sure to check out the [RABL Wiki](https://github.com/nesquena/rabl/wiki) for other usages. ### Tutorials ### Tutorials can always be helpful when first getting started: * [Railscasts #322](http://railscasts.com/episodes/322-rabl) - Ryan Bates explains RABL * [BackboneRails](http://www.backbonerails.com/) - Great screencasts by Brian Mann * [Creating an API with RABL and Padrino](http://blog.crowdint.com/2012/10/22/rabl-with-padrino.html) * http://blog.joshsoftware.com/2011/12/23/designing-rails-api-using-rabl-and-devise/ * http://engineering.gomiso.com/2011/06/27/building-a-platform-api-on-rails/ * http://blog.lawrencenorton.com/better-json-requests-with-rabl * http://www.rodrigoalvesvieira.com/developing-json-api-rails-rabl/ * http://tech.favoritemedium.com/2011/06/using-rabl-in-rails-json-web-api.html * http://seesparkbox.com/foundry/better_rails_apis_with_rabl * http://blog.dcxn.com/2011/06/22/rails-json-templates-through-rabl * http://teohm.github.com/blog/2011/05/31/using-rabl-in-rails-json-web-api Let me know if there's any other useful resources not listed here. ### Related Libraries ### There are other libraries that can either complement or extend the functionality of RABL: * [versioncake](https://github.com/bwillis/versioncake) - Excellent library for easily versioning your RABL APIs * [gon](https://github.com/gazay/gon) - Exposes your Rails variables in JS with RABL support integrated. * [rabl-rails](https://github.com/ccocchi/rabl-rails) - Reimplementation for RABL and Rails [focused on speed](https://github.com/ccocchi/rabl-benchmark/blob/master/BENCHMARK). Let me know if there's any other related libraries not listed here. ### Troubleshooting ### * [Redundant calls for a collection](https://github.com/nesquena/rabl/issues/142#issuecomment-2969107) * [Testing RABL Views](https://github.com/nesquena/rabl/issues/130#issuecomment-4179285) ### Examples ### See the [examples](https://github.com/nesquena/rabl/tree/master/examples) directory. ## Issues ## Check out the [Issues](https://github.com/nesquena/rabl/issues) tab for a full list: * Rigorous benchmarking and performance optimizations ## Authors and Contributors ## Active Maintainers: * [Douwe Maan](https://github.com/DouweM) * [Nathan Esquenazi](https://github.com/nesquena) Thanks to [Miso](http://gomiso.com) for allowing me to create this for our applications and release this project! * [Nathan Esquenazi](https://github.com/nesquena) - Creator of the project * [Arthur Chiu](https://github.com/achiu) - Core Maintainer, Riot Testing Guru * [Tim Lee](https://github.com/timothy1ee) - RABL was a great name chosen by the Miso CTO. * [Douwe Maan](https://github.com/DouweM) - Multi support for caching, fixed test suite * [Andrew Latimer](https://github.com/ahlatimer) - Multi support for caching * [David Sommers](https://github.com/databyte) - Template resolution, caching support, and much more * [Rick Thomas](https://github.com/rickthomasjr) - Added options for extends and Sinatra testing * [Benjamin Yu](https://github.com/byu) - Added msgpack format support * [Chris Kimpton](https://github.com/kimptoc) - Helping with documentation and wiki * [Marjun](https://github.com/mpagalan) - Added xml option configurations * [Anton Orel](https://github.com/skyeagle) - Added Rails 3.1 compatibility * [Sasha Koss](https://github.com/kossnocorp) - Added multi_json support * [Matthew Schulkind](https://github.com/mschulkind) - Cleanup of configuration and tests * [Luke van der Hoeven](https://github.com/plukevdh) - Support non-ORM objects in templates * [Andrey Voronkov](https://github.com/Antiarchitect) - Added BSON format support * [Alli Witheford](https://github.com/alzeih) - Added Plist format support * [Ryan Bigg](https://github.com/radar) - Improved template resolution code * [Ivan Vanderbyl](https://github.com/ivanvanderbyl) - Added general purpose renderer * [Cyril Mougel](https://github.com/shingara) - Added cache_engine pluggable support and renderer tweaks * [Teng Siong Ong](https://github.com/siong1987) - Improved renderer interface * [Brad Dunbar](https://github.com/braddunbar) - Pass current object into blocks and many more contributors listed in the [CHANGELOG](https://github.com/nesquena/rabl/blob/master/CHANGELOG.md). Want to contribute support for another format? Check out the patches for [msgpack support](https://github.com/nesquena/rabl/pull/69), [plist support](https://github.com/nesquena/rabl/pull/153) and [BSON support](https://github.com/nesquena/rabl/pull/163) for reference. Please fork and contribute, any help in making this project better is appreciated! This project is a member of the [OSS Manifesto](http://ossmanifesto.org). ## Inspirations ## There are a few excellent libraries that helped inspire RABL and they are listed below: * [Tequila](https://github.com/inem/tequila) * [JSON Builder](https://github.com/dewski/json_builder) * [Argonaut](https://github.com/jbr/argonaut) Thanks again for all of these great projects. ## Copyright ## Copyright © 2011-2013 Nathan Esquenazi. See [MIT-LICENSE](https://github.com/nesquena/rabl/blob/master/MIT-LICENSE) for details.