rabl 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1,4 +1,5 @@
1
1
  *.gem
2
2
  .bundle
3
+ .rvmrc
3
4
  Gemfile.lock
4
5
  pkg/*
data/README.md CHANGED
@@ -25,6 +25,12 @@ or add to your Gemfile:
25
25
 
26
26
  and run `bundle install` to install the dependency.
27
27
 
28
+ If you are using Rails 2.X or Padrino, RABL works out of the box. With Sinatra, or any other tilt-based framework, simply register:
29
+
30
+ Rabl.register!
31
+
32
+ and RABL will be initialized.
33
+
28
34
  ## Usage ##
29
35
 
30
36
  ### Object Assignment ###
data/Rakefile CHANGED
@@ -1,2 +1,10 @@
1
1
  require 'bundler'
2
2
  Bundler::GemHelper.install_tasks
3
+
4
+ require 'rake/testtask'
5
+ Rake::TestTask.new(:test) do |test|
6
+ test.libs << 'lib' << 'test'
7
+ test.pattern = 'test/**/*_test.rb'
8
+ test.verbose = true
9
+ test.ruby_opts = ['-rubygems']
10
+ end
data/lib/rabl.rb CHANGED
@@ -1,8 +1,19 @@
1
1
  require 'rabl/version'
2
2
  require 'rabl/engine'
3
3
  require 'rabl/builder'
4
- require 'rabl/template' if defined?(Rails)
5
4
 
5
+ # Rabl.register!
6
6
  module Rabl
7
- # Nothing yet
7
+ def self.register!
8
+ require 'rabl/template' if defined?(Rails)
9
+ require 'rabl/register'
10
+ end
8
11
  end
12
+
13
+ # Register
14
+ if defined?(Padrino)
15
+ require 'padrino-core'
16
+ Padrino.after_load { Rabl.register! }
17
+ else
18
+ Rabl.register!
19
+ end
data/lib/rabl/builder.rb CHANGED
@@ -32,7 +32,7 @@ module Rabl
32
32
  end if @options.has_key?(:extends)
33
33
 
34
34
  @_root_name ||= @_object.class.model_name.element
35
- options[:root] ? { @_root_name => @_result } : @_result
35
+ (@options[:root] || options[:root]) ? { @_root_name => @_result } : @_result
36
36
  end
37
37
 
38
38
  # Indicates an attribute or method should be included in the json output
@@ -74,18 +74,11 @@ module Rabl
74
74
  @_result.merge!(glued_attributes)
75
75
  end
76
76
 
77
- # Renders a partial hash based on another rabl template
78
- # partial("users/show", :object => @user)
79
- def partial(file, options={}, &block)
80
- source = File.read(Rails.root.join("app/views/" + file + ".json.rabl"))
81
- self.object_to_hash(options[:object], source, &block)
82
- end
83
-
84
77
  # Extends an existing rabl template with additional attributes in the block
85
78
  # extends("users/show") { attribute :full_name }
86
79
  def extends(file, options={}, &block)
87
80
  options = options.merge!(:object => @_object)
88
- result = partial(file, options, &block)
81
+ result = @options[:engine].partial(file, options, &block)
89
82
  @_result.merge!(result)
90
83
  end
91
84
 
@@ -110,7 +103,7 @@ module Rabl
110
103
  # data_name(@users) => :user
111
104
  def data_name(data)
112
105
  return data.values.first if data.is_a?(Hash)
113
- return data.first.class.model_name.element.pluralize if data.first.is_a?(ActiveRecord::Base)
106
+ return data.first.class.model_name.element.pluralize if data.respond_to?(:first) && data.first.respond_to?(:valid?)
114
107
  data.class.model_name.element
115
108
  end
116
109
  end
data/lib/rabl/engine.rb CHANGED
@@ -1,15 +1,23 @@
1
1
  module Rabl
2
2
  class Engine
3
3
  # Constructs a new ejs engine based on given vars, handler and declarations
4
- def initialize(vars, handler, source_string=nil, &block)
5
- @_vars = vars
6
- @_handler = handler
7
- @_options = { :handler => @_handler, :vars => @_vars, :engine => self }
8
- self.copy_instance_variables_from(@_handler, [:@assigns, :@helpers]);
9
- @_object = vars[:object] || self.default_object
10
- # raise @user.inspect + " - " + @_handler.instance_variable_get(:@options).inspect + " - " + @_handler.inspect
11
- instance_eval(source_string) if source_string.present?
4
+ # Rabl::Engine.new("...source...", { :format => "xml" })
5
+ def initialize(source, options={})
6
+ @_source = source
7
+ @_options = options.reverse_merge(:format => "json")
8
+ end
9
+
10
+ # Renders the representation based on source, object, scope and locals
11
+ # Rabl::Engine.new("...source...", { :format => "xml" }).render(scope, { :foo => "bar", :object => @user })
12
+ def render(scope, locals, &block)
13
+ @_locals = locals
14
+ @_scope = scope
15
+ @_options = @_options.merge(:scope => @_scope, :locals => @_locals, :engine => self)
16
+ self.copy_instance_variables_from(@_scope, [:@assigns, :@helpers]);
17
+ @_object = locals[:object] || self.default_object
18
+ instance_eval(@_source) if @_source.present?
12
19
  instance_eval(&block) if block_given?
