adequate_exposure 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6a1d34ba1b491cb226abd1ed966b2e1fc51469a5
4
+ data.tar.gz: f5a79cc81e6918171764fe3441f81e7da2a372bd
5
+ SHA512:
6
+ metadata.gz: 332ca67a8253cbb83e395a95bc79167a9ac355843a772adf1b373569c83086afcc2daed5eb30bbae058a4d57b9fe73992a28d3acaadcc60bac04f47f7bb8eb5d
7
+ data.tar.gz: 2558b8622f561444eae1ba3b1c19d46b059cd83f2fe0705e06af4e33bb93e821392b6f02a5d11ebcda03fee01b162066072e60e66fa4cebff0dbdc02b6c01abb
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem "rspec-rails", "~> 3.0"
6
+ gem "rake", "~> 10.3"
7
+ gem "pry"
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Hashrocket Workstation
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,151 @@
1
+ # Adequate Exposure
2
+
3
+ This is WIP. Please don't send pull requests yet, I'm still actively rewriting things.
4
+
5
+ Adequate exposure. Exposing things, adequately.
6
+
7
+ Adequate exposure is a lightweight alternative to [Decent Exposure](https://github.com/voxdolo/decent_exposure). With it's narrowly focused api you can get exactly what you need without all the extra dressing.
8
+
9
+ *Note: It is not the intent of the author to imply that Decent Exposure is inadequate.)*
10
+
11
+ Installation is as simple as: `$ gem install adequate_exposure`. Once you have that down we can start talking about the API.
12
+
13
+ ## API
14
+
15
+ The whole API consists of one `expose` method.
16
+
17
+ In the simplest scenario you'll just use it to expose a model in the controller:
18
+
19
+ ```ruby
20
+ class ThingsController < ApplicationController
21
+ expose :thing
22
+ end
23
+ ```
24
+
25
+ Now every time you call `thing` in your controller or view, it'll look for an id and try to perform `Thing.find(id)` or `Thing.new` if the id is not found. It'll also memoize the result in `@exposed_thing` instance variable.
26
+
27
+ You can also provide your own logic of how `thing` should be resolved by passing a block that'll be executed in your controller context.
28
+
29
+ ```ruby
30
+ class ThingsController < ApplicationController
31
+ expose(:thing){ Thing.find(get_thing_id_somehow) }
32
+
33
+ private
34
+
35
+ def get_thing_id_somehow
36
+ 42
37
+ end
38
+ end
39
+ ```
40
+
41
+ The default resolving workflow if pretty powerful and customizable. It could be expressed with the following pseudocode:
42
+
43
+ ```ruby
44
+ def fetch(scope, id)
45
+ id ? decorate(find(id, scope)) : decorate(build(scope))
46
+ end
47
+
48
+ def id
49
+ params[:thing_id] || params[:id]
50
+ end
51
+
52
+ def find(id, scope)
53
+ scope.find(id) # Thing.find(id)
54
+ end
55
+
56
+ def build(scope)
57
+ scope.new # Thing.new
58
+ end
59
+
60
+ def scope
61
+ model # Thing
62
+ end
63
+
64
+ def model
65
+ exposure_name.classify.constantize # :thing -> Thing
66
+ end
67
+
68
+ def decorate(thing)
69
+ thing
70
+ end
71
+ ```
72
+
73
+ Each step is overridable with options. The acceptable options to the `expose` macro are:
74
+
75
+ **find**
76
+
77
+ How to perform the finding. Could be useful if you don't want to use standard Rails finder.
78
+
79
+ ```ruby
80
+ expose :thing, find: ->(id, scope){ scope.find_by(slug: id) }
81
+ ```
82
+
83
+ **build**
84
+
85
+ Allows to override the build process that takes place when id is not provided.
86
+
87
+ ```ruby
88
+ expose :thing, build: ->(scope){ Thing.build_with_defaults }
89
+ ```
90
+
91
+ **id**
92
+
93
+ Allows to specify how to extract id from parameters hash.
94
+
95
+ ```ruby
96
+ # default
97
+ expose :thing, id: ->{ params[:thing_id] || params[:id] }
98
+
99
+ # id is always goona be 42
100
+ expose :thing, id: ->{ 42 }
101
+
102
+ # equivalent to id: ->{ params[:custom_thing_id] }
103
+ expose :thing, id: :custom_thing_id
104
+
105
+ # equivalent to id: ->{ params[:try_this_id] || params[:or_maybe_that_id] }
106
+ expose :thing, id: %i[try_this_id or_maybe_that_id]
107
+ ```
108
+
109
+ **scope**
110
+
111
+ Defines the scope that's used in `find` and `build` steps.
112
+
113
+ ```ruby
114
+ expose :thing, scope: ->{ current_user.things }
115
+ expose :thing, scope: :current_user # the same as above
116
+ ```
117
+
118
+ **model**
119
+
120
+ Specify the model to use.
121
+
122
+ ```ruby
123
+ expose :thing, model: ->{ AnotherThing }
124
+ expose :thing, model: AnotherThing
125
+ expose :thing, model: :another_thing
126
+ ```
127
+
128
+ **fetch**
129
+
130
+ Allows to override the `fetch` logic that's happening when you first call exposed helper.
131
+
132
+ ```ruby
133
+ expose :thing, fetch: ->{ get_thing_some_way_or_another }
134
+ expose(:thing){ get_thing_some_way_or_another }
135
+ ```
136
+
137
+ **decorate**
138
+
139
+ Allows to define a block that wraps and instance before it's returned. Useful for decorators.
140
+
141
+ ```ruby
142
+ expose :thing, decorate: ->(thing){ ThingDecorator.new(thing) }
143
+ ```
144
+
145
+ ## Contributing
146
+
147
+ 1. Fork it ( https://github.com/[my-github-username]/adequate_exposure/fork )
148
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
149
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
150
+ 4. Push to the branch (`git push origin my-new-feature`)
151
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new
5
+
6
+ task default: :spec
@@ -0,0 +1,22 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "adequate_exposure/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "adequate_exposure"
8
+ spec.version = AdequateExposure::VERSION
9
+ spec.authors = ["Pavel Pravosud"]
10
+ spec.email = ["pavel@pravosud.com"]
11
+ spec.summary = "More adequate than decent"
12
+ spec.homepage = "https://github.com/rwz/adequate_exposure"
13
+ spec.license = "MIT"
14
+ spec.files = `git ls-files -z`.split("\x0")
15
+ spec.test_files = spec.files.grep(/\Aspec\//)
16
+ spec.require_path = "lib"
17
+
18
+ spec.required_ruby_version = "~> 2.0"
19
+
20
+ spec.add_dependency "railties", "~> 4.0"
21
+ spec.add_dependency "activesupport", "~> 4.0"
22
+ end
@@ -0,0 +1,13 @@
1
+ require "active_support/lazy_load_hooks"
2
+
3
+ module AdequateExposure
4
+ autoload :Controller, "adequate_exposure/controller"
5
+ autoload :Exposure, "adequate_exposure/exposure"
6
+ autoload :Attribute, "adequate_exposure/attribute"
7
+ autoload :Context, "adequate_exposure/context"
8
+ autoload :Flow, "adequate_exposure/flow"
9
+
10
+ ActiveSupport.on_load :action_controller do
11
+ extend Controller
12
+ end
13
+ end
@@ -0,0 +1,31 @@
1
+ module AdequateExposure
2
+ class Attribute
3
+ attr_reader :name, :fetch, :ivar_name
4
+
5
+ def initialize(name:, fetch:, ivar_name:)
6
+ @name, @fetch, @ivar_name = name, fetch, ivar_name
7
+ end
8
+
9
+ def getter_method_name
10
+ name.to_sym
11
+ end
12
+
13
+ def setter_method_name
14
+ "#{name}=".to_sym
15
+ end
16
+
17
+ def expose!(klass)
18
+ attribute = self
19
+
20
+ klass.instance_eval do
21
+ define_method attribute.getter_method_name do
22
+ Context.new(self, attribute).get
23
+ end
24
+
25
+ define_method attribute.setter_method_name do |value|
26
+ Context.new(self, attribute).set(value)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,44 @@
1
+ require "active_support/core_ext/module/delegation"
2
+
3
+ module AdequateExposure
4
+ class Context
5
+ attr_reader :context, :attribute
6
+
7
+ def initialize(context, attribute)
8
+ @context, @attribute = context, attribute
9
+ end
10
+
11
+ def get
12
+ ivar_defined?? ivar_get : set(fetch_value)
13
+ end
14
+
15
+ def set(value)
16
+ ivar_set(value)
17
+ end
18
+
19
+ private
20
+
21
+ delegate :instance_variable_set, :instance_variable_get,
22
+ :instance_variable_defined?, to: :context
23
+
24
+ def ivar_defined?
25
+ instance_variable_defined?(ivar_name)
26
+ end
27
+
28
+ def ivar_get
29
+ instance_variable_get(ivar_name)
30
+ end
31
+
32
+ def ivar_set(value)
33
+ instance_variable_set(ivar_name, value)
34
+ end
35
+
36
+ def ivar_name
37
+ "@#{attribute.ivar_name}"
38
+ end
39
+
40
+ def fetch_value
41
+ context.instance_exec(&attribute.fetch)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,11 @@
1
+ require "active_support/core_ext/hash/reverse_merge"
2
+
3
+ module AdequateExposure
4
+ module Controller
5
+ def expose(name, **options, &block)
6
+ options = options.merge(name: name)
7
+ options.reverse_merge! fetch: block if block_given?
8
+ Exposure.new(options).expose! self
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,41 @@
1
+ module AdequateExposure
2
+ class Exposure
3
+ attr_reader :options
4
+
5
+ def initialize(options)
6
+ @options = options
7
+ end
8
+
9
+ def expose!(controller)
10
+ expose_attribute! controller
11
+ expose_helper_methods! controller
12
+ end
13
+
14
+ private
15
+
16
+ def expose_attribute!(controller)
17
+ attribute.expose! controller
18
+ end
19
+
20
+ def expose_helper_methods!(controller)
21
+ helper_methods = [ attribute.getter_method_name, attribute.setter_method_name ]
22
+ controller.helper_method *helper_methods
23
+ end
24
+
25
+ def attribute
26
+ @attribute ||= begin
27
+ local_options = options
28
+
29
+ name = options.fetch(:name)
30
+ ivar_name = "exposed_#{name}"
31
+ fetch = ->{ Flow.new(self, local_options).fetch }
32
+
33
+ Attribute.new(
34
+ name: name,
35
+ ivar_name: ivar_name,
36
+ fetch: fetch
37
+ )
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,105 @@
1
+ require "active_support/hash_with_indifferent_access"
2
+ require "active_support/core_ext/array/wrap"
3
+ require "active_support/core_ext/string/inflections"
4
+
5
+ module AdequateExposure
6
+ class Flow
7
+ attr_reader :controller, :options
8
+ delegate :params, to: :controller
9
+
10
+ def initialize(controller, **options)
11
+ @controller, @options = controller, HashWithIndifferentAccess.new(options)
12
+ end
13
+
14
+ def name
15
+ options.fetch(:name)
16
+ end
17
+
18
+ %i[fetch find build scope model id decorate].each do |method_name|
19
+ define_method method_name do |*args|
20
+ ivar_name = "@#{method_name}"
21
+ return instance_variable_get(ivar_name) if instance_variable_defined?(ivar_name)
22
+ instance_variable_set(ivar_name, handle_action(method_name, *args))
23
+ end
24
+ end
25
+
26
+ protected
27
+
28
+ def default_fetch
29
+ id ? decorate(find(id, scope)) : decorate(build(scope))
30
+ end
31
+
32
+ def default_id
33
+ fetch_first_defined_param %I[#{name}_id id]
34
+ end
35
+
36
+ def default_scope
37
+ model
38
+ end
39
+
40
+ def default_model
41
+ symbol_to_class(name)
42
+ end
43
+
44
+ def default_find(id, scope)
45
+ scope.find(id)
46
+ end
47
+
48
+ def default_build(scope)
49
+ scope.new
50
+ end
51
+
52
+ def default_decorate(instance)
53
+ instance
54
+ end
55
+
56
+ def handle_custom_model(value)
57
+ Class === value ? value : symbol_to_class(value)
58
+ end
59
+
60
+ def handle_custom_scope(value)
61
+ scope_parent = controller.instance_exec{ send value }
62
+ scope_parent.send(name.to_s.pluralize)
63
+ end
64
+
65
+ def handle_custom_id(value)
66
+ fetch_first_defined_param value
67
+ end
68
+
69
+ private
70
+
71
+ def id_attribute_name
72
+ Array.wrap(possible_id_keys).detect{ |key| params.key?(key) }
73
+ end
74
+
75
+ def handle_action(name, *args)
76
+ if options.key?(name)
77
+ handle_custom_action(name, *args)
78
+ else
79
+ send("default_#{name}", *args)
80
+ end
81
+ end
82
+
83
+ def handle_custom_action(name, *args)
84
+ value = options[name]
85
+
86
+ if Proc === value
87
+ controller.instance_exec(*args, &value)
88
+ else
89
+ send("handle_custom_#{name}", value, *args)
90
+ end
91
+ end
92
+
93
+ def symbol_to_class(symbol)
94
+ symbol.to_s.classify.constantize
95
+ end
96
+
97
+ def fetch_first_defined_param(keys)
98
+ Array.wrap(keys).each do |key|
99
+ return params[key] if params.key?(key)
100
+ end
101
+
102
+ nil
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,3 @@
1
+ module AdequateExposure
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,167 @@
1
+ require "spec_helper"
2
+
3
+ describe AdequateExposure::Controller do
4
+ class Thing; end
5
+ class DifferentThing; end
6
+
7
+ class BaseController
8
+ def self.helper_method(*); end
9
+
10
+ def params
11
+ @params ||= HashWithIndifferentAccess.new
12
+ end
13
+ end
14
+
15
+ let(:controller_klass) do
16
+ Class.new(BaseController) do
17
+ extend AdequateExposure::Controller
18
+ end
19
+ end
20
+
21
+ let(:controller){ controller_klass.new }
22
+
23
+ def expose(*args, &block)
24
+ controller_klass.expose(*args, &block)
25
+ end
26
+
27
+ context "getter/setter methods" do
28
+ before{ expose :thing }
29
+
30
+ it "defines getter method" do
31
+ expect(controller).to respond_to(:thing)
32
+ end
33
+
34
+ it "defines setter method" do
35
+ expect(controller).to respond_to(:thing=).with(1).argument
36
+ end
37
+ end
38
+
39
+ context "helper methods" do
40
+ it "exposes getter and setter as controller helper methods" do
41
+ expect(controller_klass).to receive(:helper_method).with(:thing, :thing=)
42
+ expose :thing
43
+ end
44
+ end
45
+
46
+ context "with block" do
47
+ before do
48
+ expose(:thing){ compute_thing }
49
+ end
50
+
51
+ it "executes block to calculate the value" do
52
+ allow(controller).to receive(:compute_thing).and_return(42)
53
+ expect(controller.thing).to eq(42)
54
+ end
55
+
56
+ it "executes the block once and memoizes the result" do
57
+ expect(controller).to receive(:compute_thing).once.and_return(42)
58
+ 10.times{ controller.thing }
59
+ end
60
+
61
+ it "allows setting value directly" do
62
+ expect(controller).to_not receive(:compute_thing)
63
+ controller.thing = :foobar
64
+ expect(controller.thing).to eq(:foobar)
65
+ end
66
+ end
67
+
68
+ context "redefine fetch" do
69
+ before do
70
+ expose :thing, fetch: ->{ compute_thing }
71
+ allow(controller).to receive(:compute_thing).and_return(42)
72
+ end
73
+
74
+ it "uses provided fetch proc instead of default" do
75
+ expect(controller.thing).to eq(42)
76
+ end
77
+ end
78
+
79
+ context "default behaviour" do
80
+ before{ expose :thing }
81
+
82
+ it "builds a new instance when id is not provided" do
83
+ expect(controller.thing).to be_instance_of(Thing)
84
+ end
85
+
86
+ context "find" do
87
+ before{ expect(Thing).to receive(:find).with(10) }
88
+ after{ controller.thing }
89
+
90
+ it "finds Thing if thing_id param is provided" do
91
+ controller.params.merge! thing_id: 10
92
+ end
93
+
94
+ it "finds Thing if id param if provided" do
95
+ controller.params.merge! id: 10
96
+ end
97
+ end
98
+ end
99
+
100
+ context "override model" do
101
+ after{ expect(controller.thing).to be_instance_of(DifferentThing) }
102
+
103
+ it "allows overriding model class with proc" do
104
+ expose :thing, model: ->{ DifferentThing }
105
+ end
106
+
107
+ it "allows overriding model with class" do
108
+ expose :thing, model: DifferentThing
109
+ end
110
+
111
+ it "allows overriding model class with symbol" do
112
+ expose :thing, model: :different_thing
113
+ end
114
+ end
115
+
116
+ context "override scope" do
117
+ it "allows overriding scope with proc" do
118
+ scope = double("Scope")
119
+ expose :thing, scope: ->{ scope }
120
+ expect(scope).to receive(:new).and_return(42)
121
+ expect(controller.thing).to eq(42)
122
+ end
123
+
124
+ it "allows overriding with symbol" do
125
+ current_user = double("User")
126
+ scope = double("Scope")
127
+ scoped_thing = double("Thing")
128
+
129
+ expect(controller).to receive(:current_user).and_return(current_user)
130
+ expect(current_user).to receive(:things).and_return(scope)
131
+ expect(scope).to receive(:new).and_return(scoped_thing)
132
+ expose :thing, scope: :current_user
133
+
134
+ expect(controller.thing).to eq(scoped_thing)
135
+ end
136
+ end
137
+
138
+ context "override id" do
139
+ after do
140
+ expect(Thing).to receive(:find).with(42)
141
+ controller.thing
142
+ end
143
+
144
+ it "allows overriding id with proc" do
145
+ expose :thing, id: ->{ get_thing_id_somehow }
146
+ expect(controller).to receive(:get_thing_id_somehow).and_return(42)
147
+ end
148
+
149
+ it "allows overriding id with symbol" do
150
+ expose :thing, id: :custom_thing_id
151
+ controller.params.merge! thing_id: 10, custom_thing_id: 42
152
+ end
153
+
154
+ it "allows overriding id with an array of symbols" do
155
+ expose :thing, id: %i[non-existent-id lolwut another_id_param]
156
+ controller.params.merge! another_id_param: 42
157
+ end
158
+ end
159
+
160
+ context "override decorator" do
161
+ it "allows specify decorator" do
162
+ expose :thing, decorate: ->(thing){ decorate(thing) }
163
+ expect(controller).to receive(:decorate).with(an_instance_of(Thing))
164
+ controller.thing
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,26 @@
1
+ require "spec_helper"
2
+ require "support/rails_app"
3
+ require "rspec/rails"
4
+
5
+ describe BirdsController, type: :controller do
6
+ context "finds bird by id" do
7
+ let(:mockingbird){ double("Bird") }
8
+ before{ expect(Bird).to receive(:find).with("mockingbird").once.and_return(mockingbird) }
9
+ after{ expect(controller.bird).to eq(mockingbird) }
10
+
11
+ it "finds model by id" do
12
+ get :show, id: "mockingbird"
13
+ end
14
+
15
+ it "finds model by bird_id" do
16
+ get :show, bird_id: "mockingbird"
17
+ end
18
+ end
19
+
20
+ it "builds bird if id is not provided" do
21
+ bird = double("Bird")
22
+ expect(Bird).to receive(:new).and_return(bird)
23
+ get :show
24
+ expect(controller.bird).to eq(bird)
25
+ end
26
+ end
@@ -0,0 +1 @@
1
+ require "adequate_exposure"
@@ -0,0 +1,39 @@
1
+ require "active_support/all"
2
+ require "active_support/dependencies/autoload"
3
+ require "action_controller"
4
+ require "action_dispatch"
5
+ require "rails"
6
+
7
+ module Rails
8
+ class App
9
+ def env_config; {} end
10
+
11
+ def routes
12
+ @routes ||= ActionDispatch::Routing::RouteSet.new.tap do |routes|
13
+ routes.draw do
14
+ resource :birds
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ def self.application
21
+ @app ||= App.new
22
+ end
23
+ end
24
+
25
+ class Bird
26
+ end
27
+
28
+ class ApplicationConroller < ActionController::Base
29
+ include Rails.application.routes.url_helpers
30
+ end
31
+
32
+ class BirdsController < ApplicationConroller
33
+ expose :bird
34
+
35
+ def show
36
+ render nothing: true
37
+ end
38
+ end
39
+
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: adequate_exposure
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Pavel Pravosud
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-07-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: railties
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '4.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '4.0'
41
+ description:
42
+ email:
43
+ - pavel@pravosud.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".gitignore"
49
+ - Gemfile
50
+ - LICENSE.txt
51
+ - README.md
52
+ - Rakefile
53
+ - adequate_exposure.gemspec
54
+ - lib/adequate_exposure.rb
55
+ - lib/adequate_exposure/attribute.rb
56
+ - lib/adequate_exposure/context.rb
57
+ - lib/adequate_exposure/controller.rb
58
+ - lib/adequate_exposure/exposure.rb
59
+ - lib/adequate_exposure/flow.rb
60
+ - lib/adequate_exposure/version.rb
61
+ - spec/controller_spec.rb
62
+ - spec/integration_spec.rb
63
+ - spec/spec_helper.rb
64
+ - spec/support/rails_app.rb
65
+ homepage: https://github.com/rwz/adequate_exposure
66
+ licenses:
67
+ - MIT
68
+ metadata: {}
69
+ post_install_message:
70
+ rdoc_options: []
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - "~>"
76
+ - !ruby/object:Gem::Version
77
+ version: '2.0'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubyforge_project:
85
+ rubygems_version: 2.2.2
86
+ signing_key:
87
+ specification_version: 4
88
+ summary: More adequate than decent
89
+ test_files:
90
+ - spec/controller_spec.rb
91
+ - spec/integration_spec.rb
92
+ - spec/spec_helper.rb
93
+ - spec/support/rails_app.rb