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,111 @@
1
+ # spec/mithril/controllers/proxy_controller_helper.rb
2
+
3
+ require 'mithril/controllers/abstract_controller_helper'
4
+
5
+ require 'mithril/controllers/abstract_controller'
6
+ require 'mithril/controllers/proxy_controller'
7
+
8
+ shared_examples_for Mithril::Controllers::ProxyController do
9
+ it_behaves_like Mithril::Controllers::AbstractController
10
+
11
+ let :proxy do described_class; end
12
+ let :child do Class.new Mithril::Controllers::AbstractController; end
13
+ let :proxy_instance do proxy.new request; end
14
+ let :child_instance do child.new request; end
15
+ let :proxy_action do FactoryGirl.generate :action_key; end
16
+ let :child_action do FactoryGirl.generate :action_key; end
17
+ let :proxy_command do proxy_action.to_s.gsub('_', ' '); end
18
+ let :child_command do child_action.to_s.gsub('_', ' '); end
19
+
20
+ before :each do
21
+ proxy.define_action proxy_action do |session, arguments|; "proxy command"; end
22
+ child.define_action child_action do |session, arguments|; "child command"; end
23
+ end # before each
24
+
25
+ let :session do {}; end
26
+ let :arguments do []; end
27
+
28
+ specify { expect(proxy_instance).to have_action proxy_action }
29
+ specify { expect(child_instance).to have_action child_action }
30
+ specify { expect(proxy_instance).not_to have_action child_action }
31
+
32
+ describe :allow_own_actions_while_proxied? do
33
+ specify { expect(proxy_instance).to respond_to(:allow_own_actions_while_proxied?).
34
+ with(0).arguments }
35
+ end # describe
36
+
37
+ describe :proxy do
38
+ specify { expect(proxy_instance).to respond_to(:proxy).with(0).arguments }
39
+ specify { expect(proxy_instance.proxy).to be_a [Mithril::Controllers::AbstractController, nil] }
40
+ end # describe proxy
41
+
42
+ describe :commands do
43
+ specify { expect(proxy_instance.commands).to include proxy_command }
44
+ specify { expect(proxy_instance.commands).not_to include child_command }
45
+ end # describe
46
+
47
+ describe :has_command? do
48
+ specify { expect(proxy_instance).to have_command proxy_command }
49
+ specify { expect(proxy_instance).not_to have_command child_command }
50
+ end # describe
51
+
52
+ describe :can_invoke? do
53
+ specify { expect(proxy_instance.can_invoke? proxy_command).to be true }
54
+ specify { expect(proxy_instance.can_invoke? child_command).to be false }
55
+ end # describe
56
+
57
+ describe :can_invoke_on_self? do
58
+ specify { expect(proxy_instance).to respond_to(:can_invoke_on_self?).
59
+ with(1).arguments }
60
+ specify { expect(proxy_instance.can_invoke_on_self? proxy_command).to be true }
61
+ specify { expect(proxy_instance.can_invoke_on_self? child_command).to be false }
62
+ end # describe
63
+
64
+ describe :invoke_command do
65
+ specify { expect(proxy_instance.invoke_command proxy_command).to eq "proxy command" }
66
+ end # describe
67
+
68
+ context "with a proxy subject defined" do
69
+ before :each do proxy_instance.stub :proxy do child_instance; end; end
70
+
71
+ specify { expect(proxy_instance.proxy).to be child_instance }
72
+
73
+ specify { expect(proxy_instance.commands).to include child_command }
74
+
75
+ specify { expect(proxy_instance).to have_command child_command }
76
+
77
+ specify { expect(proxy_instance.can_invoke? child_command).to be true }
78
+
79
+ specify { expect(proxy_instance.can_invoke_on_self? child_command).to be false }
80
+
81
+ specify { expect(proxy_instance.invoke_command child_command).to eq "child command" }
82
+
83
+ context "allowing own actions" do
84
+ before :each do proxy_instance.stub :allow_own_actions_while_proxied? do true; end; end
85
+
86
+ specify { expect(proxy_instance.allow_own_actions_while_proxied?).to be true }
87
+
88
+ specify { expect(proxy_instance.commands).to include proxy_command }
89
+
90
+ specify { expect(proxy_instance).to have_command proxy_command }
91
+
92
+ specify { expect(proxy_instance.can_invoke? proxy_command).to be true }
93
+
94
+ specify { expect(proxy_instance.invoke_command proxy_command).to eq "proxy command" }
95
+ end # context
96
+
97
+ context "allowing own actions" do
98
+ before :each do proxy_instance.stub :allow_own_actions_while_proxied? do false; end; end
99
+
100
+ specify { expect(proxy_instance.allow_own_actions_while_proxied?).to be false }
101
+
102
+ specify { expect(proxy_instance.commands).not_to include proxy_command }
103
+
104
+ specify { expect(proxy_instance).not_to have_command proxy_command }
105
+
106
+ specify { expect(proxy_instance.can_invoke? proxy_command).to be false }
107
+
108
+ specify { expect(proxy_instance.invoke_command proxy_command).to match /don't know how/i }
109
+ end # context
110
+ end # context
111
+ end # shared examples
@@ -0,0 +1,14 @@
1
+ # spec/mithril/controllers/proxy_controller_spec.rb
2
+
3
+ require 'spec_helper'
4
+ require 'mithril/controllers/proxy_controller_helper'
5
+
6
+ require 'mithril/controllers/proxy_controller'
7
+
8
+ describe Mithril::Controllers::ProxyController do
9
+ let :request do FactoryGirl.build :request; end
10
+ let :described_class do Class.new super(); end
11
+ let :instance do described_class.new request; end
12
+
13
+ it_behaves_like Mithril::Controllers::ProxyController
14
+ end # describe
@@ -0,0 +1,54 @@
1
+ # spec/mithril/mixin_helper.rb
2
+
3
+ require 'mithril/mixin'
4
+
5
+ shared_examples_for Mithril::Mixin do
6
+ let :ancestor_instance_method do FactoryGirl.generate(:action_key); end
7
+ let :ancestor_class_method do FactoryGirl.generate(:action_key); end
8
+ let :ancestor_module do
9
+ mod = Module.new
10
+ mod.send :extend, Mithril::Mixin
11
+ mod.send :define_method, ancestor_instance_method do; end
12
+ mod.const_set :ClassMethods, Module.new
13
+ mod::ClassMethods.send :define_method, ancestor_class_method do; end
14
+ mod
15
+ end # let
16
+
17
+ let :parent_instance_method do FactoryGirl.generate(:action_key); end
18
+ let :parent_class_method do FactoryGirl.generate(:action_key); end
19
+ let :parent_module do
20
+ mod = Module.new
21
+ mod.send :extend, Mithril::Mixin
22
+ mod.send :mixin, ancestor_module
23
+ mod.send :define_method, parent_instance_method do; end
24
+ mod.const_set :ClassMethods, Module.new
25
+ mod::ClassMethods.send :define_method, parent_class_method do; end
26
+ mod
27
+ end # let
28
+
29
+ context "with a direct mixin" do
30
+ before :each do described_class.send :mixin, ancestor_module; end
31
+
32
+ describe "instance methods are mixed in" do
33
+ specify { expect(instance).to respond_to ancestor_instance_method }
34
+ end # describe
35
+
36
+ describe "class method are mixed in" do
37
+ specify { expect(described_class).to respond_to ancestor_class_method }
38
+ end # describe
39
+ end # context
40
+
41
+ context "with a cascading mixin" do
42
+ before :each do described_class.send :mixin, parent_module; end
43
+
44
+ describe "instance methods are mixed in" do
45
+ specify { expect(instance).to respond_to ancestor_instance_method }
46
+ specify { expect(instance).to respond_to parent_instance_method }
47
+ end # describe
48
+
49
+ describe "class method are mixed in" do
50
+ specify { expect(described_class).to respond_to ancestor_class_method }
51
+ specify { expect(described_class).to respond_to parent_class_method }
52
+ end # describe
53
+ end # context
54
+ end # shared examples
@@ -0,0 +1,17 @@
1
+ # spec/mithril/mixin_spec.rb
2
+
3
+ require 'spec_helper'
4
+ require 'mithril/mixin_helper'
5
+
6
+ require 'mithril/mixin'
7
+
8
+ describe Mithril::Mixin do
9
+ let :described_class do
10
+ klass = Class.new.extend super()
11
+ klass.send :mixin, ancestor_module
12
+ klass
13
+ end # let
14
+ let :instance do described_class.new; end
15
+
16
+ it_behaves_like Mithril::Mixin
17
+ end # describe
@@ -0,0 +1,85 @@
1
+ # spec/mithril/parsers/simple_parser_spec.rb
2
+
3
+ require 'spec_helper'
4
+
5
+ require 'mithril/controllers/mixins/actions_base'
6
+ require 'mithril/parsers/simple_parser'
7
+
8
+ describe Mithril::Parsers::SimpleParser do
9
+ let :actions_source do
10
+ Object.new.tap do |obj| obj.stub :has_action? do false; end; end
11
+ end # let
12
+ let :instance do described_class.new actions_source; end
13
+
14
+ describe :initialize do
15
+ specify { expect(described_class).to construct.with(1).arguments }
16
+ end # describe
17
+
18
+ describe :preprocess_input do
19
+ specify { expect(instance.respond_to? :preprocess_input, true).to be true }
20
+
21
+ specify "downcases input" do
22
+ clean, dirty = "lorem ipsum", "Lorem IPSuM"
23
+ expect(instance.send :preprocess_input, dirty).to eq clean
24
+ end # specify
25
+
26
+ specify "strips leading and trailing whitespace" do
27
+ clean, dirty = "lorem ipsum", "\n\tlorem ipsum \r\r"
28
+ expect(instance.send :preprocess_input, dirty).to eq clean
29
+ end # specify
30
+
31
+ specify "normalises internal whitespace" do
32
+ clean, dirty = "lorem ipsum dolor sit amet", "lorem ipsum \rdolor\n\tsit amet"
33
+ expect(instance.send :preprocess_input, dirty).to eq clean
34
+ end # specify
35
+
36
+ specify "converts puntuation to whitespace" do
37
+ clean, dirty = "lorem ipsum dolor sit amet", "lorem?-\"ipsum' :: (dolor![sit]), amet;"
38
+ expect(instance.send :preprocess_input, dirty).to eq clean
39
+ end # specify
40
+ end # describe
41
+
42
+ describe :wordify do
43
+ specify { expect(instance.respond_to? :wordify, true).to be true }
44
+
45
+ specify "splits input on whitespace" do
46
+ output = %w(second star to the right and straight on till morning)
47
+ expect(instance.send :wordify, output.join(" ")).to eq output
48
+ end # specify
49
+ end # describe
50
+
51
+ describe :parse_command do
52
+ specify { expect(instance).to respond_to(:parse_command).
53
+ with(1).arguments }
54
+
55
+ specify "preprocesses the input" do
56
+ instance.should_receive(:preprocess_input).with("lorem ipsum").and_call_original
57
+ instance.parse_command "lorem ipsum"
58
+ end # specify
59
+
60
+ context "with actions stubbed" do
61
+ before :each do
62
+ actions_source.stub :has_action? do |key|
63
+ [:do, :do_while, :do_not, :doo_wop].include? key
64
+ end # stub
65
+ end # before :each
66
+
67
+ specify "no matching command" do
68
+ command, arguments = instance.parse_command "Don't stop believing!"
69
+ expect(command).to be nil
70
+ end # specify
71
+
72
+ specify "matching a simple command" do
73
+ command, arguments = instance.parse_command "Do you hear the people sing?"
74
+ expect(command).to be :do
75
+ expect(arguments).to eq %w(you hear the people sing)
76
+ end # specify
77
+
78
+ specify "matching a complex command" do
79
+ command, arguments = instance.parse_command "Do while is a useful construct."
80
+ expect(command).to be :do_while
81
+ expect(arguments).to eq %w(is a useful construct)
82
+ end # specify
83
+ end # context
84
+ end # describe
85
+ end # describe
@@ -0,0 +1,72 @@
1
+ # spec/mithril/request_spec.rb
2
+
3
+ require 'spec_helper'
4
+
5
+ require 'mithril/request'
6
+
7
+ describe Mithril::Request do
8
+ let :described_class do super(); end
9
+ let :instance do described_class.new; end
10
+
11
+ describe :constructor do
12
+ it { expect(described_class).to construct.with(0..1).arguments }
13
+
14
+ context "with a session argument" do
15
+ let :hsh_value do { :foo => :bar }; end
16
+ let :instance do described_class.new hsh_value; end
17
+
18
+ specify { expect(instance.session).to be hsh_value }
19
+ end # context
20
+ end # describe
21
+
22
+ describe :session do
23
+ specify { expect(instance).to respond_to(:session).with(0).arguments }
24
+
25
+ specify { expect(instance.session).to be_a Hash }
26
+ end # describe session
27
+
28
+ describe :session= do
29
+ let :hsh_value do { :foo => :bar }; end
30
+
31
+ specify { expect(instance).to respond_to(:session=).with(1).arguments }
32
+
33
+ specify "changes value when set" do
34
+ instance.session = hsh_value
35
+ expect(instance.session).to be hsh_value
36
+ end # specify
37
+ end # describe session=
38
+
39
+ describe :input do
40
+ specify { expect(instance).to respond_to(:input).with(0).arguments }
41
+
42
+ specify { expect(instance.input).to be nil }
43
+ end # describe input
44
+
45
+ describe :input= do
46
+ let :str_value do "string"; end
47
+
48
+ specify { expect(instance).to respond_to(:input=).with(1).arguments }
49
+
50
+ specify "changes value when set" do
51
+ instance.input = str_value
52
+ expect(instance.input).to eq str_value
53
+ end # specify
54
+ end # describe
55
+
56
+ describe :output do
57
+ specify { expect(instance).to respond_to(:output).with(0).arguments }
58
+
59
+ specify { expect(instance.output).to be nil }
60
+ end # describe
61
+
62
+ describe :output= do
63
+ let :str_value do "string"; end
64
+
65
+ specify { expect(instance).to respond_to(:output=).with(1).arguments }
66
+
67
+ specify "changes value when set" do
68
+ instance.output = str_value
69
+ expect(instance.output).to eq str_value
70
+ end # specify
71
+ end # describe
72
+ end # describe
@@ -0,0 +1,25 @@
1
+ # spec/mithril_spec.rb
2
+
3
+ require 'spec_helper'
4
+
5
+ require 'mithril'
6
+
7
+ describe Mithril do
8
+ describe "self.logger" do
9
+ specify { expect(described_class).to respond_to(:logger).with(0).arguments }
10
+
11
+ specify "has a default value" do
12
+ expect(described_class.logger).to respond_to :log
13
+ end # specify
14
+ end # describe
15
+
16
+ describe "self.logger=" do
17
+ specify { expect(described_class).to respond_to(:logger=).with(1).arguments }
18
+
19
+ specify "changes value when set" do
20
+ logger = double("logger", :log => nil)
21
+ described_class.logger = logger
22
+ expect(described_class.logger).to be logger
23
+ end # specify
24
+ end # describe
25
+ end # describe
@@ -0,0 +1,15 @@
1
+ # spec/spec_helper.rb
2
+
3
+ require 'rspec'
4
+ require 'factory_girl'
5
+
6
+ RSpec.configure do |config|
7
+ config.color_enabled = true
8
+ end # config
9
+
10
+ #=# Require Factories, Custom Matchers, &c #=#
11
+ Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each { |f| require f }
12
+
13
+ module Mithril
14
+ module Mock; end
15
+ end # module Mithril
@@ -0,0 +1,7 @@
1
+ # spec/factories/action_factory.rb
2
+
3
+ require 'factory_girl'
4
+
5
+ FactoryGirl.define do
6
+ sequence :action_key do |index| :"action_#{index}"; end
7
+ end # define
@@ -0,0 +1,11 @@
1
+ # spec/support/factories/request_factory.rb
2
+
3
+ require 'factory_girl'
4
+
5
+ require 'mithril/request'
6
+
7
+ FactoryGirl.define do
8
+ factory :request, class: Mithril::Request do
9
+ session { Hash.new }
10
+ end # factory
11
+ end # define
@@ -0,0 +1,23 @@
1
+ # spec/support/matchers/be_kind_of.rb
2
+
3
+ require 'rspec'
4
+
5
+ module RSpec::Matchers::BuiltIn
6
+ class BeAKindOf < BaseMatcher
7
+ def match(expected, actual)
8
+ @actual = actual
9
+ self.match_type? expected
10
+ end # method match
11
+
12
+ def match_type?(expected)
13
+ case
14
+ when expected.nil?
15
+ @actual.nil?
16
+ when expected.respond_to?(:each)
17
+ expected.reduce(false) { |memo, obj| memo || match_type?(obj) }
18
+ else
19
+ @actual.kind_of? expected
20
+ end # case
21
+ end # method match_type
22
+ end # class
23
+ end # module