vmsim 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +27 -0
- data/README.txt +1 -0
- data/Rakefile +40 -0
- data/VERSION +1 -0
- data/bin/vmdeploy +23 -0
- data/bin/vmsim +37 -0
- data/doc/actuators_and_sensors.txt +32 -0
- data/doc/handout.odt +0 -0
- data/doc/machine.jpg +0 -0
- data/doc/todo.txt +25 -0
- data/lib/adapter/actuator_collection.rb +61 -0
- data/lib/adapter/sensor_collection.rb +57 -0
- data/lib/archive_builder.rb +64 -0
- data/lib/control/main.rb +21 -0
- data/lib/control.rb +3 -0
- data/lib/deploy/deployer.rb +96 -0
- data/lib/deploy.rb +1 -0
- data/lib/devices/devices.rb +73 -0
- data/lib/devices.rb +1 -0
- data/lib/gui/SimulatorGui.gtk +289 -0
- data/lib/gui/simulator_gtk.rb +57 -0
- data/lib/gui/simulator_gui.rb +64 -0
- data/lib/gui.rb +2 -0
- data/lib/hardware/bin.rb +28 -0
- data/lib/hardware/button.rb +18 -0
- data/lib/hardware/can.rb +9 -0
- data/lib/hardware/cash_register.rb +79 -0
- data/lib/hardware/component.rb +56 -0
- data/lib/hardware/display.rb +29 -0
- data/lib/hardware/drawer.rb +45 -0
- data/lib/hardware/enum.rb +20 -0
- data/lib/hardware/simulator.rb +98 -0
- data/lib/hardware.rb +10 -0
- data/lib/hardware_adapter.rb +11 -0
- data/lib/vmlog.rb +5 -0
- data/test/adapter/actuator_collection_test.rb +106 -0
- data/test/adapter/sensor_collection_test.rb +51 -0
- data/test/deploy/deployer_test.rb +114 -0
- data/test/deploy/was_run.sh +5 -0
- data/test/devices/devices_test.rb +78 -0
- data/test/hardware/bin_test.rb +57 -0
- data/test/hardware/button_test.rb +23 -0
- data/test/hardware/can_test.rb +11 -0
- data/test/hardware/cash_register_test.rb +157 -0
- data/test/hardware/component_test.rb +37 -0
- data/test/hardware/display_test.rb +94 -0
- data/test/hardware/drawer_test.rb +100 -0
- data/test/hardware/enum_test.rb +33 -0
- data/test/hardware/simulator_test.rb +189 -0
- data/test/test_helper.rb +5 -0
- data/vmsim.gemspec +89 -0
- metadata +131 -0
@@ -0,0 +1,157 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'..','test_helper')
|
2
|
+
require 'mocha'
|
3
|
+
require 'hardware'
|
4
|
+
require 'hardware_adapter'
|
5
|
+
|
6
|
+
module Hardware
|
7
|
+
RIGHT_AWAY = 0
|
8
|
+
class CashRegisterDroppingCoinsInBin < Test::Unit::TestCase
|
9
|
+
attr_reader :register, :bin
|
10
|
+
def setup
|
11
|
+
@bin = mock('bin')
|
12
|
+
@register = CashRegister.new(bin, Adapter::SensorCollection.null, nil)
|
13
|
+
register.fill(Coin.two_euro, 1, RIGHT_AWAY)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_drops_coin_in_bin
|
17
|
+
bin.expects(:receive).with(Coin.two_euro)
|
18
|
+
register.drop_coin(Coin.two_euro, RIGHT_AWAY)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_drops_nohting_when_empty
|
22
|
+
bin.expects(:receive).with(Coin.two_euro).never
|
23
|
+
register.drop_coin(Coin.one_euro, RIGHT_AWAY)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_drops_eventually_empties_the_coin_stock
|
27
|
+
bin.expects(:receive).with(Coin.two_euro).once
|
28
|
+
register.drop_coin(Coin.two_euro, RIGHT_AWAY)
|
29
|
+
register.drop_coin(Coin.two_euro, RIGHT_AWAY)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_filling_coins_adds_to_stock
|
33
|
+
register.fill(Coin.two_euro, 1, 0)
|
34
|
+
bin.expects(:receive).with(Coin.two_euro).twice
|
35
|
+
register.drop_coin(Coin.two_euro, RIGHT_AWAY)
|
36
|
+
register.drop_coin(Coin.two_euro, RIGHT_AWAY)
|
37
|
+
register.drop_coin(Coin.two_euro, RIGHT_AWAY)
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_insert_coin_adds_it_to_stock
|
41
|
+
register.insert_coin(Coin.two_euro)
|
42
|
+
bin.expects(:receive).with(Coin.two_euro).twice
|
43
|
+
register.drop_coin(Coin.two_euro, RIGHT_AWAY)
|
44
|
+
register.drop_coin(Coin.two_euro, RIGHT_AWAY)
|
45
|
+
register.drop_coin(Coin.two_euro, RIGHT_AWAY)
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
class CashRegisterSensorFiringTest < Test::Unit::TestCase
|
51
|
+
attr_reader :register, :bin, :sensor_collection
|
52
|
+
|
53
|
+
def setup
|
54
|
+
@bin = stub('bin', :receive)
|
55
|
+
@sensor_collection = mock('sensor_collection')
|
56
|
+
@register = CashRegister.new(bin, sensor_collection, nil)
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_insert_two_euros_fires_cash_insert_200
|
60
|
+
sensor_collection.expects(:fire).with(:cash_insert_200)
|
61
|
+
register.insert_coin(Coin.two_euro)
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_insert_one_euro_fires_cash_insert_100
|
65
|
+
sensor_collection.expects(:fire).with(:cash_insert_100)
|
66
|
+
register.insert_coin(Coin.one_euro)
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_insert_fifty_cents_fires_cash_insert_50
|
70
|
+
sensor_collection.expects(:fire).with(:cash_insert_50)
|
71
|
+
register.insert_coin(Coin.fifty_cents)
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_filling_two_euros_fires_cash_fills_200
|
75
|
+
sensor_collection.expects(:fire).with(:cash_fill_200).twice
|
76
|
+
register.fill(Coin.two_euro, 2, RIGHT_AWAY)
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_filling_one_euro_fires_cash_fills_100
|
80
|
+
sensor_collection.expects(:fire).with(:cash_fill_100).once
|
81
|
+
register.fill(Coin.one_euro, 1, RIGHT_AWAY)
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_filling_fifty_cents_fires_cash_fills_50
|
85
|
+
sensor_collection.expects(:fire).with(:cash_fill_50).twice
|
86
|
+
register.fill(Coin.fifty_cents, 2, RIGHT_AWAY)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
class CashRegisterConfigureTest < Test::Unit::TestCase
|
91
|
+
attr_reader :sensor_collection, :actuator_collection, :register
|
92
|
+
def setup
|
93
|
+
@sensor_collection = mock('sensor_collection')
|
94
|
+
@actuator_collection = mock('actuator_collection')
|
95
|
+
@register = CashRegister.new(nil, sensor_collection, actuator_collection)
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_configures_sensors_for_coins_insertions_and_actuators_for_coin_drops
|
99
|
+
sensor_collection.expects(:create_sensor_for).with(:cash_insert_200)
|
100
|
+
sensor_collection.expects(:create_sensor_for).with(:cash_insert_100)
|
101
|
+
sensor_collection.expects(:create_sensor_for).with(:cash_insert_50)
|
102
|
+
sensor_collection.expects(:create_sensor_for).with(:cash_fill_200)
|
103
|
+
sensor_collection.expects(:create_sensor_for).with(:cash_fill_100)
|
104
|
+
sensor_collection.expects(:create_sensor_for).with(:cash_fill_50)
|
105
|
+
actuator_collection.expects(:create_actuator_for).with(:cash_drop_200)
|
106
|
+
actuator_collection.expects(:create_actuator_for).with(:cash_drop_100)
|
107
|
+
actuator_collection.expects(:create_actuator_for).with(:cash_drop_50)
|
108
|
+
|
109
|
+
register.configure()
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
class MyCashRegister < CashRegister
|
115
|
+
def drop_coin(coin)
|
116
|
+
@coin = coin
|
117
|
+
end
|
118
|
+
def coin_dropped?(coin)
|
119
|
+
@coin == coin
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
class CashRegisterRespondingToActuatorsTest < Test::Unit::TestCase
|
124
|
+
attr_reader :sensor_collection, :actuator_collection, :register
|
125
|
+
def setup
|
126
|
+
@sensor_collection = mock('sensor_collection')
|
127
|
+
@actuator_collection = mock('actuator_collection')
|
128
|
+
@register = MyCashRegister.new(nil, sensor_collection, actuator_collection)
|
129
|
+
sensor_collection.stubs(:create_sensor_for)
|
130
|
+
actuator_collection.stubs(:create_actuator_for)
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_actuating_drop_200_drops_two_euro_coin_in_bin
|
134
|
+
actuator_collection.stubs(:create_actuator_for).with(:cash_drop_200).yields
|
135
|
+
|
136
|
+
register.configure()
|
137
|
+
|
138
|
+
assert register.coin_dropped?(Coin.two_euro), "two euro should be dropped"
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_actuating_drop_100_drops_one_euro_coin_in_bin
|
142
|
+
actuator_collection.stubs(:create_actuator_for).with(:cash_drop_100).yields
|
143
|
+
|
144
|
+
register.configure()
|
145
|
+
|
146
|
+
assert register.coin_dropped?(Coin.one_euro), "one euro should be dropped"
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_actuating_drop_50_drops_fifty_cents_coin_in_bin
|
150
|
+
actuator_collection.stubs(:create_actuator_for).with(:cash_drop_50).yields
|
151
|
+
|
152
|
+
register.configure()
|
153
|
+
|
154
|
+
assert register.coin_dropped?(Coin.fifty_cents), "fifty cents should be dropped"
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'..','test_helper')
|
2
|
+
require 'hardware'
|
3
|
+
|
4
|
+
module Hardware
|
5
|
+
class MyComponent < Component
|
6
|
+
def changed # published protected method
|
7
|
+
super
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class ComponentMonitorChangesTest < Test::Unit::TestCase
|
12
|
+
attr_reader :component, :changed_block_called
|
13
|
+
def setup
|
14
|
+
@component = MyComponent.new(nil,nil)
|
15
|
+
@changed_block_called = 'changed_block_not_called'
|
16
|
+
component.monitor_changes do
|
17
|
+
@changed_block_called = 'changed_block_called'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_changes_block_initially_not_called
|
22
|
+
assert_equal 'changed_block_not_called', changed_block_called
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_changes_block_initially_called_when_changed
|
26
|
+
component.changed
|
27
|
+
assert_equal 'changed_block_called', changed_block_called
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_changed_ignored_when_block_not_registered
|
31
|
+
@component = MyComponent.new(nil,nil)
|
32
|
+
component.changed
|
33
|
+
assert_equal 'changed_block_not_called', changed_block_called
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'..','test_helper')
|
2
|
+
require 'mocha'
|
3
|
+
require 'hardware'
|
4
|
+
require 'hardware_adapter'
|
5
|
+
|
6
|
+
module Hardware
|
7
|
+
class DisplayTest < Test::Unit::TestCase
|
8
|
+
attr_reader :display
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@display = Display.new(Adapter::ActuatorCollection.null)
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_can_display_text_on_first_line
|
15
|
+
display.show(0, "line 1")
|
16
|
+
assert_equal "line 1", display.line_one
|
17
|
+
assert_equal "", display.line_two
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_can_display_text_on_second_line
|
21
|
+
display.show(1, "line 2")
|
22
|
+
assert_equal "", display.line_one
|
23
|
+
assert_equal "line 2", display.line_two
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_displaying_on_higher_line_is_ignored
|
27
|
+
display.show(3, "blah")
|
28
|
+
assert_equal "", display.line_one
|
29
|
+
assert_equal "", display.line_two
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_displaying_on_negative_line_is_ignored
|
33
|
+
display.show(-1, "blah")
|
34
|
+
assert_equal "", display.line_one
|
35
|
+
assert_equal "", display.line_two
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_displaying_with_string_as_index_is_ignored
|
39
|
+
display.show("0", "blah")
|
40
|
+
assert_equal "", display.line_one
|
41
|
+
assert_equal "", display.line_two
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_line_will_be_limited_to_16
|
45
|
+
display.show(0, "much longer than sixteen chars")
|
46
|
+
assert_equal "much longer than", display.line_one
|
47
|
+
display.show(1, "much longer than sixteen chars")
|
48
|
+
assert_equal "much longer than", display.line_two
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
def test_display_updates_ui_when_show_is_called
|
53
|
+
ui_contains = 'nothing'
|
54
|
+
display.monitor_changes do
|
55
|
+
ui_contains = [display.line_one, display.line_two].join('-')
|
56
|
+
end
|
57
|
+
display.show(1, 'blah')
|
58
|
+
assert_equal '-blah', ui_contains
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_display_updates_ui_when_nothing_shown
|
62
|
+
ui_contains = 'nothing'
|
63
|
+
display.monitor_changes do
|
64
|
+
ui_contains = [display.line_one, display.line_two].join('-')
|
65
|
+
end
|
66
|
+
display.show(-1, 'blah') # error - nothing shown
|
67
|
+
assert_equal 'nothing', ui_contains
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class DisplayConfigureTest < Test::Unit::TestCase
|
72
|
+
attr_reader :display, :actuator_collection
|
73
|
+
|
74
|
+
def setup
|
75
|
+
@actuator_collection = mock('actuator_collection')
|
76
|
+
@display = Display.new(actuator_collection)
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_configure_configures_actuator_for_display
|
80
|
+
actuator_collection.expects(:create_actuator_for).with(:display_show)
|
81
|
+
display.configure
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_firing_actuator_will_call_show
|
85
|
+
actuator_collection.expects(:create_actuator_for).
|
86
|
+
with(:display_show).
|
87
|
+
yields(0, 'line one')
|
88
|
+
|
89
|
+
display.configure
|
90
|
+
assert_equal "line one", display.line_one
|
91
|
+
assert_equal "", display.line_two
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require File.expand_path File.join(File.dirname(__FILE__),'..','test_helper')
|
2
|
+
require 'mocha'
|
3
|
+
require 'hardware'
|
4
|
+
|
5
|
+
module Hardware
|
6
|
+
RIGHT_AWAY = 0
|
7
|
+
class DrawerDroppingTest < Test::Unit::TestCase
|
8
|
+
attr_reader :drawer, :bin
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@bin = mock('bin')
|
12
|
+
@drawer = Drawer.new(bin)
|
13
|
+
@drawer.fill(Can.cola, 1, RIGHT_AWAY)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_drops_item_to_bin
|
17
|
+
bin.expects(:receive).with(Can.cola)
|
18
|
+
drawer.drop(RIGHT_AWAY)
|
19
|
+
bin.expects(:receive).with(Can.fanta)
|
20
|
+
Drawer.new(bin).fill(Can.fanta, 1, RIGHT_AWAY).drop(RIGHT_AWAY)
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_dropping_reduces_the_stock
|
24
|
+
bin.stubs(:receive)
|
25
|
+
drawer.drop(RIGHT_AWAY)
|
26
|
+
assert_equal [], drawer.stock
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_dropping_more_than_you_have_has_no_effect
|
30
|
+
bin.expects(:receive).with(Can.cola).once
|
31
|
+
drawer.drop(RIGHT_AWAY)
|
32
|
+
drawer.drop(RIGHT_AWAY)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_filling_adds_a_number_of_cans_in_stock
|
36
|
+
drawer.fill(Can.cola, 2, RIGHT_AWAY)
|
37
|
+
assert_equal([Can.cola, Can.cola, Can.cola], drawer.stock)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class DrawerSensorTest < Test::Unit::TestCase
|
42
|
+
attr_reader :drawer, :bin, :sensor_collection
|
43
|
+
|
44
|
+
def setup
|
45
|
+
@bin = stub('bin', :receive)
|
46
|
+
@sensor_collection = mock('sensor_collection')
|
47
|
+
@drawer = Drawer.new(bin, sensor_collection)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_dropping_a_can_fires_a_sensor_event
|
51
|
+
@sensor_collection.stubs(:fire).with(:drawer_fill_can_0)
|
52
|
+
@drawer.fill(Can.cola, 1, RIGHT_AWAY)
|
53
|
+
@sensor_collection.expects(:fire).with(:drawer_drop_can_0)
|
54
|
+
@drawer.drop(RIGHT_AWAY)
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_filling_fires_fill_can_event_for_each_can
|
58
|
+
@sensor_collection.expects(:fire).with(:drawer_fill_can_0).times(3)
|
59
|
+
@drawer.fill(Can.cola, 3, RIGHT_AWAY)
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
class ConfiguringDrawerTest < Test::Unit::TestCase
|
65
|
+
attr_reader :drawer, :bin, :sensor_collection, :actuator_collection
|
66
|
+
|
67
|
+
def setup
|
68
|
+
@sensor_collection = mock('sensor_collection')
|
69
|
+
@actuator_collection = mock('mock_collection')
|
70
|
+
@bin = mock('bin')
|
71
|
+
|
72
|
+
@drawer = Drawer.new(bin, sensor_collection, actuator_collection, 1)
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_configure_sensors_configures_drop_and_fill_can
|
76
|
+
sensor_collection.expects(:create_sensor_for).with(:drawer_drop_can_1)
|
77
|
+
sensor_collection.expects(:create_sensor_for).with(:drawer_fill_can_1)
|
78
|
+
actuator_collection.expects(:create_actuator_for).with(:drawer_drop_can_1)
|
79
|
+
|
80
|
+
drawer.configure
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_fired_actuator_drops_can
|
84
|
+
sensor_collection.stubs(:create_sensor_for)
|
85
|
+
# YIELD is what happens when the actuator is fired
|
86
|
+
actuator_collection.expects(:create_actuator_for).with(:drawer_drop_can_1).yields
|
87
|
+
|
88
|
+
def drawer.drop
|
89
|
+
@drop_called = true
|
90
|
+
end
|
91
|
+
def drawer.drop_called
|
92
|
+
@drop_called
|
93
|
+
end
|
94
|
+
|
95
|
+
drawer.configure
|
96
|
+
|
97
|
+
assert drawer.drop_called, "drop should be called as result of yield of actuator"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..','test_helper')
|
2
|
+
require 'hardware/enum'
|
3
|
+
module Hardware
|
4
|
+
class EnumTest < Test::Unit::TestCase
|
5
|
+
class MyEnum < Enum
|
6
|
+
values :first, :second
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_enum_value_is_accessible_with_class_method
|
10
|
+
assert_nothing_raised do
|
11
|
+
MyEnum.first
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_non_existing_value_raises_exception
|
16
|
+
assert_raises RuntimeError do
|
17
|
+
MyEnum.blah
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_enum_values_are_exactly_same
|
22
|
+
assert_same MyEnum.first, MyEnum.first
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_different_enum_values_are_exactly_same
|
26
|
+
assert_not_same MyEnum.second, MyEnum.first
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_inspecting_a_value_returns_a_readable_string
|
30
|
+
assert_equal 'Hardware::EnumTest::MyEnum.first', MyEnum.first.inspect
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,189 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'..','test_helper')
|
2
|
+
require 'mocha'
|
3
|
+
require 'hardware'
|
4
|
+
|
5
|
+
module Hardware
|
6
|
+
class SimulatorAssembleABinTest < Test::Unit::TestCase
|
7
|
+
def test_attaches_a_sensor_to_receiving_an_item
|
8
|
+
sensors = Adapter::SensorCollection.new
|
9
|
+
simulator = Simulator.new
|
10
|
+
bin = Bin.new(sensors)
|
11
|
+
simulator.assemble_hardware_component(:bin, bin)
|
12
|
+
sensor_called = false
|
13
|
+
sensors.on(:bin_entry) do
|
14
|
+
sensor_called = true
|
15
|
+
end
|
16
|
+
bin.receive("some_object")
|
17
|
+
assert sensor_called, "bin_entry sensor should be fired"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class SimulatorAssembleHardwareComponents < Test::Unit::TestCase
|
22
|
+
attr_reader :sensors, :simulator, :component
|
23
|
+
def setup
|
24
|
+
@sensors = Adapter::SensorCollection.new
|
25
|
+
@simulator = Simulator.new
|
26
|
+
@component = mock("hardware_component")
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_configuring_a_hardware_component_configures_the_component
|
30
|
+
component.expects(:configure).with().once
|
31
|
+
simulator.assemble_hardware_component(:bin, component)
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_configuring_a_list_of_similar_hardware_components_configures_them_all
|
35
|
+
component.expects(:configure).with().twice
|
36
|
+
simulator.assemble_hardware_components(:drawer, [component, component])
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_configured_hardware_component_is_available_by_name
|
40
|
+
bin = stub('bin', :configure)
|
41
|
+
simulator.assemble_hardware_component(:bin, bin)
|
42
|
+
assert_same bin, simulator.component(:bin)
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_configured_hardware_components_are_available_by_name
|
46
|
+
drawer0 = stub('drawer0', :configure)
|
47
|
+
drawer1 = stub('drawer1', :configure)
|
48
|
+
|
49
|
+
simulator.assemble_hardware_components(:drawer, [drawer0, drawer1])
|
50
|
+
|
51
|
+
assert_same drawer0, simulator.component(:drawer_0)
|
52
|
+
assert_same drawer1, simulator.component(:drawer_1)
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_monitor_changes_delegates_to_the_appropriate_hardware_component
|
56
|
+
component.stubs(:configure)
|
57
|
+
simulator.assemble_hardware_component(:my_comp, component)
|
58
|
+
|
59
|
+
component.expects(:monitor_changes).yields()
|
60
|
+
block_given = 'block not given'
|
61
|
+
simulator.monitor_changes(:my_comp) do
|
62
|
+
block_given = 'block_given'
|
63
|
+
end
|
64
|
+
|
65
|
+
assert_equal 'block_given', block_given
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class SimulatorAssembleHardware < Test::Unit::TestCase
|
70
|
+
attr_reader :actuators, :sensors, :simulator
|
71
|
+
def setup
|
72
|
+
@actuators = Adapter::ActuatorCollection.new
|
73
|
+
@sensors = Adapter::SensorCollection.new
|
74
|
+
@simulator = Simulator.new(actuators, sensors)
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_assembles_one_bin
|
78
|
+
simulator.assemble_hardware
|
79
|
+
assert_equal(Bin, simulator.bin.class)
|
80
|
+
assert sensors.list.include?(:bin_entry)
|
81
|
+
assert sensors.list.include?(:bin_fetch_all)
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_assembles_one_display
|
85
|
+
simulator.assemble_hardware
|
86
|
+
assert_equal(Display, simulator.display.class)
|
87
|
+
assert actuators.list.include?(:display_show)
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_assembles_4_drawers
|
91
|
+
simulator.assemble_hardware
|
92
|
+
assert_equal(Drawer, simulator.drawer(0).class)
|
93
|
+
assert_equal(Drawer, simulator.drawer(1).class)
|
94
|
+
assert_equal(Drawer, simulator.drawer(2).class)
|
95
|
+
assert_equal(Drawer, simulator.drawer(3).class)
|
96
|
+
assert actuators.list.include?(:drawer_drop_can_0)
|
97
|
+
assert actuators.list.include?(:drawer_drop_can_1)
|
98
|
+
assert actuators.list.include?(:drawer_drop_can_2)
|
99
|
+
assert actuators.list.include?(:drawer_drop_can_3)
|
100
|
+
assert sensors.list.include?(:drawer_drop_can_0)
|
101
|
+
assert sensors.list.include?(:drawer_drop_can_1)
|
102
|
+
assert sensors.list.include?(:drawer_drop_can_2)
|
103
|
+
assert sensors.list.include?(:drawer_drop_can_3)
|
104
|
+
assert sensors.list.include?(:drawer_fill_can_0)
|
105
|
+
assert sensors.list.include?(:drawer_fill_can_1)
|
106
|
+
assert sensors.list.include?(:drawer_fill_can_2)
|
107
|
+
assert sensors.list.include?(:drawer_fill_can_3)
|
108
|
+
end
|
109
|
+
def test_assembles_4_buttons
|
110
|
+
simulator.assemble_hardware
|
111
|
+
assert_equal(Button, simulator.button(0).class)
|
112
|
+
assert_equal(Button, simulator.button(1).class)
|
113
|
+
assert_equal(Button, simulator.button(2).class)
|
114
|
+
assert_equal(Button, simulator.button(3).class)
|
115
|
+
assert sensors.list.include?(:button_press_0)
|
116
|
+
assert sensors.list.include?(:button_press_1)
|
117
|
+
assert sensors.list.include?(:button_press_2)
|
118
|
+
assert sensors.list.include?(:button_press_3)
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_assembles_cash_register
|
122
|
+
simulator.assemble_hardware
|
123
|
+
assert_equal(CashRegister, simulator.component(:cash_register).class)
|
124
|
+
assert actuators.list.include?(:cash_drop_100)
|
125
|
+
assert actuators.list.include?(:cash_drop_200)
|
126
|
+
assert actuators.list.include?(:cash_drop_50)
|
127
|
+
assert sensors.list.include?(:cash_fill_100)
|
128
|
+
assert sensors.list.include?(:cash_fill_200)
|
129
|
+
assert sensors.list.include?(:cash_fill_50)
|
130
|
+
assert sensors.list.include?(:cash_insert_100)
|
131
|
+
assert sensors.list.include?(:cash_insert_200)
|
132
|
+
assert sensors.list.include?(:cash_insert_50)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
class SimulatorReset < Test::Unit::TestCase
|
137
|
+
attr_reader :actuators, :sensors, :simulator
|
138
|
+
def setup
|
139
|
+
@actuators = Adapter::ActuatorCollection.new
|
140
|
+
@sensors = Adapter::SensorCollection.new
|
141
|
+
@simulator = Simulator.new(actuators, sensors)
|
142
|
+
simulator.assemble_hardware
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_empties_drawers
|
146
|
+
simulator.drawer(0).fill(Hardware::Can.cola, 2, 0)
|
147
|
+
simulator.reset
|
148
|
+
assert simulator.drawer(0).empty?
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_empties_cash_register
|
152
|
+
simulator.cash_register.fill(Hardware::Coin.one_euro, 2, 0)
|
153
|
+
simulator.reset
|
154
|
+
assert simulator.cash_register.empty?
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_removes_sensor_listeners
|
158
|
+
bin_entry_called = "was not called"
|
159
|
+
sensors.on(:bin_entry) { bin_entry_called = "was called" }
|
160
|
+
simulator.reset
|
161
|
+
sensors.fire(:bin_entry)
|
162
|
+
|
163
|
+
assert_equal "was not called", bin_entry_called
|
164
|
+
end
|
165
|
+
|
166
|
+
def test_fires_start_boot_block
|
167
|
+
boot_block = "was not called"
|
168
|
+
simulator.on_boot { boot_block = "was called" }
|
169
|
+
simulator.reset
|
170
|
+
assert_equal "was called", boot_block
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
class SimulatorBoot < Test::Unit::TestCase
|
175
|
+
attr_reader :simulator
|
176
|
+
def setup
|
177
|
+
@simulator = Simulator.new(Adapter::ActuatorCollection.null, Adapter::SensorCollection.null)
|
178
|
+
simulator.assemble_hardware
|
179
|
+
end
|
180
|
+
|
181
|
+
def test_fires_start_boot_block
|
182
|
+
boot_block = "was not called"
|
183
|
+
simulator.on_boot { boot_block = "was called" }
|
184
|
+
simulator.boot
|
185
|
+
assert_equal "was called", boot_block
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
end
|