vmsim 0.2.3
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/.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,20 @@
|
|
1
|
+
module Hardware
|
2
|
+
class Enum
|
3
|
+
def initialize(type)
|
4
|
+
@type = type
|
5
|
+
end
|
6
|
+
def inspect
|
7
|
+
return "#{self.class.name}.#{@type}"
|
8
|
+
end
|
9
|
+
def self.method_missing(method)
|
10
|
+
begin
|
11
|
+
self.send('class_variable_get',"@@#{method}")
|
12
|
+
rescue
|
13
|
+
raise "Enum constant '#{method}' not defined in #{self}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
def self.values(*values)
|
17
|
+
values.each{|value| send('class_variable_set',"@@#{value}", new(value.to_s))}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'hardware_adapter'
|
2
|
+
module Hardware
|
3
|
+
class Simulator
|
4
|
+
attr_reader :bin, :cash_register, :display
|
5
|
+
|
6
|
+
def initialize(actuators = Adapter.actuators, sensors = Adapter.sensors)
|
7
|
+
@components = {}
|
8
|
+
@actuators = actuators
|
9
|
+
@sensors = sensors
|
10
|
+
end
|
11
|
+
|
12
|
+
def component(component_name)
|
13
|
+
@components[component_name]
|
14
|
+
end
|
15
|
+
|
16
|
+
def assemble_hardware_component(component_name, component)
|
17
|
+
@components[component_name] = component
|
18
|
+
component.configure
|
19
|
+
end
|
20
|
+
|
21
|
+
def assemble_hardware_components(basename, components)
|
22
|
+
components.each_with_index do |component, sequence_number|
|
23
|
+
assemble_hardware_component(component_name(basename, sequence_number), component)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def monitor_changes(component_name, &block)
|
28
|
+
component(component_name).monitor_changes(&block)
|
29
|
+
end
|
30
|
+
|
31
|
+
def assemble_hardware
|
32
|
+
assemble_hardware_component :bin, create_bin
|
33
|
+
assemble_hardware_component :display, create_display
|
34
|
+
assemble_hardware_component :cash_register, create_cash_register
|
35
|
+
assemble_hardware_components :drawer, create_drawers
|
36
|
+
assemble_hardware_components :button, create_buttons
|
37
|
+
end
|
38
|
+
|
39
|
+
def drawer(no)
|
40
|
+
@drawers[no]
|
41
|
+
end
|
42
|
+
|
43
|
+
def button(no)
|
44
|
+
@buttons[no]
|
45
|
+
end
|
46
|
+
|
47
|
+
def reset
|
48
|
+
@components.each { |name, component| component.reset }
|
49
|
+
sensors.remove_fire_listeners
|
50
|
+
boot
|
51
|
+
end
|
52
|
+
|
53
|
+
def boot
|
54
|
+
call_boot_block
|
55
|
+
end
|
56
|
+
|
57
|
+
def on_boot(&block)
|
58
|
+
@boot_block = block
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
private
|
63
|
+
attr_reader :actuators, :sensors
|
64
|
+
|
65
|
+
def call_boot_block
|
66
|
+
@boot_block.call if @boot_block
|
67
|
+
end
|
68
|
+
def component_name(basename, sequence_number)
|
69
|
+
"#{basename}_#{sequence_number}".to_sym
|
70
|
+
end
|
71
|
+
|
72
|
+
def create_display
|
73
|
+
@display = Hardware::Display.new(actuators)
|
74
|
+
end
|
75
|
+
|
76
|
+
def create_cash_register
|
77
|
+
@cash_register = Hardware::CashRegister.new(bin, sensors, actuators)
|
78
|
+
end
|
79
|
+
|
80
|
+
def create_drawers
|
81
|
+
@drawers = [ Hardware::Drawer.new(bin,sensors,actuators, 0),
|
82
|
+
Hardware::Drawer.new(bin,sensors,actuators, 1),
|
83
|
+
Hardware::Drawer.new(bin,sensors,actuators, 2),
|
84
|
+
Hardware::Drawer.new(bin,sensors,actuators, 3)]
|
85
|
+
end
|
86
|
+
|
87
|
+
def create_buttons
|
88
|
+
@buttons = [ Hardware::Button.new(sensors, 0),
|
89
|
+
Hardware::Button.new(sensors, 1),
|
90
|
+
Hardware::Button.new(sensors, 2),
|
91
|
+
Hardware::Button.new(sensors, 3)]
|
92
|
+
end
|
93
|
+
|
94
|
+
def create_bin
|
95
|
+
@bin = Hardware::Bin.new(sensors)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
data/lib/hardware.rb
ADDED
data/lib/vmlog.rb
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'..','test_helper')
|
2
|
+
require 'hardware_adapter'
|
3
|
+
|
4
|
+
module Adapter
|
5
|
+
class ActuatorCollectionTest < Test::Unit::TestCase
|
6
|
+
attr_reader :actuator_collection, :actuator_called, :other_actuator_called
|
7
|
+
def setup
|
8
|
+
@actuator_collection = ActuatorCollection.new(SynchronousFirer)
|
9
|
+
@actuator_called = false
|
10
|
+
@other_actuator_called = false
|
11
|
+
actuator_collection.create_actuator_for('some_actuator') do
|
12
|
+
@actuator_called = true
|
13
|
+
end
|
14
|
+
actuator_collection.create_actuator_for(:some_other_actuator) do
|
15
|
+
@other_actuator_called = true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_list_lists_actuators
|
20
|
+
assert_equal [:some_actuator, :some_other_actuator], actuator_collection.list
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_actuators_not_called_if_not_fired
|
24
|
+
assert_equal false, actuator_called, "this actuator should not be called yet"
|
25
|
+
assert_equal false, other_actuator_called, "this actuator should not be called yet"
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_calls_block_given_for_any_actuator
|
29
|
+
actuator_collection.fire(:some_actuator)
|
30
|
+
actuator_collection.fire(:some_other_actuator)
|
31
|
+
|
32
|
+
assert actuator_called, "actuator should be called on fire"
|
33
|
+
assert other_actuator_called, "actuator should be called on fire"
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_actuator_block_can_accept_parameters
|
37
|
+
int_val = -1
|
38
|
+
string_val = ""
|
39
|
+
actuator_collection.create_actuator_for(:parametarized_actuator) do |param1, param2|
|
40
|
+
int_val = param1
|
41
|
+
string_val = param2
|
42
|
+
end
|
43
|
+
actuator_collection.fire(:parametarized_actuator, 34, "gijs")
|
44
|
+
|
45
|
+
assert_equal 34, int_val
|
46
|
+
assert_equal "gijs", string_val
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_actuator_block_may_skip_parameters
|
50
|
+
int_val = -1
|
51
|
+
string_val = ""
|
52
|
+
actuator_collection.create_actuator_for(:parametarized_actuator) do |param1, param2|
|
53
|
+
int_val = param1
|
54
|
+
string_val = param2
|
55
|
+
end
|
56
|
+
actuator_collection.fire(:parametarized_actuator, 34, "gijs", "truus")
|
57
|
+
|
58
|
+
assert_equal 34, int_val
|
59
|
+
assert_equal "gijs", string_val
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_raises_exception_on_firing_unknown_actuator
|
63
|
+
assert_raises NoSuchActuatorException do
|
64
|
+
actuator_collection.fire(:unknown_actuator)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_raises_exception_on_no_block_given
|
69
|
+
assert_raises NoActuatorBlockGiven do
|
70
|
+
actuator_collection.create_actuator_for(:actuator_no_block)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_raises_exception_on_duplicate_actuator
|
75
|
+
assert_raises DuplicateActuatorException do
|
76
|
+
actuator_collection.create_actuator_for(:some_actuator) {}
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
class AsynchronousFirerTest < Test::Unit::TestCase
|
82
|
+
def test_fires_on_other_thread
|
83
|
+
fired = false
|
84
|
+
firer = AsynchronousFirer.new do
|
85
|
+
sleep(0.1)
|
86
|
+
fired = true
|
87
|
+
end
|
88
|
+
t = firer.fire
|
89
|
+
assert_equal false, fired, "should not be fired"
|
90
|
+
t.join
|
91
|
+
assert fired, "should be fired"
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_fires_on_other_thread_with_parameters
|
95
|
+
fired = ''
|
96
|
+
firer = AsynchronousFirer.new do |value|
|
97
|
+
sleep(0.1)
|
98
|
+
fired = value
|
99
|
+
end
|
100
|
+
t = firer.fire('passed string value')
|
101
|
+
assert_equal '', fired, "should not be fired"
|
102
|
+
t.join
|
103
|
+
assert_equal 'passed string value', fired, "should be fired"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'..','test_helper')
|
2
|
+
require 'hardware_adapter'
|
3
|
+
|
4
|
+
module Adapter
|
5
|
+
|
6
|
+
class SensorCollectionFireTest < Test::Unit::TestCase
|
7
|
+
attr_reader :sensors
|
8
|
+
def setup
|
9
|
+
@sensors = SensorCollection.new
|
10
|
+
sensors.create_sensor_for(:bin_entry)
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_list_lists_sensor
|
14
|
+
sensors.create_sensor_for(:something_entry)
|
15
|
+
assert_equal [:bin_entry, :something_entry], sensors.list
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_calls_block_given_for_a_sensor
|
19
|
+
bin_entry_fired = false
|
20
|
+
sensors.on(:bin_entry) do
|
21
|
+
bin_entry_fired = true
|
22
|
+
end
|
23
|
+
sensors.fire(:bin_entry)
|
24
|
+
assert bin_entry_fired, "bin_entry should be fired"
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_swallows_fire_silently_when_no_handler_defined
|
28
|
+
sensors.fire(:bin_entry)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
class SensorCollectionFireWithoutReceptorsCreatedTest < Test::Unit::TestCase
|
34
|
+
attr_reader :sensors
|
35
|
+
def setup
|
36
|
+
@sensors = SensorCollection.new
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_swallows_fire_silently_when_no_handler_defined
|
40
|
+
sensors.fire(:bin_entry)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_on_raises_a_no_such_sensor_exception
|
44
|
+
assert_raises NoSuchSensorException do
|
45
|
+
sensors.on(:bin_entry) {}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'..','test_helper')
|
2
|
+
require 'deploy'
|
3
|
+
require 'tmpdir'
|
4
|
+
require 'archive_builder'
|
5
|
+
|
6
|
+
module Deploy
|
7
|
+
module DeployerTestHelper
|
8
|
+
attr_reader :deployer
|
9
|
+
def create_deployer
|
10
|
+
@deployer = Deployer.new(File.expand_path(File.join(File.dirname(__FILE__), 'was_run.sh')))
|
11
|
+
end
|
12
|
+
def deploy(archive)
|
13
|
+
create_deployer
|
14
|
+
deployer.deploy archive
|
15
|
+
end
|
16
|
+
def is_running(pid)
|
17
|
+
begin
|
18
|
+
Process.kill(0, pid)
|
19
|
+
return true
|
20
|
+
rescue
|
21
|
+
return false
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class DeployerDeployTest < Test::Unit::TestCase
|
27
|
+
include ArchiveBuilder
|
28
|
+
include DeployerTestHelper
|
29
|
+
include FileUtils
|
30
|
+
def teardown
|
31
|
+
rm_r './tmp' if File.exists?('./tmp')
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_unzips_the_archive_and_fires_the_executable
|
35
|
+
deploy an_archive('controlcode.pkg') {
|
36
|
+
a_file("main.rb").with("puts 'was unpacked'")
|
37
|
+
}
|
38
|
+
assert is_running(deployer.current_pid)
|
39
|
+
assert_match /was started.*was unpacked/m, deployer.wait_for.run_log
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_unzips_the_archive_with_relative_path_and_fires_the_executable
|
43
|
+
deploy an_archive('controlcode.pkg', 'tmp') {
|
44
|
+
a_file("main.rb").with("puts 'was unpacked'")
|
45
|
+
}
|
46
|
+
assert is_running(deployer.current_pid)
|
47
|
+
assert_match /was started.*was unpacked/m, deployer.wait_for.run_log
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_clears_current_pid_on_exit
|
51
|
+
deploy an_archive('controlcode.pkg') {
|
52
|
+
a_file("main.rb").with("puts 'was unpacked'")
|
53
|
+
}
|
54
|
+
assert_nil deployer.wait_for.current_pid
|
55
|
+
assert !File.exists?(Deployer::PIDFILE), "PIDFILE should be gone"
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_removes_previous_files
|
59
|
+
deploy an_archive('controlcode.pkg') {
|
60
|
+
a_file("loaded_class.rb").with("class LoadedClass; end")
|
61
|
+
a_file("main.rb").with("require 'loaded_class'")
|
62
|
+
}
|
63
|
+
|
64
|
+
deploy an_archive('controlcode.pkg') {
|
65
|
+
a_file("main.rb").with("puts 'was unpacked'")
|
66
|
+
}
|
67
|
+
|
68
|
+
assert !File.exists?(File.join(Deployer::DEPLOYED_DIR, 'loaded_class.rb')), "loaded class should be removed"
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_removes_previous_directories
|
72
|
+
deploy an_archive('controlcode.pkg') {
|
73
|
+
a_file("lib/loaded_class.rb").with("class LoadedClass; end")
|
74
|
+
a_file("main.rb").with("require 'lib/loaded_class'")
|
75
|
+
}
|
76
|
+
|
77
|
+
deploy an_archive('controlcode.pkg') {
|
78
|
+
a_file("main.rb").with("puts 'was unpacked'")
|
79
|
+
}
|
80
|
+
|
81
|
+
assert !File.exists?(File.join(Deployer::DEPLOYED_DIR, 'loaded_class.rb')), "loaded class should be removed"
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_kills_the_current_running_process_and_starts_new_one
|
85
|
+
deploy an_archive('controlcode.pkg') {
|
86
|
+
a_file("main.rb").with("sleep 1")
|
87
|
+
}
|
88
|
+
old_process_id = deployer.current_pid
|
89
|
+
|
90
|
+
deploy an_archive('controlcode.pkg') {
|
91
|
+
a_file("main.rb").with("puts 'was unpacked'")
|
92
|
+
}
|
93
|
+
|
94
|
+
assert !is_running(old_process_id), "process should be stopped before starting new"
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
class DeployerKillTest < Test::Unit::TestCase
|
100
|
+
include ArchiveBuilder
|
101
|
+
include DeployerTestHelper
|
102
|
+
|
103
|
+
def test_kills_the_current_running_process
|
104
|
+
deploy an_archive('controlcode.pkg') {
|
105
|
+
a_file("main.rb").with("sleep 20")
|
106
|
+
}
|
107
|
+
process_id = deployer.current_pid
|
108
|
+
create_deployer
|
109
|
+
deployer.kill
|
110
|
+
assert !is_running(process_id), "process should be stopped"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'..','test_helper')
|
2
|
+
require 'mocha'
|
3
|
+
require 'devices'
|
4
|
+
|
5
|
+
module Devices
|
6
|
+
class DevicesTest < Test::Unit::TestCase
|
7
|
+
attr_reader :actuators, :sensors, :devices, :handler
|
8
|
+
def setup
|
9
|
+
@actuators = mock('actuatorcollection')
|
10
|
+
@sensors = mock('sensorcollection')
|
11
|
+
@devices = Devices.new(actuators, sensors)
|
12
|
+
@handler = 'not called'
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_display_show
|
16
|
+
actuators.expects(:fire).with(:display_show, 1, "test message")
|
17
|
+
devices.display_show(1, "test message")
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_button_on_press
|
21
|
+
sensors.expects(:on).with(:button_press_1).yields
|
22
|
+
devices.on_button_pressed(1) { handler_called }
|
23
|
+
assert_equal 'called', handler
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_bin_entry
|
27
|
+
sensors.expects(:on).with(:bin_entry).yields
|
28
|
+
devices.on_bin_entry { handler_called }
|
29
|
+
assert_equal 'called', handler
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_bin_fetch_all
|
33
|
+
sensors.expects(:on).with(:bin_fetch_all).yields
|
34
|
+
devices.on_bin_fetch_all { handler_called }
|
35
|
+
assert_equal 'called', handler
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_cash_register_fill_money
|
39
|
+
sensors.expects(:on).with(:cash_fill_100).yields
|
40
|
+
devices.on_cash_filled(100) { handler_called }
|
41
|
+
assert_equal 'called', handler
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_cash_register_insert_money
|
45
|
+
sensors.expects(:on).with(:cash_insert_100).yields
|
46
|
+
devices.on_cash_inserted(100) { handler_called }
|
47
|
+
assert_equal 'called', handler
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_cash_drop_drops_coin
|
51
|
+
actuators.expects(:fire).with(:cash_drop_100)
|
52
|
+
devices.cash_drop_coin(100)
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_drawer_register_can_dropped
|
56
|
+
sensors.expects(:on).with(:drawer_drop_can_0).yields
|
57
|
+
devices.on_drawer_dropped(0) { handler_called }
|
58
|
+
assert_equal 'called', handler
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_drawer_register_can_filled
|
62
|
+
sensors.expects(:on).with(:drawer_fill_can_0).yields
|
63
|
+
devices.on_drawer_filled(0) { handler_called }
|
64
|
+
assert_equal 'called', handler
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_drawer_drop_drops_can
|
68
|
+
actuators.expects(:fire).with(:drawer_drop_can_1)
|
69
|
+
devices.drawer_drop_can(1)
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def handler_called
|
75
|
+
@handler = 'called'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,57 @@
|
|
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 BinTest < Test::Unit::TestCase
|
8
|
+
attr_reader :bin, :sensor_collection
|
9
|
+
def setup
|
10
|
+
@sensor_collection = mock('sensor_collection')
|
11
|
+
@bin = Bin.new(sensor_collection)
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_receive_fills_the_bin_with_the_item
|
15
|
+
sensor_collection.expects(:fire).with(:bin_entry)
|
16
|
+
bin.receive('some_object')
|
17
|
+
assert_equal(['some_object'], bin.contents)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_fetch_the_stuff_empties_the_bin
|
21
|
+
sensor_collection.stubs(:fire).with(:bin_entry) # firing :bin_entry tested above
|
22
|
+
bin.receive('some_object')
|
23
|
+
bin.receive('some_object')
|
24
|
+
|
25
|
+
sensor_collection.expects(:fire).with(:bin_fetch_all)
|
26
|
+
bin.fetch_all
|
27
|
+
|
28
|
+
assert_equal([], bin.contents)
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_configure_configures_the_sensor_in_the_sensor_collection
|
32
|
+
sensor_collection.expects(:create_sensor_for).with(:bin_entry)
|
33
|
+
sensor_collection.expects(:create_sensor_for).with(:bin_fetch_all)
|
34
|
+
bin.configure
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_updates_ui_when_receiving_something
|
38
|
+
bin = Bin.new(Adapter::SensorCollection.null)
|
39
|
+
change_called = false
|
40
|
+
bin.monitor_changes do
|
41
|
+
change_called = true
|
42
|
+
end
|
43
|
+
bin.receive('some_object')
|
44
|
+
assert change_called, 'change was not called'
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_updates_ui_when_fetching_all
|
48
|
+
bin = Bin.new(Adapter::SensorCollection.null)
|
49
|
+
change_called = false
|
50
|
+
bin.monitor_changes do
|
51
|
+
change_called = true
|
52
|
+
end
|
53
|
+
bin.fetch_all
|
54
|
+
assert change_called, 'change was not called'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'..','test_helper')
|
2
|
+
require 'mocha'
|
3
|
+
require 'hardware'
|
4
|
+
|
5
|
+
module Hardware
|
6
|
+
class ButtonTest < Test::Unit::TestCase
|
7
|
+
attr_reader :sensor_collection, :button
|
8
|
+
def setup
|
9
|
+
@sensor_collection = mock('sensor_collection')
|
10
|
+
@button = Button.new(sensor_collection, 1)
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_press_fires_sensor
|
14
|
+
sensor_collection.expects(:fire).with(:button_press_1)
|
15
|
+
button.press
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_configure_configures_sensor_for_button_press
|
19
|
+
sensor_collection.expects(:create_sensor_for).with(:button_press_1)
|
20
|
+
button.configure
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'..','test_helper')
|
2
|
+
require 'hardware'
|
3
|
+
|
4
|
+
module Hardware
|
5
|
+
class CanTest < Test::Unit::TestCase
|
6
|
+
def test_to_s_shows_can_name
|
7
|
+
assert_equal 'can of cola', Can.cola.to_s
|
8
|
+
assert_equal 'can of fanta', Can.fanta.to_s
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|