20
+ self.send("to_" + @_options[:format])
13
21
  end
14
22
 
15
23
  # Sets the object to be used as the data source for this template
@@ -63,14 +71,14 @@ module Rabl
63
71
  # Renders a partial hash based on another rabl template
64
72
  # partial("users/show", :object => @user)
65
73
  def partial(file, options={}, &block)
66
- source = File.read(Rails.root.join("app/views/" + file + ".json.rabl"))
74
+ source = self.fetch_source(file)
67
75
  self.object_to_hash(options[:object], source, &block)
68
76
  end
69
77
 
70
78
  # Returns a hash representation of the data object
71
79
  # to_hash(:root => true)
72
80
  def to_hash(options={})
73
- if @_object.is_a?(ActiveRecord::Base)
81
+ if is_record?(@_object)
74
82
  Rabl::Builder.new(@_object, @_options).to_hash(options)
75
83
  elsif @_object.respond_to?(:each)
76
84
  @_object.map { |object| Rabl::Builder.new(object, @_options).to_hash(options) }
@@ -80,24 +88,39 @@ module Rabl
80
88
  # Returns a json representation of the data object
81
89
  # to_json(:root => true)
82
90
  def to_json(options={})
83
- options.reverse_merge!(:root => true)
91
+ options = options.reverse_merge(:root => true)
84
92
  to_hash(options).to_json
85
93
  end
86
94
 
87
95
  # Returns a hash based representation of any data object given ejs template block
88
96
  # object_to_hash(@user) { attribute :full_name } => { ... }
89
97
  def object_to_hash(object, source=nil, &block)
90
- return object unless object.is_a?(ActiveRecord::Base) || object.first.is_a?(ActiveRecord::Base)
91
- self.class.new(@_vars.merge(:object => object), @_handler, source, &block).to_hash(:root => false)
98
+ return object unless is_record?(object) || is_record?(object.respond_to?(:first) && object.first)
99
+ self.class.new(source, :format => "hash", :root => false).render(@_scope, :object => object, &block)
92
100
  end
93
101
 
94
102
  protected
95
103
 
96
104
  # Returns a guess at the default object for this template
97
105
  def default_object
98
- @_handler.respond_to?(:controller) ?
99
- instance_variable_get("@#{@_handler.controller.controller_name}") :
106
+ @_scope.respond_to?(:controller) ?
107
+ instance_variable_get("@#{@_scope.controller.controller_name}") :
100
108
  nil
101
109
  end
110
+
111
+ # Returns true if item is a ORM record; false otherwise
112
+ def is_record?(obj)
113
+ obj && obj.respond_to?(:valid?)
114
+ end
115
+
116
+ # Returns source for a given relative file
117
+ # fetch_source("show") => "...contents..."
118
+ def fetch_source(file)
119
+ root_path = Rails.root if defined?(Rails)
120
+ root_path = Padrino.root if defined?(Padrino)
121
+ view_path = File.join(root_path, "app/views/")
122
+ file_path = Dir[File.join(view_path, file + "*.rabl")].first
123
+ File.read(file_path) if file_path
124
+ end
102
125
  end
103
126
  end
@@ -0,0 +1,20 @@
1
+ ## TILT ##
2
+ if defined?(Tilt)
3
+ class RablTemplate < Tilt::Template
4
+ def initialize_engine
5
+ return if defined?(::Rabl)
6
+ require_template_library 'rabl'
7
+ end
8
+
9
+ def prepare
10
+ options = @options.merge(:format => "json")
11
+ @engine = ::Rabl::Engine.new(data, options)
12
+ end
13
+
14
+ def evaluate(scope, locals, &block)
15
+ @engine.render(scope, locals, &block)
16
+ end
17
+ end
18
+
19
+ Tilt.register 'rabl', RablTemplate
20
+ end
data/lib/rabl/template.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # Rails Template
2
+
1
3
  require 'action_view/base'
2
4
  require 'action_view/template'
3
5
 
@@ -7,9 +9,8 @@ module ActionView
7
9
  include Compilable
8
10
 
