brentano 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
1
  source "http://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in brentano.gemspec
4
- gemspec
4
+ gemspec
@@ -0,0 +1,94 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ brentano (0.0.1)
5
+ activerecord (~> 3)
6
+ activesupport (~> 3)
7
+ hashie (>= 0.4)
8
+ railties (~> 3)
9
+
10
+ GEM
11
+ remote: http://rubygems.org/
12
+ specs:
13
+ abstract (1.0.0)
14
+ actionmailer (3.0.7)
15
+ actionpack (= 3.0.7)
16
+ mail (~> 2.2.15)
17
+ actionpack (3.0.7)
18
+ activemodel (= 3.0.7)
19
+ activesupport (= 3.0.7)
20
+ builder (~> 2.1.2)
21
+ erubis (~> 2.6.6)
22
+ i18n (~> 0.5.0)
23
+ rack (~> 1.2.1)
24
+ rack-mount (~> 0.6.14)
25
+ rack-test (~> 0.5.7)
26
+ tzinfo (~> 0.3.23)
27
+ activemodel (3.0.7)
28
+ activesupport (= 3.0.7)
29
+ builder (~> 2.1.2)
30
+ i18n (~> 0.5.0)
31
+ activerecord (3.0.7)
32
+ activemodel (= 3.0.7)
33
+ activesupport (= 3.0.7)
34
+ arel (~> 2.0.2)
35
+ tzinfo (~> 0.3.23)
36
+ activeresource (3.0.7)
37
+ activemodel (= 3.0.7)
38
+ activesupport (= 3.0.7)
39
+ activesupport (3.0.7)
40
+ arel (2.0.9)
41
+ builder (2.1.2)
42
+ diff-lcs (1.1.2)
43
+ erubis (2.6.6)
44
+ abstract (>= 1.0.0)
45
+ hashie (1.0.0)
46
+ i18n (0.5.0)
47
+ mail (2.2.19)
48
+ activesupport (>= 2.3.6)
49
+ i18n (>= 0.4.0)
50
+ mime-types (~> 1.16)
51
+ treetop (~> 1.4.8)
52
+ mime-types (1.16)
53
+ polyglot (0.3.1)
54
+ rack (1.2.2)
55
+ rack-mount (0.6.14)
56
+ rack (>= 1.0.0)
57
+ rack-test (0.5.7)
58
+ rack (>= 1.0)
59
+ rails (3.0.7)
60
+ actionmailer (= 3.0.7)
61
+ actionpack (= 3.0.7)
62
+ activerecord (= 3.0.7)
63
+ activeresource (= 3.0.7)
64
+ activesupport (= 3.0.7)
65
+ bundler (~> 1.0)
66
+ railties (= 3.0.7)
67
+ railties (3.0.7)
68
+ actionpack (= 3.0.7)
69
+ activesupport (= 3.0.7)
70
+ rake (>= 0.8.7)
71
+ thor (~> 0.14.4)
72
+ rake (0.8.7)
73
+ rspec (2.6.0)
74
+ rspec-core (~> 2.6.0)
75
+ rspec-expectations (~> 2.6.0)
76
+ rspec-mocks (~> 2.6.0)
77
+ rspec-core (2.6.0)
78
+ rspec-expectations (2.6.0)
79
+ diff-lcs (~> 1.1.2)
80
+ rspec-mocks (2.6.0)
81
+ sqlite3 (1.3.3)
82
+ thor (0.14.6)
83
+ treetop (1.4.9)
84
+ polyglot (>= 0.3.1)
85
+ tzinfo (0.3.27)
86
+
87
+ PLATFORMS
88
+ ruby
89
+
90
+ DEPENDENCIES
91
+ brentano!
92
+ rails (= 3.0.7)
93
+ rspec (~> 2)
94
+ sqlite3 (~> 1.3.3)
@@ -12,12 +12,16 @@ Gem::Specification.new do |s|
12
12
  s.summary = %q{Classy presenters for Rails 3}
13
13
  s.description = %q{Brentano helps you present ActiveRecord collections to your controllers and avoid repetitive ORM logic}
14
14
 
15
- s.rubyforge_project = "brentano"
16
-
17
- s.add_dependency "activesupport", "~> 3.0"
18
- s.add_dependency "activerecord", "~> 3.0"
19
- s.add_dependency "actionpack", "~> 3.0"
20
- s.add_dependency "hashie", "~> 0.4"
15
+ s.rubyforge_project = "Brentano"
16
+
17
+ s.add_dependency "activesupport", "~> 3"
18
+ s.add_dependency "activerecord", "~> 3"
19
+ s.add_dependency "railties", "~> 3"
20
+ s.add_dependency "hashie", ">= 0.4"
21
+
22
+ s.add_development_dependency "rails", '3.0.7'
23
+ s.add_development_dependency "sqlite3", "~> 1.3.3"
24
+ s.add_development_dependency "rspec", "~> 2"
21
25
 
