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.
Files changed (128) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +19 -0
  4. data/Gemfile.lock +134 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.md +320 -0
  7. data/Rakefile +49 -0
  8. data/VERSION +1 -0
  9. data/controll.gemspec +184 -0
  10. data/lib/controll.rb +14 -0
  11. data/lib/controll/assistant.rb +19 -0
  12. data/lib/controll/command.rb +24 -0
  13. data/lib/controll/commander.rb +24 -0
  14. data/lib/controll/errors.rb +1 -0
  15. data/lib/controll/executor.rb +6 -0
  16. data/lib/controll/executor/base.rb +16 -0
  17. data/lib/controll/executor/notificator.rb +12 -0
  18. data/lib/controll/flow_handler.rb +11 -0
  19. data/lib/controll/flow_handler/base.rb +19 -0
  20. data/lib/controll/flow_handler/control.rb +85 -0
  21. data/lib/controll/flow_handler/errors.rb +5 -0
  22. data/lib/controll/flow_handler/event_helper.rb +18 -0
  23. data/lib/controll/flow_handler/redirect.rb +51 -0
  24. data/lib/controll/flow_handler/redirect/action.rb +45 -0
  25. data/lib/controll/flow_handler/redirect/mapper.rb +41 -0
  26. data/lib/controll/flow_handler/render.rb +51 -0
  27. data/lib/controll/helper.rb +101 -0
  28. data/lib/controll/helper/event_matcher.rb +21 -0
  29. data/lib/controll/helper/hash_access.rb +26 -0
  30. data/lib/controll/helper/notify.rb +74 -0
  31. data/lib/controll/helper/params.rb +20 -0
  32. data/lib/controll/helper/path_resolver.rb +45 -0
  33. data/lib/controll/helper/session.rb +20 -0
  34. data/lib/controll/notify.rb +7 -0
  35. data/lib/controll/notify/base.rb +75 -0
  36. data/lib/controll/notify/flash.rb +52 -0
  37. data/lib/controll/notify/typed.rb +39 -0
  38. data/spec/acceptance/app_test.rb +156 -0
  39. data/spec/app/.gitignore +15 -0
  40. data/spec/app/Gemfile +6 -0
  41. data/spec/app/Gemfile.lock +108 -0
  42. data/spec/app/README.rdoc +261 -0
  43. data/spec/app/Rakefile +7 -0
  44. data/spec/app/app/controllers/application_controller.rb +6 -0
  45. data/spec/app/app/controllers/posts_controller.rb +52 -0
  46. data/spec/app/app/models/.gitkeep +0 -0
  47. data/spec/app/app/models/post.rb +88 -0
  48. data/spec/app/app/views/layouts/application.html.erb +13 -0
  49. data/spec/app/app/views/posts/_form.html.erb +31 -0
  50. data/spec/app/app/views/posts/edit.html.erb +6 -0
  51. data/spec/app/app/views/posts/index.html.erb +23 -0
  52. data/spec/app/app/views/posts/new.html.erb +5 -0
  53. data/spec/app/app/views/posts/show.html.erb +8 -0
  54. data/spec/app/config.ru +4 -0
  55. data/spec/app/config/application.rb +16 -0
  56. data/spec/app/config/boot.rb +6 -0
  57. data/spec/app/config/environment.rb +5 -0
  58. data/spec/app/config/environments/development.rb +21 -0
  59. data/spec/app/config/environments/test.rb +29 -0
  60. data/spec/app/config/initializers/backtrace_silencers.rb +7 -0
  61. data/spec/app/config/initializers/inflections.rb +15 -0
  62. data/spec/app/config/initializers/mime_types.rb +5 -0
  63. data/spec/app/config/initializers/secret_token.rb +7 -0
  64. data/spec/app/config/initializers/session_store.rb +8 -0
  65. data/spec/app/config/locales/en.yml +5 -0
  66. data/spec/app/config/routes.rb +62 -0
  67. data/spec/app/db/seeds.rb +7 -0
  68. data/spec/app/lib/assets/.gitkeep +0 -0
  69. data/spec/app/lib/tasks/.gitkeep +0 -0
  70. data/spec/app/log/.gitkeep +0 -0
  71. data/spec/app/public/404.html +26 -0
  72. data/spec/app/public/422.html +26 -0
  73. data/spec/app/public/500.html +25 -0
  74. data/spec/app/public/favicon.ico +0 -0
  75. data/spec/app/public/index.html +241 -0
  76. data/spec/app/public/javascripts/application.js +9663 -0
  77. data/spec/app/public/robots.txt +5 -0
  78. data/spec/app/public/stylesheets/application.css +83 -0
  79. data/spec/app/script/rails +6 -0
  80. data/spec/app/spec/controllers/posts_controller_spec.rb +59 -0
  81. data/spec/app/spec/isolated_spec_helper.rb +6 -0
  82. data/spec/app/spec/spec_helper.rb +5 -0
  83. data/spec/app/spec/unit/controllers/posts_controller_isolated_spec.rb +63 -0
  84. data/spec/app/spec/unit/controllers/posts_controller_spec.rb +59 -0
  85. data/spec/app/test/functional/.gitkeep +0 -0
  86. data/spec/app/test/functional/posts_controller_test.rb +67 -0
  87. data/spec/app/test/isolated_test_helper.rb +7 -0
  88. data/spec/app/test/test_helper.rb +6 -0
  89. data/spec/app/test/unit/.gitkeep +0 -0
  90. data/spec/app/test/unit/controllers/posts_controller_isolated_test.rb +71 -0
  91. data/spec/app/test/unit/controllers/posts_controller_test.rb +67 -0
  92. data/spec/app/vendor/assets/javascripts/.gitkeep +0 -0
  93. data/spec/app/vendor/assets/stylesheets/.gitkeep +0 -0
  94. data/spec/app/vendor/plugins/.gitkeep +0 -0
  95. data/spec/controll/asssistant_spec.rb +5 -0
  96. data/spec/controll/command_spec.rb +56 -0
  97. data/spec/controll/commander_spec.rb +68 -0
  98. data/spec/controll/executor/notificator_spec.rb +27 -0
  99. data/spec/controll/flow_handler/control_spec.rb +159 -0
  100. data/spec/controll/flow_handler/redirect/action_spec.rb +48 -0
  101. data/spec/controll/flow_handler/redirect/mapper_spec.rb +69 -0
  102. data/spec/controll/flow_handler/redirect_spec.rb +93 -0
  103. data/spec/controll/flow_handler/render_spec.rb +110 -0
  104. data/spec/controll/helper/event_matcher_spec.rb +21 -0
  105. data/spec/controll/helper/hash_access_spec.rb +25 -0
  106. data/spec/controll/helper/notify_spec.rb +48 -0
  107. data/spec/controll/helper/params_spec.rb +28 -0
  108. data/spec/controll/helper/path_resolver_spec.rb +49 -0
  109. data/spec/controll/helper/session_spec.rb +28 -0
  110. data/spec/controll/helper_spec.rb +108 -0
  111. data/spec/controll/notify/base_spec.rb +123 -0
  112. data/spec/controll/notify/flash_spec.rb +27 -0
  113. data/spec/controll/notify/message_handler.rb +72 -0
  114. data/spec/controll/notify/typed_spec.rb +28 -0
  115. data/spec/functional_test_helper.rb +25 -0
  116. data/spec/helper.rb +33 -0
  117. data/spec/rspec_controller_class.rb +15 -0
  118. data/spec/rspec_functional_helper.rb +25 -0
  119. data/spec/rspec_helper.rb +42 -0
  120. data/spec/spec_helper.rb +11 -0
  121. data/spec/test_helper.rb +183 -0
  122. data/spec/unit/functional_test_helper_test.rb +65 -0
  123. data/spec/unit/macros_test.rb +43 -0
  124. data/spec/unit/mixin_test.rb +147 -0
  125. data/spec/unit/rspec_functional_helper.rb +42 -0
  126. data/spec/unit/rspec_helper_test.rb +91 -0
  127. data/spec/unit/test_helper_test.rb +235 -0
  128. 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
@@ -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
@@ -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