mithril 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 (41) hide show
  1. data/CHANGELOG.md +31 -0
  2. data/README.md +0 -0
  3. data/bin/mithril +5 -0
  4. data/lib/mithril.rb +13 -0
  5. data/lib/mithril/controllers.rb +7 -0
  6. data/lib/mithril/controllers/abstract_controller.rb +130 -0
  7. data/lib/mithril/controllers/mixins.rb +7 -0
  8. data/lib/mithril/controllers/mixins/actions_base.rb +114 -0
  9. data/lib/mithril/controllers/mixins/help_actions.rb +46 -0
  10. data/lib/mithril/controllers/mixins/mixin_with_actions.rb +27 -0
  11. data/lib/mithril/controllers/proxy_controller.rb +89 -0
  12. data/lib/mithril/mixin.rb +33 -0
  13. data/lib/mithril/parsers.rb +7 -0
  14. data/lib/mithril/parsers/simple_parser.rb +57 -0
  15. data/lib/mithril/request.rb +11 -0
  16. data/lib/mithril/version.rb +5 -0
  17. data/spec/matchers/be_kind_of_spec.rb +50 -0
  18. data/spec/matchers/construct_spec.rb +49 -0
  19. data/spec/matchers/respond_to_spec.rb +158 -0
  20. data/spec/mithril/controllers/_text_controller_helper.rb +81 -0
  21. data/spec/mithril/controllers/abstract_controller_helper.rb +118 -0
  22. data/spec/mithril/controllers/abstract_controller_spec.rb +15 -0
  23. data/spec/mithril/controllers/mixins/actions_base_helper.rb +121 -0
  24. data/spec/mithril/controllers/mixins/actions_base_spec.rb +18 -0
  25. data/spec/mithril/controllers/mixins/help_actions_helper.rb +111 -0
  26. data/spec/mithril/controllers/mixins/help_actions_spec.rb +19 -0
  27. data/spec/mithril/controllers/mixins/mixin_with_actions_spec.rb +44 -0
  28. data/spec/mithril/controllers/proxy_controller_helper.rb +111 -0
  29. data/spec/mithril/controllers/proxy_controller_spec.rb +14 -0
  30. data/spec/mithril/mixin_helper.rb +54 -0
  31. data/spec/mithril/mixin_spec.rb +17 -0
  32. data/spec/mithril/parsers/simple_parser_spec.rb +85 -0
  33. data/spec/mithril/request_spec.rb +72 -0
  34. data/spec/mithril_spec.rb +25 -0
  35. data/spec/spec_helper.rb +15 -0
  36. data/spec/support/factories/action_factory.rb +7 -0
  37. data/spec/support/factories/request_factory.rb +11 -0
  38. data/spec/support/matchers/be_kind_of.rb +23 -0
  39. data/spec/support/matchers/construct.rb +49 -0
  40. data/spec/support/matchers/respond_to.rb +52 -0
  41. metadata +142 -0
