controll 0.2.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.
- data/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +19 -0
- data/Gemfile.lock +134 -0
- data/LICENSE.txt +20 -0
- data/README.md +320 -0
- data/Rakefile +49 -0
- data/VERSION +1 -0
- data/controll.gemspec +184 -0
- data/lib/controll.rb +14 -0
- data/lib/controll/assistant.rb +19 -0
- data/lib/controll/command.rb +24 -0
- data/lib/controll/commander.rb +24 -0
- data/lib/controll/errors.rb +1 -0
- data/lib/controll/executor.rb +6 -0
- data/lib/controll/executor/base.rb +16 -0
- data/lib/controll/executor/notificator.rb +12 -0
- data/lib/controll/flow_handler.rb +11 -0
- data/lib/controll/flow_handler/base.rb +19 -0
- data/lib/controll/flow_handler/control.rb +85 -0
- data/lib/controll/flow_handler/errors.rb +5 -0
- data/lib/controll/flow_handler/event_helper.rb +18 -0
- data/lib/controll/flow_handler/redirect.rb +51 -0
- data/lib/controll/flow_handler/redirect/action.rb +45 -0
- data/lib/controll/flow_handler/redirect/mapper.rb +41 -0
- data/lib/controll/flow_handler/render.rb +51 -0
- data/lib/controll/helper.rb +101 -0
- data/lib/controll/helper/event_matcher.rb +21 -0
- data/lib/controll/helper/hash_access.rb +26 -0
- data/lib/controll/helper/notify.rb +74 -0
- data/lib/controll/helper/params.rb +20 -0
- data/lib/controll/helper/path_resolver.rb +45 -0
- data/lib/controll/helper/session.rb +20 -0
- data/lib/controll/notify.rb +7 -0
- data/lib/controll/notify/base.rb +75 -0
- data/lib/controll/notify/flash.rb +52 -0
- data/lib/controll/notify/typed.rb +39 -0
- data/spec/acceptance/app_test.rb +156 -0
- data/spec/app/.gitignore +15 -0
- data/spec/app/Gemfile +6 -0
- data/spec/app/Gemfile.lock +108 -0
- data/spec/app/README.rdoc +261 -0
- data/spec/app/Rakefile +7 -0
- data/spec/app/app/controllers/application_controller.rb +6 -0
- data/spec/app/app/controllers/posts_controller.rb +52 -0
- data/spec/app/app/models/.gitkeep +0 -0
- data/spec/app/app/models/post.rb +88 -0
- data/spec/app/app/views/layouts/application.html.erb +13 -0
- data/spec/app/app/views/posts/_form.html.erb +31 -0
- data/spec/app/app/views/posts/edit.html.erb +6 -0
- data/spec/app/app/views/posts/index.html.erb +23 -0
- data/spec/app/app/views/posts/new.html.erb +5 -0
- data/spec/app/app/views/posts/show.html.erb +8 -0
- data/spec/app/config.ru +4 -0
- data/spec/app/config/application.rb +16 -0
- data/spec/app/config/boot.rb +6 -0
- data/spec/app/config/environment.rb +5 -0
- data/spec/app/config/environments/development.rb +21 -0
- data/spec/app/config/environments/test.rb +29 -0
- data/spec/app/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/app/config/initializers/inflections.rb +15 -0
- data/spec/app/config/initializers/mime_types.rb +5 -0
- data/spec/app/config/initializers/secret_token.rb +7 -0
- data/spec/app/config/initializers/session_store.rb +8 -0
- data/spec/app/config/locales/en.yml +5 -0
- data/spec/app/config/routes.rb +62 -0
- data/spec/app/db/seeds.rb +7 -0
- data/spec/app/lib/assets/.gitkeep +0 -0
- data/spec/app/lib/tasks/.gitkeep +0 -0
- data/spec/app/log/.gitkeep +0 -0
- data/spec/app/public/404.html +26 -0
- data/spec/app/public/422.html +26 -0
- data/spec/app/public/500.html +25 -0
- data/spec/app/public/favicon.ico +0 -0
- data/spec/app/public/index.html +241 -0
- data/spec/app/public/javascripts/application.js +9663 -0
- data/spec/app/public/robots.txt +5 -0
- data/spec/app/public/stylesheets/application.css +83 -0
- data/spec/app/script/rails +6 -0
- data/spec/app/spec/controllers/posts_controller_spec.rb +59 -0
- data/spec/app/spec/isolated_spec_helper.rb +6 -0
- data/spec/app/spec/spec_helper.rb +5 -0
- data/spec/app/spec/unit/controllers/posts_controller_isolated_spec.rb +63 -0
- data/spec/app/spec/unit/controllers/posts_controller_spec.rb +59 -0
- data/spec/app/test/functional/.gitkeep +0 -0
- data/spec/app/test/functional/posts_controller_test.rb +67 -0
- data/spec/app/test/isolated_test_helper.rb +7 -0
- data/spec/app/test/test_helper.rb +6 -0
- data/spec/app/test/unit/.gitkeep +0 -0
- data/spec/app/test/unit/controllers/posts_controller_isolated_test.rb +71 -0
- data/spec/app/test/unit/controllers/posts_controller_test.rb +67 -0
- data/spec/app/vendor/assets/javascripts/.gitkeep +0 -0
- data/spec/app/vendor/assets/stylesheets/.gitkeep +0 -0
- data/spec/app/vendor/plugins/.gitkeep +0 -0
- data/spec/controll/asssistant_spec.rb +5 -0
- data/spec/controll/command_spec.rb +56 -0
- data/spec/controll/commander_spec.rb +68 -0
- data/spec/controll/executor/notificator_spec.rb +27 -0
- data/spec/controll/flow_handler/control_spec.rb +159 -0
- data/spec/controll/flow_handler/redirect/action_spec.rb +48 -0
- data/spec/controll/flow_handler/redirect/mapper_spec.rb +69 -0
- data/spec/controll/flow_handler/redirect_spec.rb +93 -0
- data/spec/controll/flow_handler/render_spec.rb +110 -0
- data/spec/controll/helper/event_matcher_spec.rb +21 -0
- data/spec/controll/helper/hash_access_spec.rb +25 -0
- data/spec/controll/helper/notify_spec.rb +48 -0
- data/spec/controll/helper/params_spec.rb +28 -0
- data/spec/controll/helper/path_resolver_spec.rb +49 -0
- data/spec/controll/helper/session_spec.rb +28 -0
- data/spec/controll/helper_spec.rb +108 -0
- data/spec/controll/notify/base_spec.rb +123 -0
- data/spec/controll/notify/flash_spec.rb +27 -0
- data/spec/controll/notify/message_handler.rb +72 -0
- data/spec/controll/notify/typed_spec.rb +28 -0
- data/spec/functional_test_helper.rb +25 -0
- data/spec/helper.rb +33 -0
- data/spec/rspec_controller_class.rb +15 -0
- data/spec/rspec_functional_helper.rb +25 -0
- data/spec/rspec_helper.rb +42 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/test_helper.rb +183 -0
- data/spec/unit/functional_test_helper_test.rb +65 -0
- data/spec/unit/macros_test.rb +43 -0
- data/spec/unit/mixin_test.rb +147 -0
- data/spec/unit/rspec_functional_helper.rb +42 -0
- data/spec/unit/rspec_helper_test.rb +91 -0
- data/spec/unit/test_helper_test.rb +235 -0
- metadata +289 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module FocusedController
|
|
2
|
+
module RSpecControllerClass
|
|
3
|
+
def controller_class
|
|
4
|
+
metadata = self.metadata[:example_group]
|
|
5
|
+
klass = nil
|
|
6
|
+
|
|
7
|
+
until metadata.nil? || klass.respond_to?(:new)
|
|
8
|
+
klass = metadata[:description_args].first
|
|
9
|
+
metadata = metadata[:example_group]
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
klass.respond_to?(:new) ? klass : super
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require 'action_controller'
|
|
2
|
+
require 'action_view'
|
|
3
|
+
require 'action_dispatch'
|
|
4
|
+
require 'rspec/rails'
|
|
5
|
+
require 'focused_controller/functional_test_helper'
|
|
6
|
+
require 'focused_controller/rspec_controller_class'
|
|
7
|
+
|
|
8
|
+
module FocusedController
|
|
9
|
+
module RSpecFunctionalHelper
|
|
10
|
+
def self.append_features(base)
|
|
11
|
+
base.class_eval do
|
|
12
|
+
# This must be included first
|
|
13
|
+
include RSpec::Rails::ControllerExampleGroup
|
|
14
|
+
extend ClassMethods
|
|
15
|
+
include FocusedController::FunctionalTestHelper
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
super
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
module ClassMethods
|
|
22
|
+
include FocusedController::RSpecControllerClass
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require 'focused_controller/test_helper'
|
|
2
|
+
require 'focused_controller/rspec_controller_class'
|
|
3
|
+
|
|
4
|
+
begin
|
|
5
|
+
# Requiring specific files rather than just 'rspec/rails' because I don't
|
|
6
|
+
# want to force the configuration that 'rspec/rails' adds on people if they
|
|
7
|
+
# haven't specifically chosen to receive it.
|
|
8
|
+
require 'rspec/rails/matchers'
|
|
9
|
+
require 'rspec/rails/adapters'
|
|
10
|
+
require 'rspec/rails/example/rails_example_group'
|
|
11
|
+
rescue LoadError
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
module FocusedController
|
|
15
|
+
module RSpecHelper
|
|
16
|
+
def self.append_features(base)
|
|
17
|
+
base.class_eval do
|
|
18
|
+
# This must get included higher in the ancestor chain than
|
|
19
|
+
# this module so that inheritance works as desired
|
|
20
|
+
include FocusedController::TestHelper
|
|
21
|
+
extend ClassMethods
|
|
22
|
+
subject { controller }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
super
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
if defined?(RSpec::Rails)
|
|
29
|
+
include RSpec::Rails::RailsExampleGroup
|
|
30
|
+
include RSpec::Rails::Matchers::RedirectTo
|
|
31
|
+
include RSpec::Rails::Matchers::RenderTemplate
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
module ClassMethods
|
|
35
|
+
include FocusedController::RSpecControllerClass
|
|
36
|
+
|
|
37
|
+
def stub_url(*helper_names)
|
|
38
|
+
before { stub_url(*helper_names) }
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require 'rspec'
|
|
2
|
+
require 'rails'
|
|
3
|
+
require 'controll'
|
|
4
|
+
|
|
5
|
+
# Requires supporting files with custom matchers and macros, etc,
|
|
6
|
+
# in ./support/ and its subdirectories.
|
|
7
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
|
8
|
+
|
|
9
|
+
RSpec.configure do |config|
|
|
10
|
+
|
|
11
|
+
end
|
data/spec/test_helper.rb
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
require 'action_dispatch'
|
|
2
|
+
require 'active_support/concern'
|
|
3
|
+
require 'active_support/core_ext/class/attribute'
|
|
4
|
+
require 'active_support/hash_with_indifferent_access'
|
|
5
|
+
|
|
6
|
+
module FocusedController
|
|
7
|
+
module TestHooks
|
|
8
|
+
attr_reader :_render_options
|
|
9
|
+
|
|
10
|
+
def render_to_body(options = {})
|
|
11
|
+
_process_options(options)
|
|
12
|
+
@_render_options = options
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def url_for(options = nil)
|
|
16
|
+
if options.is_a?(StubbedURL)
|
|
17
|
+
options
|
|
18
|
+
else
|
|
19
|
+
super
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
class TestRequest < ActionDispatch::TestRequest
|
|
25
|
+
def initialize(env = {})
|
|
26
|
+
super
|
|
27
|
+
self.session = HashWithIndifferentAccess.new
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def cookie_jar
|
|
31
|
+
@cookie_jar ||= ActionDispatch::Cookies::CookieJar.new
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def flash
|
|
35
|
+
session['flash'] ||= ActionDispatch::Flash::FlashHash.new
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
class TestResponse < ActionDispatch::TestResponse
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
class StubbedURL
|
|
43
|
+
attr_reader :helper_name, :args
|
|
44
|
+
|
|
45
|
+
def initialize(helper_name, args)
|
|
46
|
+
@helper_name = helper_name.to_s
|
|
47
|
+
@args = args
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def ==(other)
|
|
51
|
+
other.is_a?(self.class) &&
|
|
52
|
+
helper_name == other.helper_name &&
|
|
53
|
+
args == other.args
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Deals with _compute_redirect_to_location in action_controller/metal/redirecting
|
|
57
|
+
# (I don't feel proud about this...)
|
|
58
|
+
def gsub(*)
|
|
59
|
+
self
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def to_s
|
|
63
|
+
"#{helper_name}(#{args.each(&:to_s).join(', ')})"
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
module TestHelper
|
|
68
|
+
extend ActiveSupport::Concern
|
|
69
|
+
include ActionDispatch::Assertions::ResponseAssertions
|
|
70
|
+
|
|
71
|
+
included do
|
|
72
|
+
class_attribute :_controller_class, :instance_reader => false, :instance_writer => false
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
module ClassMethods
|
|
76
|
+
def controller_class=(klass)
|
|
77
|
+
self._controller_class = klass
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def controller_class
|
|
81
|
+
_controller_class || name.sub(/Test$/, '').constantize
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def include_routes
|
|
85
|
+
if controller_class.respond_to?(:_routes) && controller_class._routes
|
|
86
|
+
include controller_class._routes.named_routes.module
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def stub_url(*names)
|
|
91
|
+
setup { stub_url(*names) }
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def controller
|
|
96
|
+
@controller ||= begin
|
|
97
|
+
controller = self.class.controller_class.new
|
|
98
|
+
controller.singleton_class.send :include, TestHooks
|
|
99
|
+
controller.request = request
|
|
100
|
+
controller.response = response
|
|
101
|
+
controller
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def request
|
|
106
|
+
@request ||= TestRequest.new
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def response
|
|
110
|
+
@response ||= TestResponse.new
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def req(params = nil, session = nil, flash = nil)
|
|
114
|
+
controller.params = params if params
|
|
115
|
+
controller.session.update session if session
|
|
116
|
+
controller.flash.update flash if flash
|
|
117
|
+
controller.run
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def session
|
|
121
|
+
controller.session
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def flash
|
|
125
|
+
controller.flash
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def cookies
|
|
129
|
+
request.cookie_jar
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def assert_template(template, message = nil)
|
|
133
|
+
assert_equal template.to_s, controller._render_options[:template], message
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def assert_response(type, message = nil)
|
|
137
|
+
controller # make sure controller is initialized
|
|
138
|
+
super
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def assert_redirected_to(location, message = nil)
|
|
142
|
+
controller # make sure controller is initialized
|
|
143
|
+
super
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def url_for(*args)
|
|
147
|
+
controller.url_for(*args)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def respond_to?(*args)
|
|
151
|
+
unless defined?(@_routes_included) && @_routes_included
|
|
152
|
+
self.class.include_routes
|
|
153
|
+
@_routes_included = true
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
super
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def method_missing(method_name, *args, &block)
|
|
160
|
+
if respond_to?(method_name)
|
|
161
|
+
send(method_name, *args, &block)
|
|
162
|
+
else
|
|
163
|
+
super
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def stub_url(*names)
|
|
168
|
+
[self, controller].each do |host|
|
|
169
|
+
host.singleton_class.class_eval do
|
|
170
|
+
names.each do |name|
|
|
171
|
+
define_method("#{name}_url") do |*args|
|
|
172
|
+
StubbedURL.new("#{name}_url", args)
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
define_method("#{name}_path") do |*args|
|
|
176
|
+
StubbedURL.new("#{name}_path", args)
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
require 'helper'
|
|
2
|
+
require 'focused_controller/functional_test_helper'
|
|
3
|
+
require 'action_controller'
|
|
4
|
+
|
|
5
|
+
module FocusedController
|
|
6
|
+
module FunctionalTestHelper
|
|
7
|
+
class FakePostsController
|
|
8
|
+
class Action < ActionController::Base; end
|
|
9
|
+
class Index < Action; end
|
|
10
|
+
class Show < Action; end
|
|
11
|
+
|
|
12
|
+
class TestCase < ActionController::TestCase
|
|
13
|
+
include FocusedController::FunctionalTestHelper
|
|
14
|
+
|
|
15
|
+
def initialize(method_name = :foo)
|
|
16
|
+
super
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def foo; end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
class IndexTest < TestCase
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
class ShowTest < TestCase
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe FunctionalTestHelper do
|
|
30
|
+
subject { FakePostsController::IndexTest.new }
|
|
31
|
+
|
|
32
|
+
it 'automatically determines the controller class' do
|
|
33
|
+
FakePostsController::IndexTest.controller_class.
|
|
34
|
+
must_equal FakePostsController::Index
|
|
35
|
+
FakePostsController::ShowTest.controller_class.
|
|
36
|
+
must_equal FakePostsController::Show
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "doesn't require using the action name to dispatch the action" do
|
|
40
|
+
subject.singleton_class.class_eval do
|
|
41
|
+
attr_reader :last_process
|
|
42
|
+
|
|
43
|
+
def process(*args)
|
|
44
|
+
@last_process = args
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
subject.get :foo, :bar, :baz
|
|
49
|
+
subject.last_process.must_equal ['run', :foo, :bar, :baz, 'GET']
|
|
50
|
+
|
|
51
|
+
subject.post :foo, :bar, :baz
|
|
52
|
+
subject.last_process.must_equal ['run', :foo, :bar, :baz, 'POST']
|
|
53
|
+
|
|
54
|
+
subject.put :foo, :bar, :baz
|
|
55
|
+
subject.last_process.must_equal ['run', :foo, :bar, :baz, 'PUT']
|
|
56
|
+
|
|
57
|
+
subject.delete :foo, :bar, :baz
|
|
58
|
+
subject.last_process.must_equal ['run', :foo, :bar, :baz, 'DELETE']
|
|
59
|
+
|
|
60
|
+
subject.head :foo, :bar, :baz
|
|
61
|
+
subject.last_process.must_equal ['run', :foo, :bar, :baz, 'HEAD']
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require 'helper'
|
|
2
|
+
|
|
3
|
+
class ApplicationController
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
require 'focused_controller/macros'
|
|
7
|
+
|
|
8
|
+
class MyBaseAction < ::FocusedAction
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
module FocusedController
|
|
12
|
+
describe Macros do
|
|
13
|
+
describe ".focused_action" do
|
|
14
|
+
let(:klass) do
|
|
15
|
+
klass = Class.new(FocusedController::Test::MixinTestController)
|
|
16
|
+
klass.name = "PostsController"
|
|
17
|
+
klass.use_focused_macros
|
|
18
|
+
klass.action_parent MyBaseAction
|
|
19
|
+
klass
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
subject { klass }
|
|
23
|
+
|
|
24
|
+
describe 'create an Action class with a #run method' do
|
|
25
|
+
before do
|
|
26
|
+
subject.focused_action(:show) do
|
|
27
|
+
def run
|
|
28
|
+
"running"
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'should have the superclass MyBaseAction' do
|
|
34
|
+
subject::Show.superclass.should == MyBaseAction
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'should have a run method' do
|
|
38
|
+
subject::Show.new.run.should == "running"
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
require 'helper'
|
|
2
|
+
require 'action_controller'
|
|
3
|
+
|
|
4
|
+
module FocusedController
|
|
5
|
+
module Test
|
|
6
|
+
class MixinTestBaseController
|
|
7
|
+
def view_assigns
|
|
8
|
+
{'some' => 'var'}
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
class MixinTestController < ActionController::Base
|
|
13
|
+
include FocusedController::Mixin
|
|
14
|
+
|
|
15
|
+
class << self
|
|
16
|
+
attr_accessor :name
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
module FocusedController
|
|
23
|
+
describe Mixin do
|
|
24
|
+
describe "with a PostsController::Show class" do
|
|
25
|
+
let(:klass) do
|
|
26
|
+
klass = Class.new(FocusedController::Test::MixinTestController)
|
|
27
|
+
klass.name = "PostsController::Show"
|
|
28
|
+
klass
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
subject { klass.new }
|
|
32
|
+
|
|
33
|
+
it "has a .controller_path of 'posts'" do
|
|
34
|
+
klass.controller_path.must_equal 'posts'
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "has a .call which dispatches the #run action" do
|
|
38
|
+
def klass.action(name)
|
|
39
|
+
if name.to_s == 'run'
|
|
40
|
+
proc { |env| "omg" }
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
klass.call(nil).must_equal "omg"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "has an #action_name of 'show'" do
|
|
48
|
+
subject.action_name.must_equal 'show'
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "uses the run method for the action" do
|
|
52
|
+
subject.method_for_action('whatever').must_equal 'run'
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "removes all view assigns by default" do
|
|
56
|
+
subject.view_assigns.must_equal({})
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "can be configured to allow view assigns" do
|
|
60
|
+
subject.class.allow_view_assigns = true
|
|
61
|
+
subject.instance_variable_set('@foo', 'bar')
|
|
62
|
+
subject.view_assigns['foo'].must_equal('bar')
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it "has a #run method by default" do
|
|
66
|
+
subject.run.must_equal nil
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
describe '.run' do
|
|
71
|
+
subject do
|
|
72
|
+
@klass = Class.new do
|
|
73
|
+
include FocusedController::Mixin
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it 'defines a #run method' do
|
|
78
|
+
subject.run { 'running' }
|
|
79
|
+
subject.new.run.must_equal 'running'
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
describe '.expose' do
|
|
84
|
+
subject do
|
|
85
|
+
@klass = Class.new do
|
|
86
|
+
include FocusedController::Mixin
|
|
87
|
+
|
|
88
|
+
@helper_methods = []
|
|
89
|
+
|
|
90
|
+
class << self
|
|
91
|
+
attr_reader :helper_methods
|
|
92
|
+
|
|
93
|
+
def helper_method(name)
|
|
94
|
+
@helper_methods << name
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it 'defines a #foo method' do
|
|
101
|
+
subject.expose(:foo) { 'bar' }
|
|
102
|
+
subject.new.foo.must_equal 'bar'
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it 'declares the method a helper method' do
|
|
106
|
+
subject.expose(:foo) { 'bar' }
|
|
107
|
+
subject.helper_methods.must_equal [:foo]
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it 'memoizes the result' do
|
|
111
|
+
count = 0
|
|
112
|
+
counter = proc { count += 1 }
|
|
113
|
+
subject.expose(:foo) { counter.call }
|
|
114
|
+
|
|
115
|
+
obj = subject.new
|
|
116
|
+
obj.foo.must_equal 1
|
|
117
|
+
obj.foo.must_equal 1
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
it 'it memoizes falsey values' do
|
|
121
|
+
val = true
|
|
122
|
+
meth = proc { val = !val }
|
|
123
|
+
subject.expose(:foo) { meth.call }
|
|
124
|
+
|
|
125
|
+
obj = subject.new
|
|
126
|
+
obj.foo.must_equal false
|
|
127
|
+
obj.foo.must_equal false
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
it 'instance evals the block' do
|
|
131
|
+
subject.expose(:foo) { @bar }
|
|
132
|
+
obj = subject.new
|
|
133
|
+
obj.instance_variable_set('@bar', 'bar')
|
|
134
|
+
obj.foo.must_equal 'bar'
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
it 'declares an attr_reader when called without a block' do
|
|
138
|
+
subject.expose :foo
|
|
139
|
+
subject.helper_methods.must_equal [:foo]
|
|
140
|
+
|
|
141
|
+
obj = subject.new
|
|
142
|
+
obj.instance_variable_set('@foo', 'bar')
|
|
143
|
+
obj.foo.must_equal 'bar'
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|