nxt 0.3.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. checksums.yaml +15 -0
  2. data/README.md +45 -0
  3. data/lib/communication/bluetooth_communication.rb +85 -0
  4. data/lib/communication/serial_port_profile.rb +71 -0
  5. data/lib/nxt.rb +111 -20
  6. data/lib/ruby-nxt.sublime-project +8 -0
  7. data/lib/ruby-nxt.sublime-workspace +288 -0
  8. data/lib/telegrams/commands/direct/get_battery_level.rb +8 -0
  9. data/lib/telegrams/commands/direct/get_current_program_name.rb +8 -0
  10. data/lib/{nxt/commands/sound.rb → telegrams/commands/direct/get_input_values.rb} +0 -0
  11. data/lib/{nxt/commands/tone.rb → telegrams/commands/direct/keep_alive.rb} +0 -0
  12. data/lib/telegrams/commands/direct/ls_get_status.rb +0 -0
  13. data/lib/telegrams/commands/direct/ls_read.rb +0 -0
  14. data/lib/telegrams/commands/direct/ls_write.rb +0 -0
  15. data/lib/telegrams/commands/direct/message_read.rb +0 -0
  16. data/lib/telegrams/commands/direct/message_write.rb +0 -0
  17. data/lib/telegrams/commands/direct/output_state.rb +229 -0
  18. data/lib/telegrams/commands/direct/play_sound_file.rb +38 -0
  19. data/lib/telegrams/commands/direct/play_tone.rb +34 -0
  20. data/lib/telegrams/commands/direct/replies/get_battery_level_reply.rb +28 -0
  21. data/lib/telegrams/commands/direct/replies/get_current_program_name_reply.rb +30 -0
  22. data/lib/telegrams/commands/direct/replies/play_sound_file_reply.rb +13 -0
  23. data/lib/telegrams/commands/direct/replies/play_tone_reply.rb +14 -0
  24. data/lib/telegrams/commands/direct/replies/reset_motor_position_reply.rb +13 -0
  25. data/lib/telegrams/commands/direct/replies/set_input_mode_reply.rb +11 -0
  26. data/lib/telegrams/commands/direct/replies/set_output_state_reply.rb +11 -0
  27. data/lib/telegrams/commands/direct/replies/start_program_reply.rb +13 -0
  28. data/lib/telegrams/commands/direct/replies/stop_program_reply.rb +13 -0
  29. data/lib/telegrams/commands/direct/replies/stop_sound_playback_reply.rb +13 -0
  30. data/lib/telegrams/commands/direct/reset_input_scaled_value.rb +0 -0
  31. data/lib/telegrams/commands/direct/reset_motor_position.rb +8 -0
  32. data/lib/telegrams/commands/direct/set_input_mode.rb +101 -0
  33. data/lib/telegrams/commands/direct/set_output_state.rb +29 -0
  34. data/lib/telegrams/commands/direct/start_program.rb +30 -0
  35. data/lib/telegrams/commands/direct/stop_program.rb +9 -0
  36. data/lib/telegrams/commands/direct/stop_sound_playback.rb +8 -0
  37. data/lib/telegrams/commands/direct_command.rb +8 -0
  38. data/lib/telegrams/commands/direct_command_reply.rb +10 -0
  39. data/lib/telegrams/commands/message_translator.rb +46 -0
  40. data/lib/telegrams/commands/system/get_device_info.rb +8 -0
  41. data/lib/telegrams/commands/system/replies/get_device_info_reply.rb +41 -0
  42. data/lib/telegrams/commands/system_command.rb +8 -0
  43. data/lib/telegrams/messages/error.rb +0 -0
  44. data/lib/telegrams/messages/message.rb +0 -0
  45. data/lib/telegrams/messages/success.rb +0 -0
  46. data/lib/telegrams/no_message_reply.rb +10 -0
  47. data/lib/telegrams/reply.rb +82 -0
  48. data/lib/telegrams/respondable_telegram.rb +29 -0
  49. data/lib/telegrams/telegram.rb +14 -0
  50. data/spec/communication/bluetooth_communication_spec.rb +170 -0
  51. data/spec/communication/serial_port_profile_spec.rb +139 -0
  52. data/spec/helper.rb +1 -0
  53. data/spec/nxt_spec.rb +438 -0
  54. data/spec/telegrams/commands/direct/get_battery_level_spec.rb +26 -0
  55. data/spec/telegrams/commands/direct/get_current_program_name_spec.rb +26 -0
  56. data/spec/telegrams/commands/direct/output_state_spec.rb +198 -0
  57. data/spec/telegrams/commands/direct/play_sound_file_spec.rb +75 -0
  58. data/spec/telegrams/commands/direct/play_tone_spec.rb +63 -0
  59. data/spec/telegrams/commands/direct/replies/get_battery_level_reply_spec.rb +40 -0
  60. data/spec/telegrams/commands/direct/replies/get_current_program_name_reply_spec.rb +33 -0
  61. data/spec/telegrams/commands/direct/replies/play_sound_file_reply_spec.rb +13 -0
  62. data/spec/telegrams/commands/direct/replies/play_tone_reply_spec.rb +14 -0
  63. data/spec/telegrams/commands/direct/replies/reset_motor_position_reply_spec.rb +13 -0
  64. data/spec/telegrams/commands/direct/replies/set_input_mode_reply_spec.rb +12 -0
  65. data/spec/telegrams/commands/direct/replies/set_output_state_reply_spec.rb +12 -0
  66. data/spec/telegrams/commands/direct/replies/start_program_reply_spec.rb +12 -0
  67. data/spec/telegrams/commands/direct/replies/stop_program_reply_spec.rb +13 -0
  68. data/spec/telegrams/commands/direct/replies/stop_sound_playback_reply_spec.rb +13 -0
  69. data/spec/telegrams/commands/direct/reset_motor_position_spec.rb +31 -0
  70. data/spec/telegrams/commands/direct/set_input_mode_spec.rb +122 -0
  71. data/spec/telegrams/commands/direct/set_output_state_spec.rb +72 -0
  72. data/spec/telegrams/commands/direct/start_program_spec.rb +58 -0
  73. data/spec/telegrams/commands/direct/stop_program_spec.rb +34 -0
  74. data/spec/telegrams/commands/direct/stop_sound_playback_spec.rb +34 -0
  75. data/spec/telegrams/commands/direct_command_reply_spec.rb +7 -0
  76. data/spec/telegrams/commands/direct_command_spec.rb +34 -0
  77. data/spec/telegrams/commands/system/get_device_info_spec.rb +16 -0
  78. data/spec/telegrams/commands/system/replies/get_device_info_reply_spec.rb +63 -0
  79. data/spec/telegrams/commands/system_command_spec.rb +26 -0
  80. data/spec/telegrams/no_message_reply_spec.rb +12 -0
  81. data/spec/telegrams/reply_spec.rb +63 -0
  82. data/spec/telegrams/respondable_telegram_spec.rb +66 -0
  83. data/spec/telegrams/telegram_spec.rb +38 -0
  84. metadata +97 -116
  85. data/README.markdown +0 -52
  86. data/Rakefile +0 -35
  87. data/lib/nxt/commands/base.rb +0 -51
  88. data/lib/nxt/commands/input.rb +0 -60
  89. data/lib/nxt/commands/output.rb +0 -105
  90. data/lib/nxt/commands/program.rb +0 -70
  91. data/lib/nxt/connectors/base.rb +0 -35
  92. data/lib/nxt/connectors/input/color.rb +0 -30
  93. data/lib/nxt/connectors/input/touch.rb +0 -11
  94. data/lib/nxt/connectors/input/ultrasonic.rb +0 -11
  95. data/lib/nxt/connectors/output/motor.rb +0 -114
  96. data/lib/nxt/errors.rb +0 -25
  97. data/lib/nxt/exceptions.rb +0 -26
  98. data/lib/nxt/interfaces/base.rb +0 -36
  99. data/lib/nxt/interfaces/serial_port.rb +0 -88
  100. data/lib/nxt/interfaces/usb.rb +0 -8
  101. data/lib/nxt/nxt_brick.rb +0 -167
  102. data/lib/nxt/patches/module.rb +0 -22
  103. data/lib/nxt/patches/string.rb +0 -29
  104. data/lib/nxt/utils/accessors.rb +0 -24
  105. data/spec/matchers.rb +0 -7
  106. data/spec/nxt/connectors/output/motor_spec.rb +0 -55
  107. data/spec/nxt/interfaces/serial_port_spec.rb +0 -73
  108. data/spec/nxt/nxt_brick_spec.rb +0 -199
  109. data/spec/spec_helper.rb +0 -4