22
26
  s.files = `git ls-files`.split("\n")
23
27
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -1,21 +1,21 @@
1
- require 'brentano/rails'
1
+ require 'brentano/railtie'
2
2
 
3
3
  module Brentano
4
-
4
+
5
5
  autoload :Presenter, 'brentano/presenter'
6
6
  autoload :Query, 'brentano/query'
7
-
7
+
8
8
  mattr_accessor :query_limit
9
9
  @@query_limit = 20
10
-
10
+
11
11
  mattr_accessor :qualifier_key
12
12
  @@qualifier_key = :options
13
-
13
+
14
14
  mattr_accessor :presenter_module
15
- @@presenter_module = "Presenters"
16
-
15
+ @@presenter_module = "Presenters"
16
+
17
17
  def config
18
18
  yield self
19
19
  end
20
-
21
- end
20
+
21
+ end
@@ -1,13 +1,15 @@
1
+ require 'hashie'
2
+
1
3
  module Brentano
2
4
  class Presenter
3
-
5
+
4
6
  class_attribute :sizes
5
7
 
6
8
  attr_reader :subject, :options, :collection, :maximum_size
7
9
 
8
10
  alias_method :proxy_respond_to?, :respond_to?
9
11
 
10
- def initialize(subject, options, &blk)
12
+ def initialize(subject, options = {}, &blk)
11
13
  @subject = subject
12
14
  @options = Hashie::Mash.new(options)
13
15
  yield self if block_given?
@@ -22,7 +24,7 @@ module Brentano
22
24
  @maximum_size = if size.is_a? Fixnum
23
25
  size
24
26
  else
25
- sizes[size]
27
+ sizes[size]
26
28
  end
27
29
  options.limit = @maximum_size
28
30
  end
@@ -53,6 +55,6 @@ module Brentano
53
55
  def to_sql
54
56
  @collection.to_sql
55
57
  end
56
-
58
+
57
59
  end
58
60
  end
@@ -3,38 +3,38 @@
3
3
  # queries from request params
4
4
  module Brentano
5
5
  class Query
6
-
6
+
7
7
  attr_accessor_with_default :allowed_methods, [:limit, :offset].freeze
8
8
  attr_accessor_with_default :allowed_scopes, [].freeze
9
9
  attr_accessor_with_default :absolute_limit, Brentano.query_limit
10
-
10
+
11
11
  def self.finish(relation, options)
12
- obj = new relation
12
+ obj = self.new relation
13
13
  yield obj if block_given?
14
14
  obj.apply options
15
15
  end
16
-
17
- def apply(options)
16
+
17
+ def apply(options)
18
18
  supplied_scopes = Array.wrap(options[:scopes] || options[:scope])
19
19
  supplied_scopes << "by_#{options[:by]}" if options[:by].present?
20
20
  supplied_scopes.map!(&:to_sym)
21
21
  scopes = allowed_scopes & supplied_scopes
22
- scoped_relation = scopes.inject(@relation) { |r, s| r.send(s) }
22
+ scoped_relation = scopes.inject(@relation) { |r, s| r.send(s) }
23
23
  if absolute_limit.present?
24
24
  options[:limit] ||= absolute_limit
25
25
  options[:limit] = [ options[:limit].to_i, absolute_limit ].min
26
26
  end
27
27
  options[:offset] &&= options[:offset].to_i
28
28
  options[:limit] &&= options[:limit].to_i
29
- allowed_methods.inject(scoped_relation) do |r, m|
29
+ allowed_methods.inject(scoped_relation) do |r, m|
30
30
  r = r.send(m, options[m]) if options[m].present?
31
31
  r
32
32
  end
33
33
  end
34
-
34
+
35
35
  def initialize(relation)
36
36
  @relation = relation
37
37
  end
38
-
38
+
39
39
  end
40
40
  end
@@ -1,14 +1,13 @@
1
- require 'brentano/rails/helpers'
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'rails', 'helpers')
2
2
 
3
3
  module Brentano
4
4
  class Railtie < ::Rails::Railtie
5
-
6
- initializer 'brentano.extend_action_contrller' do
5
+
6
+ initializer 'brentano.extend_action_controller' do
7
7
  ActiveSupport.on_load(:action_controller) do
8
8
  self.send :include, Brentano::Helpers