@@ -0,0 +1,118 @@
1
+ # spec/mithril/controllers/abstract_controller_helper.rb
2
+
3
+ require 'mithril/controllers/mixins/actions_base_helper'
4
+
5
+ require 'mithril/controllers/abstract_controller'
6
+
7
+ shared_examples_for Mithril::Controllers::AbstractController do
8
+ it_behaves_like Mithril::Controllers::Mixins::ActionsBase
9
+
10
+ describe :constructor do
11
+ specify { expect(described_class).to construct.with(1).arguments }
12
+ specify { expect { described_class.new request }.not_to raise_error }
13
+ end # describe
14
+
15
+ describe :parser do
16
+ specify { expect(instance).to respond_to(:parser).with(0).arguments }
17
+ end # describe
18
+
19
+ describe :parse_command do
20
+ let :input do Object.new; end
21
+
22
+ specify { expect(instance).to respond_to(:parse_command).with(1).arguments }
23
+ specify "delegates to the parser" do
24
+ instance.parser.should_receive(:parse_command).with(input)
25
+ instance.parse_command(input)
26
+ end # specify
27
+ end # describe
28
+
29
+ describe :command_missing do
30
+ let :input do Object.new; end
31
+
32
+ specify { expect(instance).to respond_to(:command_missing).with(1).arguments }
33
+ end # describe
34
+
35
+ describe :commands do
36
+ specify { expect(instance).to respond_to(:commands).with(0).arguments }
37
+ specify { expect(instance.commands).to be_a Array }
38
+ end # describe
39
+
40
+ describe :has_command? do
41
+ specify { expect(instance).to respond_to(:has_command?).with(1).arguments }
42
+ specify { expect(instance).not_to have_command FactoryGirl.generate :action_key }
43
+ end # describe
44
+
45
+ describe :can_invoke? do
46
+ specify { expect(instance).to respond_to(:can_invoke?).with(1).arguments }
47
+ specify { expect(instance.can_invoke? FactoryGirl.generate(:action_key).to_s).
48
+ to eq false }
49
+ end # describe
50
+
51
+ describe :invoke_command do
52
+ specify { expect(instance).to respond_to(:invoke_command).with(1).arguments }
53
+ end # describe
54
+
55
+ context "with actions defined" do
56
+ let :command do FactoryGirl.generate :action_key; end
57
+
58
+ before :each do described_class.define_action command do |session, args|; end; end
59
+
60
+ specify { expect(instance.commands).to include command.to_s.gsub('_',' ') }
61
+
62
+ specify { expect(instance).to have_action command }
63
+
64
+ describe "inheriting defined actions" do
65
+ let :descendant_class do Class.new described_class; end
66
+ let :instance do descendant_class.new request; end
67
+
68
+ specify { expect(instance).to have_action command }
69
+ end # describe
70
+ end # context
71
+
72
+ describe "empty actions" do
73
+ describe :allow_empty_action? do
74
+ specify { expect(instance).to respond_to(:allow_empty_action?).with(0).arguments }
75
+ end # describe
76
+ end # describe
77
+ end # shared examples
78
+
79
+ shared_examples_for "Mithril::Controllers::AbstractController#empty_actions" do |input|
80
+ let :arguments do instance.parse_command(input)[1]; end
81
+
82
+ before :each do
83
+ if instance.has_action? :""
84
+ instance.stub :_action do |session, arguments| arguments; end
85
+ else
86
+ described_class.send :define_action, :"" do |session, arguments| arguments; end
87
+ end # if-else
88
+ end # before each
89
+
90
+ context "disallowing empty actions" do
91
+ before :each do instance.stub :allow_empty_action? do false; end; end
92
+
93
+ specify { expect(instance.allow_empty_action?).to be false }
94
+
95
+ specify "rejects arbitrary input" do
96
+ expect(instance.can_invoke? input).to be false
97
+ end # describe
98
+ end # context
99
+
100
+ context "allowing empty actions" do
101
+ before :each do instance.stub :allow_empty_action? do true; end; end
102
+
103
+ specify { expect(instance.allow_empty_action?).to be true }
104
+
105
+ specify "accepts arbitrary input" do
106
+ expect(instance.can_invoke? input).to be true
107
+ end # specify
108
+
109
+ specify "calls invoke action on empty action" do
110
+ instance.should_receive(:invoke_action).with(:"", arguments).and_call_original
111
+ instance.invoke_command input
112
+ end # specify
113
+
114
+ specify "returns the input" do
115
+ expect(instance.invoke_command input).to eq arguments
116
+ end # specify
117
+ end # context
118
+ end # shared examples
@@ -0,0 +1,15 @@
1
+ # spec/controllers/mithril/abstract_controller_spec.rb
2
+
3
+ require 'spec_helper'
4
+ require 'mithril/controllers/_text_controller_helper'
5
+
6
+ require 'mithril/controllers/abstract_controller'
7
+ require 'mithril/parsers/simple_parser'
8
+
9
+ describe Mithril::Controllers::AbstractController do
10
+ let :request do FactoryGirl.build :request; end
11
+ let :described_class do Class.new super(); end
12
+ let :instance do described_class.new request; end
13
+
14
+ it_behaves_like "Mithril::Controllers::_TextController"
15
+ end # describe
@@ -0,0 +1,121 @@
1
+ # spec/mithril/controllers/mixins/actions_base_helper.rb
2
+
3
+ require 'mithril/controllers/mixins/actions_base'
4
+ require 'mithril/request'
5
+
6
+ shared_examples_for Mithril::Controllers::Mixins::ActionsBase do
7
+ let :command do FactoryGirl.generate :action_key; end
8
+
9
+ specify { expect(instance).not_to respond_to :"action_#{command}" }
10
+
11
+ describe "self.define_action" do
12
+ specify { expect(described_class).to respond_to(:define_action).
13
+ with(1..2).arguments.and.a_block }
14
+ end # describe
15
+
16
+ describe "self.actions" do
17
+ specify { expect(described_class).to respond_to(:actions).with(0..1).arguments }
18
+
19
+ specify { expect(described_class.actions).to be_a Hash }
20
+ end # describe
21
+
22
+ describe :request do
23
+ specify { expect(instance).to respond_to(:request).with(0).arguments }
24
+ specify { expect(instance.request).to be_a [Mithril::Request, nil] }
25
+ end # describe
26
+
27
+ describe :actions do
28
+ specify { expect(instance).to respond_to(:actions).with(0..1).arguments }
29
+ specify { expect(instance.actions).to be_a Hash }
30
+ end # describe
31
+
32
+ describe :has_action? do
33
+ let :command do FactoryGirl.generate :action_key; end
34
+
35
+ specify { expect(instance).to respond_to(:has_action?).with(1..2).arguments }
36
+ specify { expect(instance.has_action? command).to be false }
37
+ specify { expect(instance.has_action? command, true).to be false }
38
+ end # describe
39
+
40
+ describe :invoke_action do
41
+ specify { expect(instance).to respond_to(:invoke_action).with(2..3).arguments }
42
+ end # describe
43
+
44
+ context "with an action defined" do
45
+ let :command do FactoryGirl.generate :action_key; end
46
+
47
+ before :each do
48
+ described_class.define_action command do |session, arguments| arguments.join(" "); end
49
+ end # before each
50
+
51
+ specify { expect(described_class.actions).to have_key command }
52
+ specify { expect(described_class.actions true).to have_key command }
53
+
54
+ specify { expect(instance.actions).to have_key command }
55
+ specify { expect(instance.actions true).to have_key command }
56
+
57
+ specify { expect(instance).to have_action command }
58
+ specify { expect(instance).to have_action command, true }
59
+
60
+ describe :invoke_action do
61
+ let :request do defined?(super) ? super() : FactoryGirl.build(:request); end
62
+ let :arguments do %w(some args); end
63
+ let :output do arguments.join(" "); end
64
+
65
+ before :each do instance.stub :request do request; end; end
66
+
67
+ specify "calls the defined method" do
68
+ instance.should_receive(:"action_#{command}").with(request.session, arguments)
69
+ instance.invoke_action command, arguments
70
+ end # specify
71
+
72
+ specify "calls the defined method as private" do
73
+ instance.should_receive(:"action_#{command}").with(request.session, arguments)
74
+ instance.invoke_action command, arguments, true
75
+ end # specify
76
+
77
+ specify { instance.invoke_action(command, arguments).should eq output }
78
+ specify { instance.invoke_action(command, arguments, true).should eq output }
79
+ end # describe
80
+ end # context
81
+
82
+ describe "with a private action defined" do
83
+ let :command do FactoryGirl.generate :action_key; end
84
+
85
+ before :each do
86
+ described_class.define_action command, :private => true do |session, arguments|
87
+ arguments.join(" ")
88
+ end # define action
89
+ end # before each
90
+
91
+ specify { expect(described_class.actions).not_to have_key command }
92
+ specify { expect(described_class.actions true).to have_key command }
93
+
94
+ specify { expect(instance.actions).not_to have_key command }
95
+ specify { expect(instance.actions true).to have_key command }
96
+
97
+ specify { expect(instance).not_to have_action command }
98
+ specify { expect(instance).to have_action command, true }
99
+
100
+ describe :invoke_action do
101
+ let :request do defined?(super) ? super() : FactoryGirl.build(:request); end
102
+ let :arguments do %w(some args); end
103
+ let :output do arguments.join(" "); end
104
+
105
+ before :each do instance.stub :request do request; end; end
106
+
107
+ specify "calls the defined method" do
108
+ instance.should_not_receive(:"action_#{command}")
109
+ instance.invoke_action command, arguments
110
+ end # specify
111
+
112
+ specify "calls the defined method as private" do
113
+ instance.should_receive(:"action_#{command}").with(request.session, arguments)
114
+ instance.invoke_action command, arguments, true
115
+ end # specify
116
+
117
+ specify { instance.invoke_action(command, arguments).should be nil }
118
+ specify { instance.invoke_action(command, arguments, true).should eq output }
119
+ end # describe
120
+ end # describe
121
+ end # shared_examples
@@ -0,0 +1,18 @@
1
+ # spec/mithril/controllers/mixins/actions_base_spec.rb
2
+
3
+ require 'spec_helper'
4
+ require 'mithril/controllers/mixins/actions_base_helper'
5
+
6
+ require 'mithril/controllers/mixins/actions_base'
7
+ require 'mithril/controllers/mixins/mixin_with_actions'
8
+
9
+ describe Mithril::Controllers::Mixins::ActionsBase do
10
+ let :described_class do
11
+ klass = Class.new.extend Mithril::Controllers::Mixins::MixinWithActions
12
+ klass.send :mixin, super()
13
+ klass
14
+ end # let
15
+ let :instance do described_class.new; end
16
+
17
+ it_behaves_like Mithril::Controllers::Mixins::ActionsBase
18
+ end # describe
@@ -0,0 +1,111 @@
1
+ # spec/mithril/controllers/mixins/help_actions_helper.rb
2
+
3
+ require 'mithril/controllers/mixins/actions_base_helper'
4
+
5
+ require 'mithril/controllers/mixins/help_actions'
6
+
7
+ shared_examples_for Mithril::Controllers::Mixins::HelpActions do
8
+ it_behaves_like Mithril::Controllers::Mixins::ActionsBase
9
+
10
+ describe :help_message do
11
+ specify { expect(instance).to respond_to(:help_message).with(0).arguments }
12
+ specify { expect(instance.help_message).to be_a String }
13
+ end # describe
14
+
15
+ describe "help action" do
16
+ specify { expect(instance).to have_action :help }
17
+
18
+ context "with a help string defined" do
19
+ let :arguments do %w(); end
20
+
21
+ before :each do
22
+ instance.stub :help_message do
23
+ "You put your left foot in, you take your left foot out."
24
+ end # stub
25
+ end # before each
26
+
27
+ specify { expect(instance.invoke_action :help, arguments).
28
+ to match /put your left foot in/i }
29
+
30
+ specify { expect(instance.invoke_action :help, arguments).
31
+ to match /following commands are available/i }
32
+ end # context
33
+
34
+ describe "with no arguments" do
35
+ let :arguments do %w(); end
36
+
37
+ specify { expect(instance.invoke_action :help, arguments).
38
+ to match /following commands are available/i }
39
+ specify { expect(instance.invoke_action :help, arguments).
40
+ to match /help/i }
41
+ end # context
42
+
43
+ describe "with help" do
44
+ let :arguments do %w(help); end
45
+
46
+ specify { expect(instance.invoke_action :help, arguments).
47
+ to match /the help command/i }
48
+ end # describe
49
+ end # describe
50
+
51
+ context "with additional actions defined" do
52
+ let :action_keys do
53
+ [].tap do |ary|
54
+ 1.times do ary << FactoryGirl.generate(:action_key); end
55
+ end # tap
56
+ end # let
57
+
58
+ before :each do
59
+ action_keys.each do |key|
60
+ described_class.send :define_action, key do |session, arguments|; end
61
+ end # each
62
+ end # before each
63
+
64
+ describe "help action" do
65
+ specify "lists available commands" do
66
+ (action_keys << :help).each do |key|
67
+ command = key.to_s.gsub('_',' ')
68
+ expect(instance.invoke_action :help, %w()).to match /#{command}/
69
+ end # each
70
+ end # specify
71
+
72
+ specify "invokes the command with help" do
73
+ session = instance.request ? (instance.request.session || {}) : {}
74
+ action_keys.each do |key|
75
+ command = key.to_s.gsub('_',' ')
76
+ instance.should_receive(:"action_#{key}").with(session, %w(help))
77
+ instance.invoke_action :help, command.split(' ')
78
+ end # each
79
+ end # specify
80
+ end # describe
81
+ end # context
82
+
83
+ context "with additional commands defined" do
84
+ let :commands do
85
+ [].tap do |ary|
86
+ 1.times do ary << FactoryGirl.generate(:action_key).to_s.gsub('_', ' '); end
87
+ end # tap
88
+ end # let
89
+
90
+ before :each do
91
+ instance.stub :commands do commands; end
92
+ instance.stub :has_command? do |command| commands.include? command; end
93
+ end # before each
94
+
95
+ describe "help action" do
96
+ specify "lists available commands" do
97
+ (commands << "help").each do |command|
98
+ expect(instance.invoke_action :help, %w()).to match /#{command}/
99
+ end # each
100
+ end # specify
101
+
102
+ specify "invokes the command with help" do
103
+ session = instance.request ? (instance.request.session || {}) : {}
104
+ commands.each do |command|
105
+ instance.should_receive(:invoke_command).with("#{command} help")
106
+ instance.invoke_action :help, [command]
107
+ end # each
108
+ end # specify
109
+ end # describe
110
+ end # context
111
+ end # shared examples
@@ -0,0 +1,19 @@
1
+ # spec/mithril/controllers/mixins/help_actions_spec.rb
2
+
3
+ require 'spec_helper'
4
+ require 'mithril/controllers/mixins/help_actions_helper'
5
+
6
+ require 'mithril/controllers/mixins/help_actions'
7
+ require 'mithril/controllers/mixins/mixin_with_actions'
8
+
9
+ describe Mithril::Controllers::Mixins::HelpActions do
10
+ let :described_class do
11
+ klass = Class.new
12
+ klass.send :extend, Mithril::Controllers::Mixins::MixinWithActions
13
+ klass.send :mixin, super();
14
+ klass
15
+ end # let
16
+ let :instance do described_class.new; end
17
+
18
+ it_behaves_like Mithril::Controllers::Mixins::HelpActions
19
+ end # describe
@@ -0,0 +1,44 @@
1
+ # spec/mithril/controllers/mixins/action_mixin_spec.rb
2
+
3
+ require 'spec_helper'
4
+ require 'mithril/mixin_helper'
5
+
6
+ require 'mithril/controllers/mixins/mixin_with_actions'
7
+
8
+ describe Mithril::Controllers::Mixins::MixinWithActions do
9
+ let :described_class do
10
+ klass = Class.new.extend super()
11
+ klass.instance_eval do def actions; @actions; end; end
12
+ klass.send :mixin, ancestor_module
13
+ klass
14
+ end # let
15
+ let :instance do described_class.new; end
16
+
17
+ it_behaves_like Mithril::Mixin
18
+
19
+ let :ancestor_actions do
20
+ hsh = {}
21
+ 5.times do hsh[FactoryGirl.generate(:action_key)] = true; end
22
+ hsh
23
+ end # let
24
+ let :ancestor_module do
25
+ mod = Module.new
26
+ mod.send :extend, Mithril::Controllers::Mixins::MixinWithActions
27
+ mod.instance_eval do def actions; @actions; end; end
28
+ mod.instance_variable_set :@actions, ancestor_actions
29
+ mod
30
+ end # let
31
+
32
+ context "with a direct mixin" do
33
+ before :each do
34
+ described_class.send :mixin, ancestor_module
35
+ described_class.instance_eval do def actions; @actions; end; end
36
+ end # before each
37
+
38
+ specify "actions are inherited" do
39
+ ancestor_actions.each_key do |action|
40
+ expect(described_class.actions).to have_key action
41
+ end # each
42
+ end # specify
43
+ end # context
44
+ end # describe