9
11
  def compile(template) %{
10
- ::Rabl::Engine.new(assigns.merge(local_assigns), self) do
11
- #{template.source}
12
- end.to_#{template.format}
12
+ ::Rabl::Engine.new(#{template.source.inspect}, { :format => #{template.format.inspect} }).
13
+ render(self, assigns.merge(local_assigns))
13
14
  } end
14
15
  end
15
16
  end
data/lib/rabl/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Rabl
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
data/rabl.gemspec CHANGED
@@ -18,4 +18,7 @@ Gem::Specification.new do |s|
18
18
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
19
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
20
  s.require_paths = ["lib"]
21
+
22
+ s.add_development_dependency 'riot', '~>0.12.3'
23
+ s.add_development_dependency 'rr', '~>1.0.2'
21
24
  end
data/test.watchr ADDED
@@ -0,0 +1,48 @@
1
+ ENV["WATCHR"] = "1"
2
+ system 'clear'
3
+
4
+ def run(cmd)
5
+ puts(cmd)
6
+ system cmd
7
+ end
8
+
9
+ def run_test_file(file)
10
+ system('clear')
11
+ run(%Q(ruby -I"lib:test" -rubygems #{file}))
12
+ end
13
+
14
+ def run_all_tests
15
+ system('clear')
16
+ run('rake test')
17
+ end
18
+
19
+ def related_test_files(path)
20
+ Dir['test/**/*.rb'].select { |file| file =~ /#{File.basename(path).split(".").first}_test.rb/ }
21
+ end
22
+
23
+ watch('test/teststrap\.rb') { run_all_tests }
24
+ watch('test/(.*).*_test\.rb') { |m| run_test_file(m[0]) }
25
+ watch('lib/.*/.*\.rb') { |m| related_test_files(m[0]).map {|tf| run_test_file(tf) } }
26
+
27
+ # Ctrl-\
28
+ Signal.trap 'QUIT' do
29
+ puts " --- Running all tests ---\n\n"
30
+ run_all_tests
31
+ end
32
+
33
+ @interrupted = false
34
+
35
+ # Ctrl-C
36
+ Signal.trap 'INT' do
37
+ if @interrupted then
38
+ @wants_to_quit = true
39
+ abort("\n")
40
+ else
41
+ puts "Interrupt a second time to quit"
42
+ @interrupted = true
43
+ Kernel.sleep 1.5
44
+ # raise Interrupt, nil # let the run loop catch it
45
+ run_all_tests
46
+ end
47
+ end
48
+
@@ -0,0 +1 @@
1
+ require File.expand_path('../teststrap',__FILE__)
@@ -0,0 +1,2 @@
1
+ require File.expand_path('../teststrap',__FILE__)
2
+
@@ -0,0 +1,2 @@
1
+ require File.expand_path('../teststrap',__FILE__)
2
+
data/test/teststrap.rb ADDED
@@ -0,0 +1,11 @@
1
+ require 'riot'
2
+ require 'riot/rr'
3
+ require File.expand_path('../../lib/rabl',__FILE__)
4
+
5
+ Riot.pretty_dots
6
+
7
+ class Riot::Situation
8
+ end
9
+
10
+ class Riot::Context
11
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rabl
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 21
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 4
10
- version: 0.0.4
9
+ - 5
10
+ version: 0.0.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - Nathan Esquenazi
@@ -16,8 +16,39 @@ bindir: bin
16
16
  cert_chain: []
17
17
 
18
18
  date: 2011-04-12 00:00:00 Z
19
- dependencies: []
20
-
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: riot
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ hash: 41
29
+ segments:
30
+ - 0
31
+ - 12
32
+ - 3
33
+ version: 0.12.3
34
+ type: :development
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: rr
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ hash: 19
45
+ segments:
46
+ - 1
47
+ - 0
48
+ - 2
49
+ version: 1.0.2
50
+ type: :development
51
+ version_requirements: *id002
21
52
  description: General ruby templating for json or xml
22
53
  email:
23
54
  - nesquena@gmail.com
@@ -35,9 +66,15 @@ files:
35
66
  - lib/rabl.rb
36
67
  - lib/rabl/builder.rb
37
68
  - lib/rabl/engine.rb
69
+ - lib/rabl/register.rb
38
70
  - lib/rabl/template.rb
39
71
  - lib/rabl/version.rb
40
72
  - rabl.gemspec
73
+ - test.watchr
74
+ - test/builder_test.rb
75
+ - test/engine_test.rb
76
+ - test/template_test.rb
77
+ - test/teststrap.rb
41
78
  homepage: https://github.com/nesquena/rabl
42
79
  licenses: []
43
80
 
@@ -71,5 +108,8 @@ rubygems_version: 1.7.2
71
108
  signing_key:
72
109
  specification_version: 3
73
110
  summary: General ruby templating for json or xml
74
- test_files: []
75
-
111
+ test_files:
112
+ - test/builder_test.rb
113
+ - test/engine_test.rb
114
+ - test/template_test.rb
115
+ - test/teststrap.rb