9
9
  end
10
10
  end
11
-
12
- end
13
- end
14
11
 
12
+ end
13
+ end
@@ -1,3 +1,3 @@
1
1
  module Brentano
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -1,10 +1,10 @@
1
1
  module Brentano
2
2
  module Helpers
3
-
4
- def presenter(klass_name, subject, options = params[Brentano.qualifier_key], &blk)
3
+
4
+ def presenter(klass_name, subject, options = params[Brentano.qualifier_key], &blk)
5
5
  klass = "#{Brentano.presenter_module}::#{klass_name.to_s.camelcase}".constantize
6
6
  klass.new subject, options, &blk
7
7
  end
8
-
8
+
9
9
  end
10
10
  end
@@ -0,0 +1,164 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe TestPresenter do
4
+
5
+ before { @subject = Post.first }
6
+
7
+ describe ".new" do
8
+
9
+ it "sets the subject instance variable" do
10
+ presenter = TestPresenter.new @subject
11
+ presenter.subject.should == @subject
12
+ end
13
+
14
+ context "when options are passed" do
15
+ before do
16
+ @options = { :limit => 10 }
17
+ @presenter = TestPresenter.new @subject, @options
18
+ end
19
+
20
+ it "sets the options instance variable" do
21
+ @presenter.options.with_indifferent_access.should == @options.with_indifferent_access
22
+ end
23
+
24
+ it "makes the options into a Hashie Mash" do
25
+ @presenter.options.should be_a(Hashie::Mash)
26
+ end
27
+
28
+ end
29
+
30
+ it "calls #finish" do
31
+ TestPresenter.any_instance.should_receive(:finish)
32
+ TestPresenter.new @subject
33
+ end
34
+
35
+ context "when a block is given" do
36
+ out = nil
37
+ it "yields self to the block" do
38
+ presenter = TestPresenter.new @subject do |obj|
39
+ out = obj
40
+ end
41
+ presenter.should equal(out)
42
+ end
43
+ end
44
+ end
45
+
46
+ describe "#finish" do
47
+ before { @presenter = TestPresenter.new @subject }
48
+ specify { @presenter.collection.should be }
49
+ end
50
+
51
+ describe "#maximum_size=" do
52
+ before { @presenter = TestPresenter.new @subject }
53
+
54
+ context "when the size is a Fixnum" do
55
+ before do
56
+ @size = 3
57
+ @presenter.maximum_size = @size
58
+ end
59
+
60
+ it "sets the maximum size instance variable to the size" do
61
+ @presenter.maximum_size.should eql(@size)
62
+ end
63
+
64
+ it "sets the limit option to the size" do
65
+ @presenter.options.limit.should eql(@size)
66
+ end
67
+ end
68
+
69
+ context "when the size is not a Fixnum" do
70
+ before do
71
+ @size = size = 4
72
+ @presenter.class_eval do
73
+ self.sizes = { :large => size }
74
+ end
75
+ @presenter.maximum_size = :large
76
+ end
77
+
78
+ it "sets the corresponding size" do
79
+ @presenter.maximum_size.should eql(@size)
80
+ end
81
+ end
82
+ end
83
+
84
+ describe "#respond_to?" do
85
+ before { @presenter = TestPresenter.new @subject }
86
+
87
+ context "given the presenter responds to the method" do
88
+ before { @presenter.stub(:foo) { "ok" } }
89
+ specify { @presenter.respond_to?(:foo).should be_true }
90
+ end
91
+
92
+ context "given the presenter does not respond to the method" do
93
+ before { @presenter.stub(:proxy_respond_to?) { |method| false } }
94
+
95
+ context "and the collection responds to the method" do
96
+ specify { @presenter.respond_to?(:find).should be_true }
97
+ end
98
+
99
+ context "and the collection does not respond to the method" do
100
+ before { @presenter.collection.stub(:respond_to?) { |method| false } }
101
+ specify { @presenter.respond_to?(:foo).should be_false }
102
+ end
103
+ end
104
+ end
105
+
106
+ describe "#method_missing" do
107
+ before do
108
+ @presenter = TestPresenter.new @subject
109
+ end
110
+
111
+ context "given the collection responds to the method" do
112
+
113
+ context "and the method returns an ActiveRecord::Relation" do
114
+ before do
115
+ @presenter.maximum_size = 2
116
+ @presenter.instance_variable_set :@options, :awesome => true
117
+ @method = [:limit, 1]
118
+ @result = @presenter.method_missing(*@method)
119
+ end
120
+ subject { @result }
121
+
122
+ describe "the result" do
123
+ specify { should be_a_kind_of Brentano::Presenter }
124
+
125
+ it "should have the same maximum size as receiver" do
126
+ @presenter.maximum_size.should eql(@result.maximum_size)
127
+ end
128
+
129
+ it "should have the same options as the receiver" do
130
+ @presenter.options.should eql(@result.options)
131
+ end
132
+
133
+ it "should have the collection set to the returned ActiveRecord::Relation" do
134
+ # Use #to_sql to compare the same method on the presenters collection
135
+ @result.collection.to_sql.should eql(@presenter.collection.send(*@method).to_sql)
136
+ end
137
+ end
138
+ end
139
+
140
+ context "and the method does not return an ActiveRecord::Relation" do
141
+ describe "the result" do
142
+ it "should be the same as if the method was sent to the collection directly" do
143
+ @presenter.method_missing(:to_a).should eql(@presenter.collection.to_a)
144
+ end
145
+ end
146
+ end
147
+ end
148
+ end
149
+
150
+ describe "#as_json" do
151
+ before { @presenter = TestPresenter.new @subject }
152
+ it "delegates to the collection" do
153
+ @presenter.as_json.should eql(@presenter.collection.as_json)
154
+ end
155
+ end
156
+
157
+ describe "#to_sql" do
158
+ before { @presenter = TestPresenter.new @subject }
159
+ it "delegates to the collection" do
160
+ @presenter.to_sql.should eql(@presenter.collection.to_sql)
161
+ end
162
+ end
163
+
164
+ end
@@ -0,0 +1 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
@@ -0,0 +1,26 @@
1
+ SPEC_DIR = File.dirname(__FILE__)
2
+ lib_path = File.expand_path("#{SPEC_DIR}/../lib")
3
+ $LOAD_PATH.unshift lib_path unless $LOAD_PATH.include?(lib_path)
4
+
5
+ require 'rails'
6
+ require 'active_record'
7
+ require 'active_support/core_ext'
8
+
9
+ require 'brentano'
10
+
11
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
12
+
13
+ RSpec.configure do |config|
14
+
15
+ config.before(:all) do
16
+ TestMigration.up
17
+ post = Post.new
18
+ 50.times { post.comments << Comment.new }
19
+ post.save
20
+ end
21
+
22
+ config.after(:all) do
23
+ TestMigration.down
24
+ end
25
+
26
+ end
@@ -0,0 +1,29 @@
1
+ dbconfig = {
2
+ :adapter => 'sqlite3',
3
+ :database => ':memory:'
4
+ }
5
+
6
+ ActiveRecord::Base.establish_connection(dbconfig)
7
+ ActiveRecord::Migration.verbose = false
8
+
9
+ class TestMigration < ActiveRecord::Migration
10
+ def self.up
11
+ create_table :posts, :force => true
12
+ create_table :comments, :force => true do |t|
13
+ t.references :post
14
+ end
15
+ end
16
+
17
+ def self.down
18
+ drop_table :posts
19
+ drop_table :comments
20
+ end
21
+ end
22
+
23
+ class Post < ActiveRecord::Base
24
+ has_many :comments
25
+ end
26
+
27
+ class Comment < ActiveRecord::Base
28
+ belongs_to :post
29
+ end
@@ -0,0 +1,22 @@
1
+ class TestPresenter < Brentano::Presenter
2
+
3
+ self.sizes = {
4
+ :large => 4
5
+ }
6
+
7
+ def relation
8
+ subject.comments
9
+ end
10
+
11
+ end
12
+
13
+ module CustomFinisher
14
+
15
+ def finish
16
+ super do |with|
17
+ with.absolute_limit = false
18
+ with.allowed_scopes = [ :by_rank ]
19
+ end
20
+ end
21
+
22
+ end
metadata CHANGED
@@ -1,12 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brentano
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 0
8
- - 1
9
- version: 0.0.1
4
+ prerelease:
5
+ version: 0.0.2
10
6
  platform: ruby
