argus 0.0.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|