simple_exposure 0.0.2 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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