11
7
  authors:
12
8
  - Roberto Thais
@@ -14,7 +10,7 @@ autorequire:
14
10
  bindir: bin
15
11
  cert_chain: []
16
12
 
17
- date: 2011-01-24 00:00:00 -05:00
13
+ date: 2011-06-03 00:00:00 -04:00
18
14
  default_executable:
19
15
  dependencies:
20
16
  - !ruby/object:Gem::Dependency
@@ -25,10 +21,7 @@ dependencies:
25
21
  requirements:
26
22
  - - ~>
27
23
  - !ruby/object:Gem::Version
28
- segments:
29
- - 3
30
- - 0
31
- version: "3.0"
24
+ version: "3"
32
25
  type: :runtime
33
26
  version_requirements: *id001
34
27
  - !ruby/object:Gem::Dependency
@@ -39,24 +32,18 @@ dependencies:
39
32
  requirements:
40
33
  - - ~>
41
34
  - !ruby/object:Gem::Version
42
- segments:
43
- - 3
44
- - 0
45
- version: "3.0"
35
+ version: "3"
46
36
  type: :runtime
47
37
  version_requirements: *id002
48
38
  - !ruby/object:Gem::Dependency
49
- name: actionpack
39
+ name: railties
50
40
  prerelease: false
51
41
  requirement: &id003 !ruby/object:Gem::Requirement
