simple_exposure 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a6213f9983cd1304fe8a1ca1b5b07439dde3f44d
4
- data.tar.gz: f51988204546151b272a6332ba049f4046901f1d
3
+ metadata.gz: c4ac6213c3f38471d413641334b633e9f930c36a
4
+ data.tar.gz: cffbf6e5672dbf1ec8feebb49ecd3f0e5396441b
5
5
  SHA512:
6
- metadata.gz: c1f5e71198dcd3cf61165a39baabd819069db2ce2e790cf25244b26ed76c82058ddb375d9cc64f964d14a40e0050bbc214f4fb18e00a4d27d0c013021b454870
7
- data.tar.gz: 9b6827ad0f3cb77ba298e115e8b0dee0163d1155951b84dea155ca27de33f10491453cea18e46bff1bdc4a95ea2b11be88d0a6cdd2261b6f8bad56feac4689bd
6
+ metadata.gz: 28f0a6fbac384b2adc6ed468e9c82ae0835c86ab8c3107093364166c93d43811c5329d6489aa2c752bd5da224ccd85d5afc8be6a36a98a91b44a34f6af5b54ad
7
+ data.tar.gz: 73217785155e4003aa33ebe131b90d1807341d320624dec4ef9efc1c612a5a5f74f9ab1f625196b53062bfce3f398d05f0016f6969d0af4e3cd2b50dcf46cad5
data/CHANGELOG.md ADDED
@@ -0,0 +1,12 @@
1
+ ## v0.1.0
2
+
3
+ + Added extension shortcuts (e.g. `paginate :users`)
4
+ + Moved UnknownExtension exception directly to SimpleExposure namespace (SimpleExposure::UnknownExtension)
5
+
6
+ ## v0.0.2
7
+
8
+ + Don't apply extensions when no value is provided
9
+
10
+ ## v0.0.1
11
+
12
+ + Initial impementation
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # SimpleExposure
2
2
 
