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.
- data/CHANGELOG.md +31 -0
- data/README.md +0 -0
- data/bin/mithril +5 -0
- data/lib/mithril.rb +13 -0
- data/lib/mithril/controllers.rb +7 -0
- data/lib/mithril/controllers/abstract_controller.rb +130 -0
- data/lib/mithril/controllers/mixins.rb +7 -0
- data/lib/mithril/controllers/mixins/actions_base.rb +114 -0
- data/lib/mithril/controllers/mixins/help_actions.rb +46 -0
- data/lib/mithril/controllers/mixins/mixin_with_actions.rb +27 -0
- data/lib/mithril/controllers/proxy_controller.rb +89 -0
- data/lib/mithril/mixin.rb +33 -0
- data/lib/mithril/parsers.rb +7 -0
- data/lib/mithril/parsers/simple_parser.rb +57 -0
- data/lib/mithril/request.rb +11 -0
- data/lib/mithril/version.rb +5 -0
- data/spec/matchers/be_kind_of_spec.rb +50 -0
- data/spec/matchers/construct_spec.rb +49 -0
- data/spec/matchers/respond_to_spec.rb +158 -0
- data/spec/mithril/controllers/_text_controller_helper.rb +81 -0
- data/spec/mithril/controllers/abstract_controller_helper.rb +118 -0
- data/spec/mithril/controllers/abstract_controller_spec.rb +15 -0
- data/spec/mithril/controllers/mixins/actions_base_helper.rb +121 -0
- data/spec/mithril/controllers/mixins/actions_base_spec.rb +18 -0
- data/spec/mithril/controllers/mixins/help_actions_helper.rb +111 -0
- data/spec/mithril/controllers/mixins/help_actions_spec.rb +19 -0
- data/spec/mithril/controllers/mixins/mixin_with_actions_spec.rb +44 -0
- data/spec/mithril/controllers/proxy_controller_helper.rb +111 -0
- data/spec/mithril/controllers/proxy_controller_spec.rb +14 -0
- data/spec/mithril/mixin_helper.rb +54 -0
- data/spec/mithril/mixin_spec.rb +17 -0
- data/spec/mithril/parsers/simple_parser_spec.rb +85 -0
- data/spec/mithril/request_spec.rb +72 -0
- data/spec/mithril_spec.rb +25 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/support/factories/action_factory.rb +7 -0
- data/spec/support/factories/request_factory.rb +11 -0
- data/spec/support/matchers/be_kind_of.rb +23 -0
- data/spec/support/matchers/construct.rb +49 -0
- data/spec/support/matchers/respond_to.rb +52 -0
- 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
|
data/spec/spec_helper.rb
ADDED
@@ -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,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
|