52
42
  none: false
53
43
  requirements:
54
44
  - - ~>
55
45
  - !ruby/object:Gem::Version
56
- segments:
57
- - 3
58
- - 0
59
- version: "3.0"
46
+ version: "3"
60
47
  type: :runtime
61
48
  version_requirements: *id003
62
49
  - !ruby/object:Gem::Dependency
@@ -65,14 +52,44 @@ dependencies:
65
52
  requirement: &id004 !ruby/object:Gem::Requirement
66
53
  none: false
67
54
  requirements:
68
- - - ~>
55
+ - - ">="
69
56
  - !ruby/object:Gem::Version
70
- segments:
71
- - 0
72
- - 4
73
57
  version: "0.4"
74
58
  type: :runtime
75
59
  version_requirements: *id004
60
+ - !ruby/object:Gem::Dependency
61
+ name: rails
62
+ prerelease: false
63
+ requirement: &id005 !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - "="
67
+ - !ruby/object:Gem::Version
68
+ version: 3.0.7
69
+ type: :development
70
+ version_requirements: *id005
71
+ - !ruby/object:Gem::Dependency
72
+ name: sqlite3
73
+ prerelease: false
74
+ requirement: &id006 !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ~>
78
+ - !ruby/object:Gem::Version
79
+ version: 1.3.3
80
+ type: :development
81
+ version_requirements: *id006
82
+ - !ruby/object:Gem::Dependency
83
+ name: rspec
84
+ prerelease: false
85
+ requirement: &id007 !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ~>
89
+ - !ruby/object:Gem::Version
90
+ version: "2"
91
+ type: :development
92
+ version_requirements: *id007
76
93
  description: Brentano helps you present ActiveRecord collections to your controllers and avoid repetitive ORM logic
77
94
  email:
78
95
  - roberto.n.thais@gmail.com
@@ -85,15 +102,21 @@ extra_rdoc_files: []
85
102
  files:
86
103
  - .gitignore
87
104
  - Gemfile
105
+ - Gemfile.lock
88
106
  - README.md
89
107
  - Rakefile
90
108
  - brentano.gemspec
91
109
  - lib/brentano.rb
92
110
  - lib/brentano/presenter.rb
93
111
  - lib/brentano/query.rb
94
- - lib/brentano/rails.rb
95
- - lib/brentano/rails/helpers.rb
112
+ - lib/brentano/railtie.rb
96
113
  - lib/brentano/version.rb
114
+ - rails/helpers.rb
115
+ - spec/presenter_spec.rb
116
+ - spec/query_spec.rb
117
+ - spec/spec_helper.rb
118
+ - spec/support/active_record.rb
119
+ - spec/support/presenters.rb
97
120
  has_rdoc: true
98
121
  homepage: ""
99
122
  licenses: []
@@ -108,23 +131,23 @@ required_ruby_version: !ruby/object:Gem::Requirement
108
131
  requirements:
109
132
  - - ">="
110
133
  - !ruby/object:Gem::Version
111
- segments:
112
- - 0
113
134
  version: "0"
114
135
  required_rubygems_version: !ruby/object:Gem::Requirement
115
136
  none: false
116
137
  requirements:
117
138
  - - ">="
118
139
  - !ruby/object:Gem::Version
119
- segments:
120
- - 0
121
140
  version: "0"
122
141
  requirements: []
123
142
 
124
- rubyforge_project: brentano
125
- rubygems_version: 1.3.7
143
+ rubyforge_project: Brentano
144
+ rubygems_version: 1.6.2
126
145
  signing_key:
127
146
  specification_version: 3
128
147
  summary: Classy presenters for Rails 3
129
- test_files: []
130
-
148
+ test_files:
149
+ - spec/presenter_spec.rb
150
+ - spec/query_spec.rb
151
+ - spec/spec_helper.rb
152
+ - spec/support/active_record.rb
153
+ - spec/support/presenters.rb