@@ -0,0 +1,26 @@
1
+ require './spec/helper'
2
+ require './lib/telegrams/commands/direct/get_battery_level'
3
+
4
+ describe GetBatteryLevel do
5
+ describe "when constructing the object" do
6
+ it "must not accept any parameters" do
7
+ -> { GetBatteryLevel.new false }.must_raise ArgumentError
8
+ end
9
+
10
+ it "must default to requiring a response since it is asking for one" do
11
+ GetBatteryLevel.new.require_response?.must_equal true
12
+ end
13
+
14
+ it "must have a command of 0x0B for getbatterylevel" do
15
+ GetBatteryLevel.new.command.must_equal 0x0B
16
+ end
17
+ end
18
+
19
+ describe "as_bytes" do
20
+ it "must have the command as the second byte" do
21
+ command = GetBatteryLevel.new
22
+ command.as_bytes[1].must_equal command.command
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,26 @@
1
+ require './spec/helper'
2
+
3
+ require './lib/telegrams/commands/direct/get_current_program_name'
4
+
5
+ describe GetCurrentProgramName do
6
+ describe "when constructing the object" do
7
+ it "must not accept any parameters" do
8
+ -> { GetCurrentProgramName.new false }.must_raise ArgumentError
9
+ end
10
+
11
+ it "must default to requiring a response since it is asking for one" do
12
+ GetCurrentProgramName.new.require_response?.must_equal true
13
+ end
14
+
15
+ it "must have a command of 0x11 for getcurrentprogramname" do
16
+ GetCurrentProgramName.new.command.must_equal 0x11
17
+ end
18
+ end
19
+
20
+ describe "as_bytes" do
21
+ it "must have the command as the second byte" do
22
+ command = GetCurrentProgramName.new
23
+ command.as_bytes[1].must_equal command.command
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,198 @@
1
+ require './spec/helper'
2
+ require './lib/telegrams/commands/direct/output_state'
3
+
4
+ describe OutputState do
5
+ # attr_reader :port, :power, :mode, :regulation_mode, :turn_ratio, :run_state, :tacho_limit
6
+
7
+ # this next group can only be read from a GetOutputState call:
8
+ # tacho_count # internal count; number of counts since last reset of the motor counter
9
+ # block_tacho_count # current position relative to last programmed movement
10
+ # rotation_count # current position relative to last reset of the rotation sensor for this motor
11
+ describe "when constructing the object" do
12
+ it "must accept hash contructor arguments with defaults of 0" do
13
+ state = OutputState.new({ :port => :a })
14
+ state.port.must_equal :a
15
+ state.mode_flags.must_equal 0
16
+ end
17
+ end
18
+
19
+ describe "when using the builder structure" do
20
+ before do
21
+ @state = OutputState.new
22
+ end
23
+
24
+ it "must accept a 'for_port(port_symbol) message that sets the value and returns the object itself" do
25
+ @state.for_port(:a).must_equal @state
26
+ @state.port.must_equal :a
27
+ end
28
+
29
+ it "must accept a 'with_power(power)' message that sets the value and returns the object itself" do
30
+ @state.with_power(100).must_equal @state
31
+ @state.power.must_equal 100
32
+ end
33
+
34
+ it "must accept a 'with_mode_flags(mode_flags)' that sets the value and returns the object itself" do
35
+ @state.with_mode_flags(OutputModeFlags.MOTORON | OutputModeFlags.REGULATED).must_equal @state
36
+ @state.mode_flags.must_equal OutputModeFlags.MOTORON | OutputModeFlags.REGULATED
37
+ end
38
+
39
+ it "must accept a 'with_regulation_mode(regulation_mode)' that sets the value and returns the object itself" do
40
+ @state.with_regulation_mode(:motor_speed).must_equal @state
41
+ @state.regulation_mode.must_equal :motor_speed
42
+ end
43
+
44
+ it "must accept a 'with_turn_ratio(turn_ratio)' message that sets the value and returns the object itself" do
45
+ @state.with_turn_ratio(100).must_equal @state
46
+ @state.turn_ratio.must_equal 100
47
+ end
48
+
49
+ it "must accept a 'with_run_state(run_state)' that sets the value and returns the object itself" do
50
+ @state.with_run_state(:ramp_up).must_equal @state
51
+ @state.run_state.must_equal :ramp_up
52
+ end
53
+
54
+ it "must accept a 'with_tacho_limit(tacho_limit)' that sets the value and returns the object itself" do
55
+ @state.with_tacho_limit(325).must_equal @state
56
+ @state.tacho_limit.must_equal 325
57
+ end
58
+ end
59
+
60
+ describe "when using the setter methods" do
61
+ before do
62
+ @state = OutputState.new
63
+ end
64
+
65
+ it "must validate that the port is :a, :b, :c, or :all" do
66
+ @state.port = :a
67
+ @state.port = :b
68
+ @state.port = :c
69
+ @state.port = :all
70
+ -> { @state.port = :d }.must_raise ArgumentError
71
+ end
72
+
73
+ it "must set the port when it is set" do
74
+ @state.port = :b
75
+ @state.port.must_equal :b
76
+ end
77
+
78
+ it "must validate that the power is between -100 and 100" do
79
+ [-100, 0, 100].each do |power|
80
+ @state.power = power
81
+ @state.power.must_equal power
82
+ end
83
+ -> { @state.power = -101 }.must_raise ArgumentError
84
+ -> { @state.power = 101 }.must_raise ArgumentError
85
+ end
86
+
87
+ it "must vaidate that the mode_flags is a valid combination of 0 to all flags (0-7 as an integer)" do
88
+ (0..7).each do |mode|
89
+ @state.mode_flags = mode
90
+ @state.mode_flags.must_equal mode
91
+ end
92
+
93
+ -> { @state.mode_flags = 8 }.must_raise ArgumentError
94
+ end
95
+
96
+ it "must validate that the regulation_mode is one of the valid enumerations" do
97
+ [:idle, :motor_speed, :motor_sync].each do |regulation_mode|
98
+ @state.regulation_mode = regulation_mode
99
+ @state.regulation_mode.must_equal regulation_mode
100
+ end
101
+
102
+ -> { @state.regulation_mode = :garbage }.must_raise ArgumentError
103
+ -> { @state.regulation_mode = 1 }.must_raise ArgumentError
104
+ end
105
+
106
+ it "must validate that the turn_ratio is between -100 and 100" do
107
+ [-100, 0, 100].each do |turn_ratio|
108
+ @state.turn_ratio = turn_ratio
109
+ @state.turn_ratio.must_equal turn_ratio
110
+ end
111
+ -> { @state.turn_ratio = -101 }.must_raise ArgumentError
112
+ -> { @state.turn_ratio = 101 }.must_raise ArgumentError
113
+ end
114
+
115
+ it "must validate that the run_state is one of the valid enumerations" do
116
+ [:idle, :running, :ramp_up, :ramp_down].each do |run_state|
117
+ @state.run_state = run_state
118
+ @state.run_state.must_equal run_state
119
+ end
120
+
121
+ -> { @state.run_state = :garbage }.must_raise ArgumentError
122
+ -> { @state.run_state = 1 }.must_raise ArgumentError
123
+ end
124
+
125
+ it "must have a constant representing 'run forever' or 'unlimited'" do
126
+ OutputState.RUN_FOREVER.must_equal 0
127
+ end
128
+
129
+ it "must set the tacho_limit" do
130
+ @state.tacho_limit = 39123 # it's an unsigned long value, 4 bytes
131
+ @state.tacho_limit.must_equal 39123
132
+ end
133
+ end
134
+ end
135
+
136
+ describe OutputModeFlags do
137
+ it "must have MOTORON set to 0x01" do
138
+ OutputModeFlags.MOTORON.must_equal 0x01
139
+ end
140
+
141
+ it "must have BRAKE set to 0x02" do
142
+ OutputModeFlags.BRAKE.must_equal 0x02
143
+ end
144
+
145
+ it "must have REGULATED set to 0x04" do
146
+ OutputModeFlags.REGULATED.must_equal 0x04
147
+ end
148
+
149
+ it "must allow MOTORON and BRAKE to be combined into 0x03" do
150
+ (OutputModeFlags.MOTORON | OutputModeFlags.BRAKE).must_equal 0x03
151
+ end
152
+
153
+ it "must allow MOTORON and REGULATED to be combined into 0x05" do
154
+ (OutputModeFlags.MOTORON | OutputModeFlags.REGULATED).must_equal 0x05
155
+ end
156
+
157
+ it "must allow BRAKE and REGULATED to be combined into 0x06" do
158
+ (OutputModeFlags.BRAKE | OutputModeFlags.REGULATED).must_equal 0x06
159
+ end
160
+
161
+ it "must allow all three to be combined into 0x07" do
162
+ (OutputModeFlags.MOTORON | OutputModeFlags.BRAKE | OutputModeFlags.REGULATED).must_equal 0x07
163
+ end
164
+ end
165
+
166
+
167
+ describe RegulationMode do
168
+ it "must have IDLE defined as 0x00" do
169
+ RegulationMode.IDLE.must_equal 0x00
170
+ end
171
+
172
+ it "must have MOTOR_SPEED defined as 0x01" do
173
+ RegulationMode.MOTOR_SPEED.must_equal 0x01
174
+ end
175
+
176
+ it "must have MOTOR_SYNC defined as 0x02" do
177
+ RegulationMode.MOTOR_SYNC.must_equal 0x02
178
+ end
179
+ end
180
+
181
+
182
+ describe RunState do
183
+ it "must have IDLE defined as 0x00" do
184
+ RunState.IDLE.must_equal 0x00
185
+ end
186
+
187
+ it "must have RAMPUP defined as 0x10" do
188
+ RunState.RAMPUP.must_equal 0x10
189
+ end
190
+
191
+ it "must have RUNNING defined as 0x20" do
192
+ RunState.RUNNING.must_equal 0x20
193
+ end
194
+
195
+ it "must have RAMPDOWN defined as 0x40" do
196
+ RunState.RAMPDOWN.must_equal 0x40
197
+ end
198
+ end
@@ -0,0 +1,75 @@
1
+ require './spec/helper'
2
+
3
+ require './lib/telegrams/commands/direct/play_sound_file'
4
+
5
+
6
+ describe PlaySoundFile do
7
+ describe "when creating the play sound file command" do
8
+ it "must default to requiring a response" do
9
+ PlaySoundFile.new('name').require_response?.must_equal true
10
+ end
11
+
12
+ it "must set the require_response member to the value passed in" do
13
+ PlaySoundFile.new('name', true, false).require_response?.must_equal false
14
+ end
15
+
16
+ it "must raise an ArgumentError when the filename is nil" do
17
+ -> { PlaySoundFile.new(nil) }.must_raise ArgumentError
18
+ end
19
+
20
+ it "must set the command value to 0x02 (startprogram)" do
21
+ PlaySoundFile.new('name').command.must_equal 0x02
22
+ end
23
+
24
+ it "must set the filename to the value passed in" do
25
+ PlaySoundFile.new('name.mp3').name.must_equal 'name.mp3'
26
+ end
27
+
28
+ it "must default the loop_sound value to false" do
29
+ PlaySoundFile.new('name.mp3').loop_sound?.must_equal false
30
+ end
31
+
32
+ it "must set the loop_sound boolean to the value passed in" do
33
+ PlaySoundFile.new('name.mp3', true).loop_sound?.must_equal true
34
+ end
35
+
36
+ it "must set the loop_sound? value to false unless explicitely set to true" do
37
+ PlaySoundFile.new('name.mp3', "bizbuzz").loop_sound?.must_equal false
38
+ end
39
+
40
+ it "must try adding '.rso' to the end of the filename if there is no file extension" do
41
+ name = 'sound'
42
+ PlaySoundFile.new(name).name.must_equal "#{name}.rso"
43
+ end
44
+
45
+ it "must leave the filename alone if there is a 3 letter extension of any kind" do
46
+ name = 'sound.foo'
47
+ PlaySoundFile.new(name).name.must_equal name
48
+ end
49
+ end
50
+
51
+ describe "when rendering the command using as_bytes" do
52
+ it "must have the command value as the second byte" do
53
+ command = PlaySoundFile.new('name')
54
+ command.as_bytes[1].must_equal command.command
55
+ end
56
+
57
+ it "must have the loop_sound value as the third byte" do
58
+ PlaySoundFile.new('name.mp3', false).as_bytes[2].must_equal 0x00
59
+ PlaySoundFile.new('name.mp3', true).as_bytes[2].must_equal 0xff
60
+ end
61
+
62
+ it "must have the program name in ASCIIZ (null terminated ascii) for bytes 4-23" do
63
+ name = 'sound.mp3'
64
+ name_as_asciiz = [115, 111, 117, 110, 100, 46, 109, 112, 51, 0,
65
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
66
+
67
+ command = PlaySoundFile.new(name)
68
+ bytes = command.as_bytes
69
+ name_bytes = bytes.slice(3, 20)
70
+
71
+ name_bytes.must_equal name_as_asciiz
72
+ end
73
+ end
74
+
75
+ end
@@ -0,0 +1,63 @@
1
+ require './spec/helper'
2
+ require './lib/telegrams/commands/direct/play_tone'
3
+
4
+ describe PlayTone do
5
+ describe "when constructing the command" do
6
+ before do
7
+ @command = PlayTone.new(200, 100)
8
+ end
9
+
10
+ it "must be a direct command" do
11
+ @command.type.must_equal DirectCommand.new.type
12
+ end
13
+
14
+ it "must have a command of 0x03" do
15
+ @command.command.must_equal 0x03
16
+ end
17
+
18
+ it "must require a response by default" do
19
+ @command.require_response?.must_equal true
20
+ end
21
+
22
+ it "must throw an ArgumentException if the frequency is not passed in" do
23
+ -> { PlayTone.new }.must_raise ArgumentError
24
+ end
25
+
26
+ it "must throw an ArgumentException if the duration is not passed in" do
27
+ -> { PlayTone.new(500) }.must_raise ArgumentError
28
+ end
29
+
30
+ it "must set the frequency to what is passed in" do
31
+ PlayTone.new(500, 100).frequency.must_equal 500
32
+ end
33
+
34
+ it "must set the duration to what is passed in" do
35
+ PlayTone.new(500, 100).duration.must_equal 100
36
+ end
37
+
38
+ it "must validate that the frequency (in Hz) is between 200 and 14000 Hz (the valid range)" do
39
+ -> { PlayTone.new(199, 100) }.must_raise ArgumentError
40
+ -> { PlayTone.new(14001, 100) }.must_raise ArgumentError
41
+ end
42
+
43
+ it "must validate that the duration (in ms) is positive or zero" do
44
+ -> { PlayTone.new(500, -1) }.must_raise ArgumentError
45
+ PlayTone.new(500, 0)
46
+ end
47
+ end
48
+
49
+ describe "when rendering the command as bytes" do
50
+ it "must set byte 1 to 0x03 as the playtone command" do
51
+ PlayTone.new(500, 1).as_bytes[1].must_equal 0x03
52
+ end
53
+
54
+ it "must set bytes 2-3 to a UWORD of the frequency to play in reverse order" do
55
+ PlayTone.new(500, 1).as_bytes[2..3].must_equal [0xf4, 0x01]
56
+ end
57
+
58
+ it "must set bytes 4-5 to a UWORD of the duration to play the tone" do
59
+ PlayTone.new(500, 2000).as_bytes[4..5].must_equal [0xd0, 0x07]
60
+ end
61
+ end
62
+ end
63
+
@@ -0,0 +1,40 @@
1
+ require './spec/helper'
2
+ require './lib/telegrams/commands/direct/replies/get_battery_level_reply'
3
+
4
+ describe GetBatteryLevelReply do
5
+ describe "when creating the reply" do
6
+ before do
7
+ @millivolts = 4100
8
+
9
+ # null pad out to max length and convert to ASCIIZ bytes
10
+ @millivolts_bytes = [@millivolts.to_s(16).rjust(4, "0")].pack("H*").bytes.to_a.reverse
11
+ @reply_bytes = [2, 0x0B, 0].concat(@millivolts_bytes)
12
+ end
13
+
14
+ it "must parse the millivolts into the message member" do
15
+ reply = GetBatteryLevelReply.new(@reply_bytes)
16
+
17
+ reply.message.must_equal @millivolts
18
+ end
19
+
20
+ it "must allow access to the message through the millivolts member" do
21
+ reply = GetBatteryLevelReply.new(@reply_bytes)
22
+
23
+ reply.millivolts.must_equal @millivolts
24
+ end
25
+
26
+ it "must convert the millivolts to volts through the volts member" do
27
+ reply = GetBatteryLevelReply.new(@reply_bytes)
28
+
29
+ reply.volts.must_equal @millivolts/1000.0
30
+ end
31
+
32
+ it "must raise an ArgumentError if the reply is not for GetBatteryLevel" do
33
+ reply_bytes = [2, 0x01, 0].concat(@millivolts_bytes)
34
+
35
+ -> { reply = GetBatteryLevelReply.new(reply_bytes) }.must_raise ArgumentError
36
+ end
37
+ end
38
+
39
+
40
+ end
@@ -0,0 +1,33 @@
1
+ require './spec/helper'
2
+ require './lib/telegrams/commands/direct/replies/get_current_program_name_reply'
3
+
4
+ describe GetCurrentProgramNameReply do
5
+ describe "when creating the reply" do
6
+ before do
7
+ @filename = "foobar.rxe"
8
+
9
+ # null pad out to max length and convert to ASCIIZ bytes
10
+ @filename_bytes = @filename.ljust(20, "\0").unpack('C*')
11
+ @reply_bytes = [2, 0x11, 0].concat(@filename_bytes)
12
+ end
13
+
14
+ it "must parse the filename into the message member" do
15
+ reply = GetCurrentProgramNameReply.new(@reply_bytes)
16
+
17
+ reply.message.must_equal @filename
18
+ end
19
+
20
+ it "must allow access to the message through the program_name member" do
21
+ reply = GetCurrentProgramNameReply.new(@reply_bytes)
22
+
23
+ reply.program_name.must_equal @filename
24
+ end
25
+
26
+ it "must raise an ArgumentError if the reply is not for GetCurrentProgramName" do
27
+ reply_bytes = [2, 0x01, 0].concat(@filename_bytes)
28
+
29
+ -> { reply = GetCurrentProgramNameReply.new(reply_bytes) }.must_raise ArgumentError
30
+ end
31
+ end
32
+
33
+ end