3
- ![Gem version](http://img.shields.io/gem/v/simple_exposure.svg)
3
+ ![Gem version](http://img.shields.io/gem/v/simple_exposure.svg)
4
4
  ![Code Climate](http://img.shields.io/codeclimate/github/mikekreeki/simple_exposure.svg)
5
5
  ![Travis CI](http://img.shields.io/travis/mikekreeki/simple_exposure.svg)
6
6
  ![Github Issues](http://img.shields.io/github/issues/mikekreeki/simple_exposure.svg)
@@ -22,6 +22,8 @@ end
22
22
  p = project.title
23
23
  ```
24
24
 
25
+ Wait, there's more!
26
+
25
27
  ## Installation
26
28
 
27
29
  Add this line to your application's Gemfile:
@@ -43,11 +45,15 @@ Or install it yourself as:
43
45
  ```ruby
44
46
  # controllers/projects_controller.rb
45
47
  class ProjectsController < ApplicationController
46
- expose :projects
48
+ expose :projects, :project
47
49
 
48
50
  def index
49
51
  self.projects = Project.all
50
52
  end
53
+
54
+ def show
55
+ self.project = Project.find(1)
56
+ end
51
57
  end
52
58
 
53
59
  # views/projects/index.html.slim
@@ -55,6 +61,21 @@ end
55
61
  p = project.title
56
62
  ```
57
63
 
64
+ Expose controller methods to the views:
65
+
66
+ ```ruby
67
+ # controllers/projects_controller.rb
68
+ class ProjectsController < ApplicationController
69
+ expose :project
70
+
71
+ private
72
+
73
+ def project
74
+ @project ||= Project.find(1)
75
+ end
76
+ end
77
+ ```
78
+
58
79
  ### Provide default values
59
80
 
60
81
  ```ruby
@@ -73,12 +94,23 @@ class ProjectsController < ApplicationController
73
94
  def index
74
95
  @projects = Project.page(params[:page])
75
96
  end
76
-
77
97
  end
78
98
  ```
79
99
 
80
100
  After:
81
101
 
102
+ ```ruby
103
+ class ProjectsController < ApplicationController
104
+ paginate :projects
105
+
106
+ def index
107
+ self.projects = Project.all
108
+ end
109
+ end
110
+ ```
111
+
112
+ Which is the same as:
113
+
82
114
  ```ruby
83
115
  class ProjectsController < ApplicationController
84
116
  expose :projects, extend: :paginate
@@ -91,6 +123,31 @@ end
91
123
 
92
124
  ### Combine multiple extensions
93
125
 
126
+ Before:
127
+
128
+ ```ruby
129
+ class ProjectsController < ApplicationController
130
+
131
+ def index
132
+ @projects = Project.page(params[:page]).decorate
133
+ end
134
+ end
135
+ ```
136
+
137
+ After:
138
+
139
+ ```ruby
140
+ class ProjectsController < ApplicationController
141
+ paginate :projects, extend: :decorate
142
+
143
+ def index
144
+ self.projects = Project.all
145
+ end
146
+ end
147
+ ```
148
+
149
+ Which is the same as:
150
+
94
151
  ```ruby
95
152
  class ProjectsController < ApplicationController
96
153
  expose :projects, extend: %i(paginate decorate)
@@ -121,15 +178,13 @@ After:
121
178
 
122
179
  ```ruby
123
180
  class ProjectsController < ApplicationController
124
- expose :current_user, extend: :decorate
181
+ decorate :current_user
125
182
 
126
183
  expose :projects do
127
184
  current_user.projects.ordered
128
185
  end
129
186
 
130
- expose :completed_projects, extend: :paginate do
131
- projects.completed
132
- end
187
+ paginate(:completed_projects) { projects.completed }
133
188
  end
134
189
  ```
135
190
 
@@ -158,10 +213,19 @@ module SimpleExposure
158
213
  end
159
214
 
160
215
  class ProjectsController < ApplicationController
216
+ my_extension :projects
217
+ # or
161
218
  expose :projects, extend: :my_extension
162
219
  end
163
220
  ```
164
221
 
222
+ Note that extensions are applied at the time of `render`, not immediately when the value is assigned.
223
+
224
+ ## Similar projects
225
+
226
+ + [view_accessor](https://github.com/invisiblefunnel/view_accessor)
227
+ + [obviews](https://github.com/elia/obviews)
228
+ + [decent_exposure](https://github.com/voxdolo/decent_exposure)
165
229
 
166
230
  ## Contributing
167
231
 
@@ -2,20 +2,21 @@ require 'simple_exposure/extensions/paginate'
2
2
  require 'simple_exposure/extensions/decorate'
3
3
 
4
4
  module SimpleExposure
5
+ UnknownExtension = Class.new(NameError)
6
+
5
7
  module Core
6
8
  extend ActiveSupport::Concern
7
9
 
8
- UnknownExtension = Class.new(NameError)
9
-
10
10
  included do
11
11
  delegate :_exposure_extensions, to: :class
12
+ delegate :_exposure_extension_class, to: :class
12
13
  before_render :_apply_exposure_extensions
13
14
  end
14
15
 
15
16
  def _apply_exposure_extensions
16
17
  _exposure_extensions.each do |attribute, extensions|
17
18
  extensions.each do |extension|
18
- _apply_exposure_extension(attribute, extension)
19
+ _apply_exposure_extension(attribute, extension.to_s)
19
20
  end
20
21
  end
21
22
  end
@@ -29,12 +30,6 @@ module SimpleExposure
29
30
  end
30
31
  end
31
32
 
32
- def _exposure_extension_class(extension)
33
- Extensions.const_get(extension.camelize)
34
- rescue NameError
35
- raise UnknownExtension, "Unknown extension: #{extension}"
36
- end
37
-
38
33
  module ClassMethods
39
34
 
40
35
  def expose(*attributes, &block)
@@ -51,6 +46,12 @@ module SimpleExposure
51
46
  @_exposure_extensions ||= HashWithIndifferentAccess.new([])
52
47
  end
53
48
 
49
+ def _exposure_extension_class(extension)
50
+ Extensions.const_get(extension.camelize)
51
+ rescue NameError
52
+ raise UnknownExtension, "Unknown extension: #{extension}"
53
+ end
54
+
54
55
  private
55
56
 
56
57
  def _define_exposure_accessors(attributes, &block)
@@ -92,6 +93,29 @@ module SimpleExposure
92
93
  _exposure_extensions[attribute] += extensions
93
94
  end
94
95
  end
96
+
97
+ def method_missing(extension, *attributes, &block)
98
+ extension_class = _exposure_extension_class(extension.to_s)
99
+ if extension_class
100
+ options = attributes.extract_options!
101
+
102
+ extensions = options.fetch(:extend, nil)
103
+ extensions = Array(extensions)
104
+ extensions = extensions.prepend(extension)
105
+
106
+ options = options.merge(extend: extensions)
107
+
108
+ expose(*attributes, options, &block)
109
+ end
110
+ rescue UnknownExtension
111
+ super
112
+ end
113
+
114
+ def respond_to_missing?(extension, include_private = false)
115
+ _exposure_extension_class(extension.to_s)
116
+ rescue UnknownExtension
117
+ false
118
+ end
95
119
  end
96
120
  end
97
121
  end
@@ -1,3 +1,3 @@
1
1
  module SimpleExposure
2
- VERSION = '0.0.2'
2
+ VERSION = '0.1.0'
3
3
  end
@@ -20,5 +20,4 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_runtime_dependency 'rails', ['>= 3.2.3', '< 5']
22
22
  spec.add_development_dependency 'rspec-rails', '~> 3.0.0'
23
- spec.add_development_dependency 'capybara'
24
23
  end
@@ -0,0 +1,71 @@
1
+ require 'spec_helper'
2
+
3
+ describe ApplicationController, type: :controller do
4
+ let(:view) { controller.view_context }
5
+
6
+ it 'loads the modules' do
7
+ expect(described_class.ancestors).to include(SimpleExposure::Core)
8
+ end
9
+
10
+ it 'responds to #expose' do
11
+ expect(described_class).to respond_to(:expose)
12
+ end
13
+
14
+ before do
15
+ get :index
16
+ end
17
+
18
+ describe 'Inline definition of multiple exposed attributes' do
19
+ it 'exposes multiple attributes defined inline' do
20
+ expect(view.my_name).to eq 'Jane Doe'
21
+ expect(view.your_name).to eq 'Jane Doe'
22
+ end
23
+ end
24
+
25
+ describe 'Default values' do
26
+ it 'assigns default value' do
27
+ expect(view.message).to eq 'Hello!'
28
+ end
29
+
30
+ it 'does not override provided values with default one' do
31
+ expect(view.other_message).to eq 'Other message'
32
+ end
33
+ end
34
+
35
+ describe 'Exposing controllers instance variables' do
36
+ it 'exposes the value in ivar' do
37
+ expect(view.ivar_message).to eq 'Hello!'
38
+ end
39
+ end
40
+
41
+ describe 'Exposing private methods' do
42
+ it 'exposes controllers private methods' do
43
+ expect(view.current_user).to eq 'mikekreeki'
44
+ end
45
+ end
46
+
47
+ describe 'Extensions' do
48
+ it 'applies extension when value provided' do
49
+ expect(view.decoratable_message).to eq 'Hello!'
50
+ end
51
+
52
+ it 'does not apply extension when value not provided' do
53
+ expect(view.nil_value).to be_nil
54
+ end
55
+ end
56
+
57
+ describe 'Extension shortcuts' do
58
+ it 'quacks like a shortcut' do
59
+ expect(described_class).to respond_to :decorate
60
+ end
61
+
62
+ it 'applies the extension when specified using a shortcut' do
63
+ expect(view.second_user).to eq 'Andrew Bennett'
64
+ expect(view.third_user).to eq 'Andrew Bennett'
65
+ end
66
+
67
+ it 'takes additional extensions' do
68
+ expect(view.combined_extension).to eq 'HELLO'
69
+ end
70
+ end
71
+ end
@@ -1,18 +1,42 @@
1
+ require 'ostruct'
2
+
1
3
  class ApplicationController < ActionController::Base
2
4
  # Prevent CSRF attacks by raising an exception.
3
5
  # For APIs, you may want to use :null_session instead.
4
6
  protect_from_forgery with: :exception
5
7
 
6
- expose(:message) { 'Hello!' }
8
+ expose(:my_name, :your_name) { 'Jane Doe' }
9
+
10
+ expose(:message) { 'Hello!' }
11
+ expose(:other_message) { 'Hello!' }
12
+ expose(:ivar_message)
7
13
 
8
14
  expose(:current_user)
9
15
 
10
- expose(:posts_count) { 0 }
16
+ expose(:decoratable_message, extend: :decorate) do
17
+ OpenStruct.new(decorate: 'Hello!')
18
+ end
11
19
 
12
20
  expose(:nil_value, extend: :decorate)
13
21
 
22
+ decorate(:second_user, :third_user) { OpenStruct.new(decorate: 'Andrew Bennett') }
23
+
24
+ paginate :combined_extension, extend: :decorate do
25
+ Class.new do
26
+ def page(*)
27
+ @name = 'Hello'
28
+ self
29
+ end
30
+
31
+ def decorate
32
+ @name.upcase
33
+ end
34
+ end.new
35
+ end
36
+
14
37
  def index
15
- @posts_count = 2
38
+ self.other_message = 'Other message'
39
+ @ivar_message = 'Hello!'
16
40
  end
17
41
 
18
42
  private
@@ -1,7 +0,0 @@
1
- <%= message %>
2
-
3
- <%= current_user %>
4
-
5
- <%= posts_count %>
6
-
7
- <%= nil_value %>
data/spec/spec_helper.rb CHANGED
@@ -2,12 +2,6 @@ ENV['RAILS_ENV'] ||= 'test'
2
2
  require File.expand_path('../dummy/config/environment', __FILE__)
3
3
 
4
4
  require 'rspec/rails'
5
- require 'capybara/rspec'
6
-
7
- # Requires supporting ruby files with custom matchers and macros, etc,
8
- # in spec/support/ and its subdirectories.
9
- Dir[Rails.root.join('spec/support/**/*.rb')].each {|f| require f}
10
5
 
11
6
  RSpec.configure do |config|
12
- config.include Capybara::DSL, type: :integration
13
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_exposure
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michal Krejčí
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-14 00:00:00.000000000 Z
11
+ date: 2014-07-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -44,20 +44,6 @@ dependencies:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
46
  version: 3.0.0
47
- - !ruby/object:Gem::Dependency
48
- name: capybara
49
- requirement: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - ">="
52
- - !ruby/object:Gem::Version
53
- version: '0'
54
- type: :development
55
- prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- requirements:
58
- - - ">="
59
- - !ruby/object:Gem::Version
60
- version: '0'
61
47
  description: Cleanup your Rails controllers
62
48
  email:
63
49
  - work@mikekreeki.com
@@ -69,6 +55,7 @@ files:
69
55
  - ".ruby-gemset"
70
56
  - ".ruby-version"
71
57
  - ".travis.yml"
58
+ - CHANGELOG.md
72
59
  - Gemfile
73
60
  - LICENSE.txt
74
61
  - README.md
@@ -80,6 +67,7 @@ files:
80
67
  - lib/simple_exposure/extensions/paginate.rb
81
68
  - lib/simple_exposure/version.rb
82
69
  - simple_exposure.gemspec
70
+ - spec/controllers/application_controller_spec.rb
83
71
  - spec/dummy/.gitignore
84
72
  - spec/dummy/Gemfile
85
73
  - spec/dummy/README.rdoc
@@ -134,8 +122,6 @@ files:
134
122
  - spec/dummy/test/test_helper.rb
135
123
  - spec/dummy/vendor/assets/javascripts/.keep
136
124
  - spec/dummy/vendor/assets/stylesheets/.keep
137
- - spec/integration/simple_exposure_spec.rb
138
- - spec/simple_exposure/core_spec.rb
139
125
  - spec/spec_helper.rb
140
126
  homepage: https://github.com/mikekreeki/simple_exposure
141
127
  licenses:
@@ -162,6 +148,7 @@ signing_key:
162
148
  specification_version: 4
163
149
  summary: Cleanup your Rails controllers
164
150
  test_files:
151
+ - spec/controllers/application_controller_spec.rb
165
152
  - spec/dummy/.gitignore
166
153
  - spec/dummy/Gemfile
167
154
  - spec/dummy/README.rdoc
@@ -216,6 +203,4 @@ test_files:
216
203
  - spec/dummy/test/test_helper.rb
217
204
  - spec/dummy/vendor/assets/javascripts/.keep
218
205
  - spec/dummy/vendor/assets/stylesheets/.keep
219
- - spec/integration/simple_exposure_spec.rb
220
- - spec/simple_exposure/core_spec.rb
221
206
  - spec/spec_helper.rb
@@ -1,21 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe SimpleExposure, type: :integration do
4
- it 'loads the modules' do
5
- expect(ActionController::Base.ancestors).to include(SimpleExposure::Core)
6
- end
7
-
8
- let(:controller) { ApplicationController.new }
9
-
10
- it 'can see the content' do
11
- visit '/'
12
-
13
- controller.index
14
-
15
- expect(page).to have_content controller.send(:message)
16
- expect(page).to have_content controller.send(:current_user)
17
- expect(page).to have_content controller.send(:posts_count)
18
- end
19
-
20
-
21
- end
@@ -1,9 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe SimpleExposure::Core do
4
- let(:controller) { ApplicationController.new }
5
-
6
- it 'responds to #expose' do
7
- expect(controller.class).to respond_to(:expose)
8
- end
9
- end