argus 0.0.0 → 0.3.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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +1 -1
- data/README.md +25 -1
- data/Rakefile +4 -0
- data/lib/argus.rb +5 -0
- data/lib/argus/ardrone_control_modes.rb +14 -0
- data/lib/argus/at_commander.rb +104 -0
- data/lib/argus/cad_type.rb +22 -0
- data/lib/argus/cfields.rb +80 -0
- data/lib/argus/controller.rb +165 -0
- data/lib/argus/drone.rb +62 -0
- data/lib/argus/float_encoding.rb +13 -0
- data/lib/argus/led_animation.rb +48 -0
- data/lib/argus/nav_data.rb +78 -0
- data/lib/argus/nav_monitor.rb +83 -0
- data/lib/argus/nav_option.rb +35 -0
- data/lib/argus/nav_option_checksum.rb +20 -0
- data/lib/argus/nav_option_demo.rb +79 -0
- data/lib/argus/nav_option_unknown.rb +9 -0
- data/lib/argus/nav_option_vision_detect.rb +83 -0
- data/lib/argus/nav_streamer.rb +111 -0
- data/lib/argus/nav_tag.rb +35 -0
- data/lib/argus/null_nav_monitor.rb +13 -0
- data/lib/argus/pave_parser.rb +39 -0
- data/lib/argus/tcp_video_streamer.rb +20 -0
- data/lib/argus/time_queue.rb +62 -0
- data/lib/argus/udp_sender.rb +13 -0
- data/lib/argus/version.rb +10 -0
- data/spec/argus/at_commander_spec.rb +82 -0
- data/spec/argus/controller_spec.rb +149 -0
- data/spec/argus/float_encoding_spec.rb +12 -0
- data/spec/argus/led_animation_spec.rb +21 -0
- data/spec/argus/nav_data_spec.rb +147 -0
- data/spec/argus/nav_option_checksum_spec.rb +21 -0
- data/spec/argus/nav_option_demo_spec.rb +56 -0
- data/spec/argus/nav_option_spec.rb +32 -0
- data/spec/argus/nav_option_unknown_spec.rb +19 -0
- data/spec/argus/nav_option_vision_detect_spec.rb +65 -0
- data/spec/argus/nav_streamer_spec.rb +111 -0
- data/spec/argus/null_nav_monitor_spec.rb +17 -0
- data/spec/argus/time_queue_spec.rb +61 -0
- data/spec/argus/udp_sender_spec.rb +33 -0
- data/spec/spec_helper.rb +13 -0
- metadata +51 -12
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Argus
|
4
|
+
|
5
|
+
describe LedAnimation do
|
6
|
+
describe ".lookup_name" do
|
7
|
+
Then { LedAnimation.lookup_name(3) == :blink_orange }
|
8
|
+
end
|
9
|
+
|
10
|
+
describe ".lookup_value" do
|
11
|
+
Then { LedAnimation.lookup_value(:blink_orange) == 3 }
|
12
|
+
Then { LedAnimation.lookup_value("blink_orange") == 3 }
|
13
|
+
Then { LedAnimation.lookup_value(3) == 3 }
|
14
|
+
Then { LedAnimation.lookup_value("3") == 3 }
|
15
|
+
|
16
|
+
Then { LedAnimation.lookup_value(:unknown) == nil }
|
17
|
+
Then { LedAnimation.lookup_value("UNKNOWN") == nil }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Argus
|
4
|
+
describe NavData do
|
5
|
+
Given(:state_bits) { 0xcf8a0c94 }
|
6
|
+
Given(:seq_num) { 173064 }
|
7
|
+
Given(:vision_flag) { 0 }
|
8
|
+
Given(:raw_header) { Bytes.make_header(state_bits, seq_num, vision_flag) }
|
9
|
+
Given(:raw_nav_bytes) { Bytes.make_nav_data(raw_header) }
|
10
|
+
|
11
|
+
When(:nav_data) { NavData.new(raw_nav_bytes) }
|
12
|
+
|
13
|
+
Then { nav_data.sequence_number == 173064 }
|
14
|
+
Then { nav_data.vision_flag == 0 }
|
15
|
+
|
16
|
+
describe "sequence number" do
|
17
|
+
Given(:seq_num) { 1234 }
|
18
|
+
Then { nav_data.sequence_number == 1234 }
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "vision flag" do
|
22
|
+
Given(:vision_flag) { 1 }
|
23
|
+
Then { nav_data.vision_flag == 1 }
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "state queries" do
|
27
|
+
|
28
|
+
def bit(n)
|
29
|
+
0x00000001 << n
|
30
|
+
end
|
31
|
+
|
32
|
+
# Matcher for handling the mask testing for the state mask.
|
33
|
+
#
|
34
|
+
# Usage:
|
35
|
+
# bit(5).should be_the_mask_for(:method [, off_value, on_value])
|
36
|
+
#
|
37
|
+
# If off_value and on_value are not given, then false/true will
|
38
|
+
# be assumed.
|
39
|
+
#
|
40
|
+
matcher :be_the_mask_for do |method, off_result=false, on_result=true|
|
41
|
+
match do |mask|
|
42
|
+
@msg = "OK"
|
43
|
+
try_alternative(method, 0, off_result) &&
|
44
|
+
try_alternative(method, mask, on_result)
|
45
|
+
end
|
46
|
+
|
47
|
+
failure_message_for_should do |mask|
|
48
|
+
@msg
|
49
|
+
end
|
50
|
+
|
51
|
+
# Try one of the alternatives. Sending method to the navdata
|
52
|
+
# constructed with mask should return teh expected value.
|
53
|
+
def try_alternative(method, mask, expected)
|
54
|
+
raw = Bytes.make_nav_data(Bytes.make_header(mask, 1, 0))
|
55
|
+
nav_data = NavData.new(raw)
|
56
|
+
result = nav_data.send(method)
|
57
|
+
return true if result == expected
|
58
|
+
@msg = "expected mask of 0x#{'%08x' % mask} with #{method}\n" +
|
59
|
+
"to return: #{expected.inspect}\n" +
|
60
|
+
"got: #{result.inspect}"
|
61
|
+
false
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
Then { bit(0).should be_the_mask_for(:flying?) }
|
66
|
+
Then { bit(1).should be_the_mask_for(:video_enabled?) }
|
67
|
+
Then { bit(2).should be_the_mask_for(:vision_enabled?) }
|
68
|
+
Then { bit(3).should be_the_mask_for(:control_algorithm, :euler, :angular_speed) }
|
69
|
+
|
70
|
+
Then { bit(4).should be_the_mask_for(:altitude_control_algorithm_active?) }
|
71
|
+
Then { bit(5).should be_the_mask_for(:start_button_pressed?) }
|
72
|
+
Then { bit(6).should be_the_mask_for(:control_command_ack?) }
|
73
|
+
Then { bit(7).should be_the_mask_for(:camera_ready?) }
|
74
|
+
|
75
|
+
Then { bit(8).should be_the_mask_for(:travelling_enabled?) }
|
76
|
+
Then { bit(9).should be_the_mask_for(:usb_ready?) }
|
77
|
+
Then { bit(10).should be_the_mask_for(:mode, :all, :demo) }
|
78
|
+
Then { bit(11).should be_the_mask_for(:bootstrap?) }
|
79
|
+
|
80
|
+
Then { bit(12).should be_the_mask_for(:moter_problem?) }
|
81
|
+
Then { bit(13).should be_the_mask_for(:communication_lost?) }
|
82
|
+
Then { bit(14).should be_the_mask_for(:software_fault?) }
|
83
|
+
Then { bit(15).should be_the_mask_for(:low_battery?) }
|
84
|
+
|
85
|
+
Then { bit(16).should be_the_mask_for(:emergency_landing_requested?) }
|
86
|
+
Then { bit(17).should be_the_mask_for(:timer_elapsed?) }
|
87
|
+
Then { bit(18).should be_the_mask_for(:magnometer_needs_calibration?) }
|
88
|
+
Then { bit(19).should be_the_mask_for(:angles_out_of_range?) }
|
89
|
+
|
90
|
+
Then { bit(20).should be_the_mask_for(:too_much_wind?) }
|
91
|
+
Then { bit(21).should be_the_mask_for(:ultrasonic_sensor_deaf?) }
|
92
|
+
Then { bit(22).should be_the_mask_for(:cutout_detected?) }
|
93
|
+
Then { bit(23).should be_the_mask_for(:pic_version_number_ok?) }
|
94
|
+
|
95
|
+
Then { bit(24).should be_the_mask_for(:at_codec_thread_on?) }
|
96
|
+
Then { bit(25).should be_the_mask_for(:navdata_thread_on?) }
|
97
|
+
Then { bit(26).should be_the_mask_for(:video_thread_on?) }
|
98
|
+
Then { bit(27).should be_the_mask_for(:acquisition_thread_on?) }
|
99
|
+
|
100
|
+
Then { bit(28).should be_the_mask_for(:control_watchdog_delayed?) }
|
101
|
+
Then { bit(29).should be_the_mask_for(:adc_watchdog_delayed?) }
|
102
|
+
Then { bit(30).should be_the_mask_for(:com_watchdog_problem?) }
|
103
|
+
Then { bit(31).should be_the_mask_for(:emergency_landing?) }
|
104
|
+
end
|
105
|
+
|
106
|
+
describe "state mask" do
|
107
|
+
context "all zeros" do
|
108
|
+
Given(:state_bits) { 0 }
|
109
|
+
Then { nav_data.state_mask == state_bits }
|
110
|
+
end
|
111
|
+
|
112
|
+
context "non-zero" do
|
113
|
+
Given(:state_bits) { 12345 }
|
114
|
+
Then { nav_data.state_mask == state_bits }
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe "#options" do
|
119
|
+
Then { nav_data.options.size == 1 }
|
120
|
+
Then { nav_data.options.first.is_a?(NavOptionChecksum) }
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "multiple options" do
|
125
|
+
context "with good data" do
|
126
|
+
Given(:raw_header) { Bytes.make_header(0, 0, 0) }
|
127
|
+
Given(:raw_nav_bytes) {
|
128
|
+
Bytes.make_nav_data(raw_header, Bytes.make_demo_data)
|
129
|
+
}
|
130
|
+
When(:nav_data) { NavData.new(raw_nav_bytes) }
|
131
|
+
Then { nav_data.options.size == 2 }
|
132
|
+
Then { nav_data.options[0].is_a?(NavOptionDemo) }
|
133
|
+
Then { nav_data.options[1].is_a?(NavOptionChecksum) }
|
134
|
+
end
|
135
|
+
|
136
|
+
context "with short data" do
|
137
|
+
Given(:raw_nav_bytes) {
|
138
|
+
Bytes.make_header(0, 0, 0).pack("C*") +
|
139
|
+
[4321, 100, 0].pack("vvV")
|
140
|
+
}
|
141
|
+
When(:nav_data) { NavData.new(raw_nav_bytes) }
|
142
|
+
Then { nav_data.options.size == 1 }
|
143
|
+
Then { nav_data.options[0].is_a?(NavOptionUnknown) }
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Argus
|
4
|
+
|
5
|
+
describe NavOptionChecksum do
|
6
|
+
Given(:raw_data) { [NavTag::CHECKSUM, 8, 0x12345678].pack("vvV") }
|
7
|
+
Given(:csum) { NavOptionChecksum.new(raw_data) }
|
8
|
+
|
9
|
+
describe ".tag" do
|
10
|
+
Then { NavOptionChecksum.tag == NavTag::CHECKSUM }
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "data fields" do
|
14
|
+
Then { csum.tag == NavOptionChecksum.tag }
|
15
|
+
Then { csum.size == raw_data.size }
|
16
|
+
Then { csum.chks == 0x12345678 }
|
17
|
+
Then { csum.checksum == 0x12345678 }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'base64'
|
3
|
+
|
4
|
+
module Argus
|
5
|
+
describe NavOptionDemo do
|
6
|
+
def f(float)
|
7
|
+
FloatEncoding.encode_float(float)
|
8
|
+
end
|
9
|
+
|
10
|
+
# NOTE: This is a Base 64 encoded NavData packet recorded directly from the drone.
|
11
|
+
Given(:base64_data) {
|
12
|
+
"iHdmVdAEgA/5iwAAAAAAAAAAlAAAAAIAPAAAAADwREUAgCNFQFEiyAAAAABk" +
|
13
|
+
"AAAAZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
14
|
+
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0AAADWP3i/6kNxPniCg72IpXO+64R4" +
|
15
|
+
"v+kAAD2hLGG9u7U6PatYfz8AAAAAAAAAAAAAdcMQAEgBAAAAAAAAAAAAAAAA" +
|
16
|
+
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
17
|
+
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
18
|
+
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
19
|
+
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
20
|
+
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
21
|
+
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
22
|
+
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8I" +
|
23
|
+
"ANQdAAA="
|
24
|
+
}
|
25
|
+
Given(:raw_data) { Base64.decode64(base64_data) }
|
26
|
+
Given(:nav_data) { NavData.new(raw_data) }
|
27
|
+
|
28
|
+
When(:demo) { nav_data.options.first }
|
29
|
+
|
30
|
+
Then { ! demo.nil? }
|
31
|
+
Then { demo.tag == Argus::NavTag::DEMO }
|
32
|
+
Then { demo.size == 148 }
|
33
|
+
|
34
|
+
Then { demo.ctrl_state == 0x20000 }
|
35
|
+
Then { demo.control_state_name == :default }
|
36
|
+
Then { demo.vbat_flying_percentage == 60 }
|
37
|
+
Then { demo.battery_level == 60 }
|
38
|
+
Then { demo.theta == 3151.0 }
|
39
|
+
Then { demo.phi == 2616.0 }
|
40
|
+
Then { demo.psi == -166213.0 }
|
41
|
+
Then { demo.pitch == 3.151 }
|
42
|
+
Then { demo.roll == 2.616 }
|
43
|
+
Then { demo.yaw == -166.213 }
|
44
|
+
Then { demo.altitude == 0 }
|
45
|
+
Then { demo.vx == about(0).delta(0.00000001) }
|
46
|
+
Then { demo.vy == about(0).delta(0.00000001) }
|
47
|
+
Then { demo.vz == about(0).delta(0.00000001) }
|
48
|
+
Then { demo.detection_camera_rot }
|
49
|
+
Then { demo.detection_camera_trans }
|
50
|
+
Then { demo.detection_tag_index == 0 }
|
51
|
+
Then { demo.detection_camera_type == 13 }
|
52
|
+
Then { demo.drone_camera_rot }
|
53
|
+
Then { demo.drone_camera_trans }
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Argus
|
4
|
+
describe NavOption do
|
5
|
+
let(:raw_checksum) { [ NavTag::CHECKSUM, 8, 0x5555aaaa].pack("vvV") }
|
6
|
+
let(:raw_demo) { [ NavTag::DEMO, 148 ].pack("vv") + "\0" * 148 }
|
7
|
+
let(:raw_vision_detect) { [ NavTag::VISION_DETECT, 328 ].pack("vv") + "\0" * 328 }
|
8
|
+
let(:raw_unknown_tag) { [ 12345, 8 ].pack("vv") + " " }
|
9
|
+
|
10
|
+
When(:result) { NavOption.parse(raw_data) }
|
11
|
+
|
12
|
+
describe "parsing checksum options" do
|
13
|
+
Given(:raw_data) { raw_checksum }
|
14
|
+
Then { result.is_a?(NavOptionChecksum) }
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "parsing demo option" do
|
18
|
+
Given(:raw_data) { raw_demo }
|
19
|
+
Then { result.is_a?(NavOptionDemo) }
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "parsing vision detect option" do
|
23
|
+
Given(:raw_data) { raw_vision_detect }
|
24
|
+
Then { result.is_a?(NavOptionVisionDetect) }
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "parsing bad tag" do
|
28
|
+
Given(:raw_data) { raw_unknown_tag }
|
29
|
+
Then { result.is_a?(NavOptionUnknown) }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Argus
|
4
|
+
|
5
|
+
describe NavOptionUnknown do
|
6
|
+
Given(:raw_data) { [0x5231, 8, 0x12345678].pack("vvV") }
|
7
|
+
Given(:opt) { NavOptionUnknown.new(raw_data) }
|
8
|
+
|
9
|
+
describe ".tag" do
|
10
|
+
Then { NavOptionUnknown.tag == 0xfffe }
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "data fields" do
|
14
|
+
Then { opt.tag == 0x5231 }
|
15
|
+
Then { opt.size == raw_data.size }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Argus
|
4
|
+
|
5
|
+
describe NavOptionVisionDetect do
|
6
|
+
def f(float)
|
7
|
+
FloatEncoding.encode_float(float)
|
8
|
+
end
|
9
|
+
|
10
|
+
Given(:raw_data) {
|
11
|
+
[
|
12
|
+
NavTag::VISION_DETECT, 328,
|
13
|
+
2,
|
14
|
+
1, 2, 3, 4,
|
15
|
+
10, 11, 12, 13,
|
16
|
+
20, 21, 22, 23,
|
17
|
+
30, 31, 32, 33,
|
18
|
+
40, 41, 42, 43,
|
19
|
+
50, 51, 52, 53,
|
20
|
+
f(60.0), f(61.0), f(62.0), f(63.0),
|
21
|
+
0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,
|
22
|
+
0,0,0, 0,0,0, 0,0,0, 0,0,0,
|
23
|
+
70, 71, 72, 73
|
24
|
+
].flatten.pack("vv V V4 V4 V4 V4 V4 V4 V4 V36 V12 V4")
|
25
|
+
}
|
26
|
+
|
27
|
+
When(:detect) { NavOptionVisionDetect.new(raw_data) }
|
28
|
+
|
29
|
+
Then { NavOptionVisionDetect.tag == NavTag::VISION_DETECT }
|
30
|
+
Then { detect.tag == Argus::NavTag::VISION_DETECT }
|
31
|
+
Then { detect.size == 328 }
|
32
|
+
|
33
|
+
describe "C fields" do
|
34
|
+
Then { detect.nb_detected == 2 }
|
35
|
+
Then { detect.type == [1, 2, 3, 4] }
|
36
|
+
Then { detect.type_name == [:vertical, :vision, :none, :cocarde] }
|
37
|
+
Then { detect.xc == [10, 11, 12, 13] }
|
38
|
+
Then { detect.yc == [20, 21, 22, 23] }
|
39
|
+
Then { detect.width == [30, 31, 32, 33] }
|
40
|
+
Then { detect.height == [40, 41, 42, 43] }
|
41
|
+
Then { detect.dist == [50, 51, 52, 53] }
|
42
|
+
Then { detect.distance == [50, 51, 52, 53] }
|
43
|
+
Then { detect.orientation_angle == [60.0, 61.0, 62.0, 63.0] }
|
44
|
+
Then { detect.rotation.size == 9 * 4 }
|
45
|
+
Then { detect.translation.size == 3 * 4 }
|
46
|
+
Then { detect.camera_source == [70, 71, 72, 73] }
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "detection info" do
|
50
|
+
Then { detect.detections.size == 2 }
|
51
|
+
|
52
|
+
let(:d0) { detect.detections[0] }
|
53
|
+
Then { d0.type == 1 }
|
54
|
+
Then { d0.type_name == :vertical }
|
55
|
+
Then { d0.x == 10 }
|
56
|
+
Then { d0.y == 20 }
|
57
|
+
Then { d0.width == 30 }
|
58
|
+
Then { d0.height == 40 }
|
59
|
+
Then { d0.orientation_angle == 60.0 }
|
60
|
+
Then { d0.camera_source == 70 }
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Argus
|
4
|
+
describe NavStreamer do
|
5
|
+
Given(:remote_host) { '192.168.1.1' }
|
6
|
+
Given(:port) { 5554 }
|
7
|
+
Given(:socket) { flexmock("Socket", send: nil).should_ignore_missing }
|
8
|
+
Given(:streamer) { NavStreamer.new(remote_host: remote_host, UDPSocket: flexmock(new: socket)) }
|
9
|
+
|
10
|
+
context "after starting" do
|
11
|
+
Given { streamer.start }
|
12
|
+
|
13
|
+
context "when receiving good data" do
|
14
|
+
Given(:bytes) { Bytes.make_nav_data(Bytes.make_header(0x1234, 0, 0)) }
|
15
|
+
Given { socket.should_receive(recvfrom: bytes) }
|
16
|
+
When(:nav_data) { streamer.receive_data }
|
17
|
+
Then { nav_data.state_mask == 0x1234}
|
18
|
+
end
|
19
|
+
|
20
|
+
context "when receiving bad data" do
|
21
|
+
Given(:bytes) { [0x89, 0x77, 0x66, 0x55, 0x34, 0x12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0].pack("C*") }
|
22
|
+
Given { socket.should_receive(:recvfrom => bytes) }
|
23
|
+
When(:nav_data) { streamer.receive_data }
|
24
|
+
Then { nav_data.nil? }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "State Transitions" do
|
29
|
+
Given {
|
30
|
+
flexmock(streamer, reconnect: nil, request_nav_data: nil)
|
31
|
+
}
|
32
|
+
|
33
|
+
def goto_wait
|
34
|
+
streamer.start
|
35
|
+
end
|
36
|
+
|
37
|
+
def goto_run
|
38
|
+
streamer.start
|
39
|
+
streamer.received_data
|
40
|
+
end
|
41
|
+
|
42
|
+
context "when init & start" do
|
43
|
+
Given { streamer.start }
|
44
|
+
Then { streamer.should have_received(:reconnect).once }
|
45
|
+
Then { streamer.state == :wait }
|
46
|
+
end
|
47
|
+
|
48
|
+
context "when init & short_timeout" do
|
49
|
+
Given { streamer.short_timeout }
|
50
|
+
Then { streamer.should have_received(:reconnect).never }
|
51
|
+
Then { streamer.should have_received(:request_nav_data).never }
|
52
|
+
Then { streamer.state == :init }
|
53
|
+
end
|
54
|
+
|
55
|
+
context "when init & long_timeout" do
|
56
|
+
Given { streamer.long_timeout }
|
57
|
+
Then { streamer.should have_received(:reconnect).never }
|
58
|
+
Then { streamer.should have_received(:request_nav_data).never }
|
59
|
+
Then { streamer.state == :init }
|
60
|
+
end
|
61
|
+
|
62
|
+
context "when wait & received_data" do
|
63
|
+
Given { goto_wait }
|
64
|
+
Given { streamer.received_data }
|
65
|
+
Then { streamer.should have_received(:reconnect).once }
|
66
|
+
Then { streamer.should have_received(:request_nav_data).never }
|
67
|
+
Then { streamer.state == :run }
|
68
|
+
end
|
69
|
+
|
70
|
+
context "when wait & short_timeout" do
|
71
|
+
Given { goto_wait }
|
72
|
+
Given { streamer.short_timeout }
|
73
|
+
Then { streamer.should have_received(:reconnect).once }
|
74
|
+
Then { streamer.should have_received(:request_nav_data).once }
|
75
|
+
Then { streamer.state == :wait }
|
76
|
+
end
|
77
|
+
|
78
|
+
context "when wait & long_timeout" do
|
79
|
+
Given { goto_wait }
|
80
|
+
Given { streamer.long_timeout }
|
81
|
+
Then { streamer.should have_received(:reconnect).twice }
|
82
|
+
Then { streamer.should have_received(:request_nav_data).never }
|
83
|
+
Then { streamer.state == :wait }
|
84
|
+
end
|
85
|
+
|
86
|
+
context "when run & received_data" do
|
87
|
+
Given { goto_run }
|
88
|
+
Given { streamer.received_data }
|
89
|
+
Then { streamer.should have_received(:reconnect).once }
|
90
|
+
Then { streamer.should have_received(:request_nav_data).never }
|
91
|
+
Then { streamer.state == :run }
|
92
|
+
end
|
93
|
+
|
94
|
+
context "when run & short_timeout" do
|
95
|
+
Given { goto_run }
|
96
|
+
Given { streamer.short_timeout }
|
97
|
+
Then { streamer.should have_received(:reconnect).once }
|
98
|
+
Then { streamer.should have_received(:request_nav_data).never }
|
99
|
+
Then { streamer.state == :run }
|
100
|
+
end
|
101
|
+
|
102
|
+
context "when run & long_timeout" do
|
103
|
+
Given { goto_run }
|
104
|
+
Given { streamer.long_timeout }
|
105
|
+
Then { streamer.should have_received(:reconnect).twice }
|
106
|
+
Then { streamer.should have_received(:request_nav_data).never }
|
107
|
+
Then { streamer.state == :wait }
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|