aye_commander 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,25 @@
1
+ describe AyeCommander::MissingRequiredArgumentError do
2
+ let(:error) { AyeCommander::MissingRequiredArgumentError }
3
+
4
+ it 'is an AyeCommander::Error child' do
5
+ expect(error.superclass).to be AyeCommander::Error
6
+ end
7
+
8
+ it 'should have a descriptive message of the error' do
9
+ errori = error.new [:taco]
10
+ expect(errori.message).to eq 'Missing required arguments: [:taco]'
11
+ end
12
+ end
13
+
14
+ describe AyeCommander::UnexpectedReceivedArgumentError do
15
+ let(:error) { AyeCommander::UnexpectedReceivedArgumentError }
16
+
17
+ it 'is an AyeCommander::Error child' do
18
+ expect(error.superclass).to be AyeCommander::Error
19
+ end
20
+
21
+ it 'should have a descriptive message of the error' do
22
+ errori = error.new [:taco]
23
+ expect(errori.message).to eq 'Received unexpected arguments: [:taco]'
24
+ end
25
+ end
@@ -0,0 +1,105 @@
1
+ describe AyeCommander::Hookable::ClassMethods do
2
+ include_context :command
3
+
4
+ %i(before around after aborted).each do |kind|
5
+ context ".#{kind}" do
6
+ it "adds the args to the #{kind} hooks array" do
7
+ command.send kind, :some, :method
8
+ expect(command.send("#{kind}_hooks")).to eq [:some, :method]
9
+ expect(command.instance_variable_get(:@hooks)).to_not be_empty
10
+ expect(command.instance_variable_get(:@hooks).default).to be_empty
11
+ end
12
+
13
+ it 'adds the received block as a block, after the args' do
14
+ command.send(kind, :some) { :hello }
15
+ expect(command.send("#{kind}_hooks").count).to eq 2
16
+ expect(command.send("#{kind}_hooks").last).to be_instance_of Proc
17
+ end
18
+
19
+ it 'adds the args at the end of the array' do
20
+ command.send kind, :first
21
+ command.send kind, :second, :third
22
+ expect(command.send("#{kind}_hooks")).to eq [:first, :second, :third]
23
+ end
24
+
25
+ it 'adds the args at the beginning of the array with the prepend option' do
26
+ command.send kind, :first
27
+ command.send kind, :second, :third, prepend: true
28
+ expect(command.send("#{kind}_hooks")).to eq [:second, :third, :first]
29
+ end
30
+ end
31
+
32
+ context ".#{kind}_hooks" do
33
+ it 'returns empty array with nothing set' do
34
+ expect(command.send("#{kind}_hooks")).to eq []
35
+ end
36
+
37
+ it 'returns the array of hooks' do
38
+ command.instance_variable_set :@hooks, kind => [:hello]
39
+ expect(command.send("#{kind}_hooks")).to eq [:hello]
40
+ end
41
+ end
42
+ end
43
+
44
+ %i(before after aborted).each do |kind|
45
+ context ".call_#{kind}_hooks" do
46
+ before :each do
47
+ body = -> { success? }
48
+ command.send :define_method, :by_symbol, &body
49
+ command.send :define_method, :by_method, &body
50
+ command.send kind, :by_symbol, instance.method(:by_method), body, &body
51
+ end
52
+
53
+ it 'makes all supported hooks callable' do
54
+ expect(command.send("call_#{kind}_hooks", instance)).to all(respond_to :call)
55
+ end
56
+
57
+ it 'calls all the prepared hooks' do
58
+ hooks = command.send "call_#{kind}_hooks", instance
59
+ allow(command).to receive(:prepare_hooks).and_return(hooks)
60
+ expect(hooks).to all(receive(:call))
61
+ command.send "call_#{kind}_hooks", instance
62
+ end
63
+
64
+ it 'runs all the prepared hooks in the instance context' do
65
+ expect(instance).to receive(:success?).exactly(4).times
66
+ command.send "call_#{kind}_hooks", instance
67
+ end
68
+ end
69
+ end
70
+
71
+ context '.call_around_hooks' do
72
+ before :each do
73
+ body = lambda do |step|
74
+ @order ||= []
75
+ number = order.count + 1
76
+ @order << number
77
+
78
+ success?
79
+ step.call
80
+ failure?
81
+
82
+ @order << number
83
+ end
84
+
85
+ command.send :define_method, :by_symbol, &body
86
+ command.send :define_method, :by_method, &body
87
+ command.around :by_symbol, instance.method(:by_method), body, &body
88
+ end
89
+
90
+ it 'compacts everything into one proc' do
91
+ expect(command.call_around_hooks(instance).count).to eq 1
92
+ end
93
+
94
+ it 'calls everything' do
95
+ expect(instance).to receive(:success?).exactly(4).times
96
+ expect(instance).to receive(:failure?).exactly(4).times
97
+ command.call_around_hooks(instance)
98
+ end
99
+
100
+ it 'should call the hooks in the correct order' do
101
+ command.call_around_hooks(instance)
102
+ expect(instance.order).to eq [1, 2, 3, 4, 4, 3, 2, 1]
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,33 @@
1
+ describe AyeCommander::Initializable do
2
+ include_context :command
3
+
4
+ context '#initialize' do
5
+ it 'sets the instance variables with the received arguments' do
6
+ i = command.new(taco: :burrito, dogo: :hungry)
7
+ expect(i.taco).to eq :burrito
8
+ expect(i.dogo).to eq :hungry
9
+ end
10
+
11
+ it 'is able to handle the case when the variable start with @' do
12
+ i = command.new(:@taco => :burrito, :@dogo => :hungry)
13
+ expect(i.taco).to eq :burrito
14
+ expect(i.dogo).to eq :hungry
15
+ end
16
+
17
+ it 'is able to handle the case when no args are received' do
18
+ expect { command.new }.to_not raise_error
19
+ end
20
+
21
+ context 'when a command' do
22
+ it 'sets the status to :success if no other succeed has been set' do
23
+ command.succeeds_with :potato
24
+ expect(instance.status).to eq :success
25
+ end
26
+
27
+ it 'sets the status to the first suceed if success has been excluded' do
28
+ command.succeeds_with :potato, exclude_success: true
29
+ expect(instance.status).to eq :potato
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,45 @@
1
+ describe AyeCommander::Inspectable do
2
+ include_context :command
3
+
4
+ before :each do
5
+ instance.instance_variable_set :@variable, :something
6
+ instance.instance_variable_set :@other, :potato
7
+ end
8
+
9
+ context '#inspect' do
10
+ it 'gives a string representation of the innards of the class' do
11
+ expect(instance.inspect).to match(/#<#<Class:\dx\w+> @status: success, @variable: something, @other: potato>/)
12
+ end
13
+ end
14
+
15
+ context '#to_hash' do
16
+ it 'gives a hash representation of the innards of the class' do
17
+ result = { :@status => :success, :@variable => :something, :@other => :potato }
18
+ expect(instance.to_hash).to eq result
19
+ end
20
+
21
+ it 'gives a hash representation of the innards of the class with the requested values' do
22
+ result = { :@variable => :something, :@other => :potato }
23
+ expect(instance.to_hash([:@variable, :other])).to eq result
24
+ end
25
+ end
26
+
27
+ context '#to_result_hash' do
28
+ it 'gives a hash of all values for the result if no return was specified' do
29
+ result = { :@status => :success, :@variable => :something, :@other => :potato }
30
+ expect(instance.to_result_hash).to eq result
31
+ end
32
+
33
+ it 'gives the necessary values for the result when a return was specified' do
34
+ command.returns :other
35
+ result = { :@status => :success, :@other => :potato }
36
+ expect(instance.to_result_hash).to eq result
37
+ end
38
+
39
+ it 'assigns nil to the values that were not created when a result was specified' do
40
+ command.returns :badger
41
+ result = { :@status => :success, :@badger => nil }
42
+ expect(instance.to_result_hash).to eq result
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,130 @@
1
+ describe AyeCommander::Ivar::ClassMethods do
2
+ include_context :command
3
+
4
+ context '.define_missing_reader' do
5
+ it 'calls uses if its a command' do
6
+ expect(command).to receive(:uses).with(:taco)
7
+ command.define_missing_reader(:taco)
8
+ end
9
+
10
+ it 'defines the attr_reader if its a result' do
11
+ command.result_class.define_missing_reader(:taco)
12
+ expect(result).to respond_to :taco
13
+ expect(result).to_not respond_to :taco=
14
+ end
15
+ end
16
+
17
+ context '.to_ivar' do
18
+ it 'returns itself when the name is already in ivar form' do
19
+ expect(command.to_ivar(:@var)).to eq :@var
20
+ end
21
+
22
+ it 'returns the ivar form when name is not in ivar form' do
23
+ expect(command.to_ivar(:var)).to eq :@var
24
+ end
25
+
26
+ it 'is able to handle strings' do
27
+ expect(command.to_ivar('@var')).to eq :@var
28
+ expect(command.to_ivar('var')).to eq :@var
29
+ end
30
+ end
31
+
32
+ context '.to_nvar' do
33
+ it 'returns itself when name is already in nvar form' do
34
+ expect(command.to_nvar(:var)).to eq :var
35
+ end
36
+
37
+ it 'returns the nvar form when name is not in nvar form' do
38
+ expect(command.to_nvar(:@var)).to eq :var
39
+ end
40
+
41
+ it 'is able to handle strings' do
42
+ expect(command.to_nvar('@var')).to eq :var
43
+ expect(command.to_nvar('var')).to eq :var
44
+ end
45
+ end
46
+ end
47
+
48
+ describe AyeCommander::Ivar::Readable do
49
+ include_context :command
50
+
51
+ context '#method_missing' do
52
+ it 'raises if asked a method without an instance variable defined' do
53
+ expect { instance.taco }.to raise_error NoMethodError
54
+ end
55
+
56
+ it 'responds if asked the name of an instance variable' do
57
+ instance.instance_variable_set :@taco, :badger
58
+ expect(instance.taco).to eq :badger
59
+ end
60
+
61
+ it 'calls .define_missing_reader' do
62
+ expect(command).to receive(:define_missing_reader).with(:taco)
63
+ instance.instance_variable_set :@taco, :badger
64
+ instance.taco
65
+ end
66
+ end
67
+
68
+ context '#remove!' do
69
+ it 'removes an instance variable' do
70
+ instance.remove!(:status)
71
+ expect(instance.instance_variables).to be_empty
72
+ end
73
+ end
74
+
75
+ context '#to_ivar' do
76
+ it 'calls the .to_ivar' do
77
+ instance
78
+ expect(command).to receive(:to_ivar).with(:var)
79
+ instance.to_ivar(:var)
80
+ end
81
+ end
82
+
83
+ context '#to_nvar' do
84
+ it 'calls the .to_nvar' do
85
+ expect(command).to receive(:to_nvar).with(:var)
86
+ instance.to_nvar(:var)
87
+ end
88
+ end
89
+
90
+ context 'p#respond_to_missing?' do
91
+ it 'returns true if the variable name is defined' do
92
+ instance.instance_variable_set :@taco, :badger
93
+ expect(instance.send(:respond_to_missing?, :taco, [false])).to be true
94
+ end
95
+
96
+ it 'uses super if the variable name is not defined' do
97
+ expect(instance.send(:respond_to_missing?, :taco, [false])).to be false
98
+ end
99
+
100
+ it 'uses super if the variable name is not valid' do
101
+ expect(instance.send(:respond_to_missing?, :taco!, [false])).to be false
102
+ end
103
+ end
104
+ end
105
+
106
+ describe AyeCommander::Ivar::Writeable do
107
+ include_context :command
108
+
109
+ context '#method_missing' do
110
+ it 'responds to equality assignments' do
111
+ expect { instance.taco = 1 }.to_not raise_error
112
+ end
113
+
114
+ it 'defines the method so next time it doesnt go through method_missing' do
115
+ instance.taco = 1
116
+ expect(instance).to respond_to :taco
117
+ expect(instance).to respond_to :taco=
118
+ end
119
+ end
120
+
121
+ context 'p#respond_to_missing?' do
122
+ it 'returns true if variable name ends with =' do
123
+ expect(instance.send(:respond_to_missing?, :taco=, [false])).to be true
124
+ end
125
+
126
+ it 'uses super otherwise' do
127
+ expect(instance.send(:respond_to_missing?, :taco, [false])).to be false
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,131 @@
1
+ describe AyeCommander::Limitable::ClassMethods do
2
+ include_context :command
3
+ let(:args) { %i(arg1 arg2) }
4
+
5
+ context '.uses' do
6
+ it 'should call save_variable' do
7
+ command.uses(*args)
8
+ expect(command.uses).to eq args
9
+ end
10
+
11
+ it 'should create accessors for the received values' do
12
+ command.uses(*args)
13
+ args.each do |arg|
14
+ expect(instance).to respond_to arg
15
+ expect(instance).to respond_to "#{arg}="
16
+ end
17
+ end
18
+ end
19
+
20
+ %i(receives requires returns).each do |limiter|
21
+ context ".#{limiter}" do
22
+ before :each do
23
+ command.public_send limiter, *args
24
+ end
25
+
26
+ it 'should call .uses' do
27
+ expect(command).to receive(:uses).with(*args).and_return(true)
28
+ command.public_send limiter, *args
29
+ end
30
+
31
+ it 'should save the values to a class instance variable' do
32
+ expect(command.limiters[limiter]).to eq args
33
+ end
34
+
35
+ it 'should add consecutive values without any problem' do
36
+ command.public_send limiter, :arg3
37
+ expect(command.limiters[limiter]).to eq %i(arg1 arg2 arg3)
38
+ end
39
+
40
+ it 'should not add repeated args' do
41
+ command.public_send limiter, :arg1, :arg4
42
+ expect(command.limiters[limiter]).to eq %i(arg1 arg2 arg4)
43
+ end
44
+ end
45
+ end
46
+
47
+ context '.validate_arguments' do
48
+ let(:args) { { hello: :world, how: :are, you: :! } }
49
+
50
+ it 'calls .validate_required_arguments if it has requires' do
51
+ expect(command).to receive(:validate_required_arguments).and_return(true)
52
+ command.requires :something
53
+ command.validate_arguments args
54
+ end
55
+
56
+ it 'does not call .validate_required_arguments if theres no requires' do
57
+ expect(command).to_not receive(:validate_required_arguments)
58
+ command.validate_arguments args
59
+ end
60
+
61
+ it 'does not call .validate_required_arguments with skip_validations: :requires option' do
62
+ command.requires :something
63
+ expect(command).to_not receive(:validate_required_arguments)
64
+ command.validate_arguments args, skip_validations: :requires
65
+ end
66
+
67
+ it 'calls .validate_received_arguments if it has receives' do
68
+ expect(command).to receive(:validate_received_arguments).and_return(true)
69
+ command.receives :something
70
+ command.validate_arguments args
71
+ end
72
+
73
+ it 'does not call .validate_received_argumnts if theres no receives' do
74
+ expect(command).to_not receive(:validate_received_arguments)
75
+ command.validate_arguments args
76
+ end
77
+
78
+ it 'does not call .validate_receiveed_arguments with skip_validations: :receives option' do
79
+ command.receives :something
80
+ expect(command).to_not receive(:validate_received_arguments)
81
+ command.validate_arguments args, skip_validations: :receives
82
+ end
83
+
84
+ it 'does not call either with skip_validations: true option' do
85
+ command.requires :something
86
+ command.receives :something_else
87
+ expect(command).to_not receive(:validate_received_arguments)
88
+ expect(command).to_not receive(:validate_required_arguments)
89
+
90
+ command.validate_arguments args, skip_validations: true
91
+ end
92
+ end
93
+
94
+ context '.validate_required_arguments' do
95
+ let(:args) { { hello: :world, how: :are, you: :! } }
96
+
97
+ it 'does nothing if the required arguments are contained in the received ones' do
98
+ command.requires :hello, :you
99
+ expect { command.validate_required_arguments args }.to_not raise_error
100
+ end
101
+
102
+ it 'does nothing if it receives extra arguments' do
103
+ command.requires :hello, :you
104
+ expect { command.validate_required_arguments(**args, extra: :arg) }.to_not raise_error
105
+ end
106
+
107
+ it 'raises an error when the required arguments are not fully contained in the received ones' do
108
+ command.requires :hello, :you, :doc
109
+ expect { command.validate_required_arguments args }.to raise_error AyeCommander::MissingRequiredArgumentError
110
+ end
111
+ end
112
+
113
+ context '.validate_received_arguments' do
114
+ let(:args) { { hello: :world, how: :are, you: :! } }
115
+
116
+ it 'does nothing if receives contains all the received arguments' do
117
+ command.receives :hello, :how, :you
118
+ expect { command.validate_received_arguments args }.to_not raise_error
119
+ end
120
+
121
+ it 'does nothing if some of the arguments are missing' do
122
+ command.receives :hello, :how, :you, :potato
123
+ expect { command.validate_received_arguments args }.to_not raise_error
124
+ end
125
+
126
+ it 'raises an error when it receives arguments not contained in the receives array' do
127
+ command.receives :hello, :how, :potato
128
+ expect { command.validate_received_arguments args }.to raise_error AyeCommander::UnexpectedReceivedArgumentError
129
+ end
130
+ end
131
+ end