cosmos 4.4.0-java → 4.4.1-java

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.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/.dockerignore +2 -0
  3. data/.gitignore +1 -0
  4. data/.travis.yml +6 -6
  5. data/Dockerfile +65 -0
  6. data/Manifest.txt +12 -2
  7. data/README.md +5 -0
  8. data/Rakefile +52 -0
  9. data/appveyor.yml +18 -8
  10. data/autohotkey/config/tools/cmd_sequence/cmd_sequence.txt +2 -0
  11. data/autohotkey/lib/cmd_sequence_exporter.rb +52 -0
  12. data/autohotkey/procedures/collect.rb +2 -2
  13. data/autohotkey/procedures/collect_util.rb +1 -1
  14. data/autohotkey/procedures/script_test.rb +1 -1
  15. data/autohotkey/tools/CmdSenderAHK2 +18 -0
  16. data/autohotkey/tools/cmd_sender.ahk +34 -6
  17. data/autohotkey/tools/cmd_sender2.ahk +4 -0
  18. data/autohotkey/tools/cmd_sequence.ahk +21 -8
  19. data/autohotkey/tools/config_editor.ahk +4 -4
  20. data/bin/cstol_converter +1 -1
  21. data/cosmos.gemspec +1 -1
  22. data/data/config/command_modifiers.yaml +16 -1
  23. data/data/config/param_item_modifiers.yaml +5 -0
  24. data/data/config/system.yaml +31 -1
  25. data/data/config/telemetry_modifiers.yaml +16 -1
  26. data/data/crc.txt +415 -410
  27. data/demo/config/dart/Gemfile +1 -6
  28. data/demo/config/data/crc.txt +244 -243
  29. data/demo/config/system/system.txt +3 -0
  30. data/demo/config/system/system2.txt +3 -0
  31. data/demo/config/system/system_alt_ports.txt +3 -0
  32. data/demo/config/targets/INST/cmd_tlm/inst_cmds.txt +3 -3
  33. data/demo/config/targets/INST/cmd_tlm/inst_tlm.txt +4 -0
  34. data/demo/config/targets/INST/cmd_tlm/inst_tlm_override.txt +12 -0
  35. data/demo/config/targets/INST/lib/sim_inst.rb +2 -2
  36. data/demo/config/targets/INST/target.txt +1 -0
  37. data/demo/procedures/cosmos_api_test.rb +8 -8
  38. data/install/config/dart/Gemfile +2 -7
  39. data/install/config/data/crc.txt +143 -143
  40. data/install/config/system/system.txt +3 -0
  41. data/lib/cosmos/dart/config/boot.rb +1 -1
  42. data/lib/cosmos/dart/config/database.yml +2 -0
  43. data/lib/cosmos/dart/lib/dart_common.rb +11 -4
  44. data/lib/cosmos/dart/lib/dart_constants.rb +15 -0
  45. data/lib/cosmos/dart/lib/dart_decom_query.rb +5 -6
  46. data/lib/cosmos/dart/lib/dart_decommutator.rb +66 -56
  47. data/lib/cosmos/dart/lib/dart_master_query.rb +71 -0
  48. data/lib/cosmos/dart/lib/dart_reducer_worker_thread.rb +165 -134
  49. data/lib/cosmos/dart/processes/dart.rb +4 -2
  50. data/lib/cosmos/dart/processes/dart_decom_server.rb +2 -2
  51. data/lib/cosmos/dart/processes/dart_ingester.rb +38 -1
  52. data/lib/cosmos/dart/processes/dart_master.rb +44 -0
  53. data/lib/cosmos/dart/processes/dart_util.rb +115 -0
  54. data/lib/cosmos/gui/widgets/dart_meta_frame.rb +21 -2
  55. data/lib/cosmos/interfaces/protocols/length_protocol.rb +5 -0
  56. data/lib/cosmos/io/json_drb.rb +3 -3
  57. data/lib/cosmos/io/posix_serial_driver.rb +1 -1
  58. data/lib/cosmos/io/win32_serial_driver.rb +23 -2
  59. data/lib/cosmos/packet_logs/packet_log_reader.rb +2 -2
  60. data/lib/cosmos/packets/packet.rb +1 -1
  61. data/lib/cosmos/packets/packet_config.rb +26 -8
  62. data/lib/cosmos/packets/structure.rb +17 -0
  63. data/lib/cosmos/packets/structure_item.rb +5 -1
  64. data/lib/cosmos/packets/telemetry.rb +7 -1
  65. data/lib/cosmos/system/system.rb +115 -48
  66. data/lib/cosmos/tools/cmd_sender/cmd_params.rb +360 -0
  67. data/lib/cosmos/tools/cmd_sender/cmd_sender.rb +23 -319
  68. data/lib/cosmos/tools/cmd_sequence/cmd_sequence.rb +14 -17
  69. data/lib/cosmos/tools/cmd_sequence/sequence_item.rb +43 -331
  70. data/lib/cosmos/tools/cmd_sequence/sequence_list.rb +16 -11
  71. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_gui.rb +1 -0
  72. data/lib/cosmos/tools/config_editor/config_editor.rb +33 -2
  73. data/lib/cosmos/tools/config_editor/config_editor_frame.rb +8 -9
  74. data/lib/cosmos/tools/config_editor/system_config_dialog.rb +158 -0
  75. data/lib/cosmos/tools/script_runner/script_runner_frame.rb +2 -2
  76. data/lib/cosmos/tools/test_runner/test.rb +5 -2
  77. data/lib/cosmos/tools/test_runner/test_runner.rb +2 -2
  78. data/lib/cosmos/tools/tlm_extractor/tlm_extractor_processor.rb +17 -13
  79. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_dart_thread.rb +20 -16
  80. data/lib/cosmos/tools/tlm_grapher/tlm_grapher.rb +18 -11
  81. data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +16 -5
  82. data/lib/cosmos/utilities/ruby_lex_utils.rb +34 -30
  83. data/lib/cosmos/version.rb +4 -4
  84. data/lib/cosmos/win32/excel.rb +23 -17
  85. data/run_gui_tests.bat +1 -0
  86. data/spec/core_ext/socket_spec.rb +1 -1
  87. data/spec/install/yaml_docs_spec.rb +26 -6
  88. data/spec/interfaces/protocols/length_protocol_spec.rb +39 -0
  89. data/spec/io/json_drb_spec.rb +14 -0
  90. data/spec/io/win32_serial_driver_spec.rb +16 -2
  91. data/spec/packet_logs/packet_log_reader_spec.rb +2 -2
  92. data/spec/packets/structure_spec.rb +52 -2
  93. data/spec/packets/telemetry_spec.rb +29 -1
  94. data/spec/system/system_spec.rb +2 -2
  95. data/spec/utilities/message_log_spec.rb +6 -3
  96. data/tasks/gemfile_stats.rake +22 -13
  97. metadata +15 -5
  98. data/lib/cosmos/dart/Gemfile +0 -69
@@ -73,17 +73,24 @@ module Cosmos
73
73
  target_name.upcase!
74
74
  packet_name.upcase!
75
75
  item_name.upcase!
76
- # Check to see if the item name is followed by an array index,
77
- # notated by square brackets around an integer; i.e. ARRAY_ITEM[1]
78
- if (item_name =~ /\[\d+\]$/)
79
- # We found an array index.
80
- # The $` special variable is the string before the regex match, i.e. ARRAY_ITEM
81
- item_name = $`
82
- # The $& special variable is the string matched by the regex, i.e. [1].
83
- # Strip off the brackets and then convert the array index to an integer.
84
- item_array_index = $&.gsub(/[\[\]]/, "").to_i
85
- else
86
- item_array_index = nil
76
+
77
+ item_array_index = nil
78
+ begin
79
+ # See if we can access the item
80
+ _, item = System.telemetry.packet_and_item(target_name, packet_name, item_name)
81
+ rescue => error
82
+ # Check to see if the item name is followed by an array index,
83
+ # notated by square brackets around an integer; i.e. ARRAY_ITEM[1]
84
+ if (item_name =~ /\[\d+\]$/)
85
+ # The $` special variable is the string before the regex match, i.e. ARRAY_ITEM
86
+ item_name = $`
87
+ # The $& special variable is the string matched by the regex, i.e. [1].
88
+ # Strip off the brackets and then convert the array index to an integer.
89
+ item_array_index = $&.gsub(/[\[\]]/, "").to_i
90
+ else
91
+ # If we couldn't access the item and it's not bracket notation then it's an error
92
+ raise error
93
+ end
87
94
  end
88
95
  # Default configuration has one plot so don't add plot for first item
89
96
  data_object = HousekeepingDataObject.new
@@ -53,6 +53,12 @@ module Cosmos
53
53
  @@instance = nil
54
54
 
55
55
  def self.instance
56
+ unless @@instance
57
+ _, options = create_default_options()
58
+ options.listen = false
59
+ options.show_main = false
60
+ TlmViewer.new(options)
61
+ end
56
62
  @@instance
57
63
  end
58
64
 
@@ -118,12 +124,14 @@ module Cosmos
118
124
 
119
125
  Splash.execute(self) do |splash|
120
126
  ConfigParser.splash = splash
121
- splash.message = "Displaying requested screens"
127
+ if options.show_main
128
+ splash.message = "Displaying requested screens"
122
129
 
123
- # Startup desired screens once we're running
124
- @tlm_viewer_config.screen_infos.each do |screen_full_name, screen_info|
125
- if screen_info.show_on_startup
126
- display(screen_full_name, screen_info.x_pos, screen_info.y_pos)
130
+ # Startup desired screens once we're running
131
+ @tlm_viewer_config.screen_infos.each do |screen_full_name, screen_info|
132
+ if screen_info.show_on_startup
133
+ display(screen_full_name, screen_info.x_pos, screen_info.y_pos)
134
+ end
127
135
  end
128
136
  end
129
137
 
@@ -163,6 +171,8 @@ module Cosmos
163
171
 
164
172
  ConfigParser.splash = nil
165
173
  end
174
+
175
+ hide() unless options.show_main
166
176
  end
167
177
 
168
178
  def initialize_actions
@@ -551,6 +561,7 @@ module Cosmos
551
561
  options.title = 'Telemetry Viewer'
552
562
  options.screen = nil
553
563
  options.listen = true
564
+ options.show_main = true
554
565
  options.restore_size = false
555
566
  options.production = false
556
567
  options.replay = false
@@ -45,41 +45,45 @@ class RubyLex
45
45
  @exception_on_syntax_error = true
46
46
  @prompt = nil
47
47
  end
48
+
49
+ # Monkey patch to keep this from looping forever if the string never is closed with a right brace
50
+ def identify_string_dvar
51
+ begin
52
+ getc
48
53
 
49
- # Monkey patch to fix performance issue caused by call to reverse
50
- def get_readed
51
- if idx = @readed.rindex("\n")
52
- @base_char_no = @readed.size - (idx + 1)
53
- else
54
- @base_char_no += @readed.size
55
- end
54
+ reserve_continue = @continue
55
+ reserve_ltype = @ltype
56
+ reserve_indent = @indent
57
+ reserve_indent_stack = @indent_stack
58
+ reserve_state = @lex_state
59
+ reserve_quoted = @quoted
56
60
 
57
- readed = @readed.join("")
58
- @readed = []
59
- readed
60
- end
61
+ @ltype = nil
62
+ @quoted = nil
63
+ @indent = 0
64
+ @indent_stack = []
65
+ @lex_state = EXPR_BEG
61
66
 
62
- # Monkey patch to fix performance issue caused by call to reverse
63
- def ungetc(c = nil)
64
- if @here_readed.empty?
65
- c2 = @readed.pop
66
- else
67
- c2 = @here_readed.pop
68
- end
69
- c = c2 unless c
70
- @rests.unshift c #c =
71
- @seek -= 1
72
- if c == "\n"
73
- @line_no -= 1
74
- if idx = @readed.rindex("\n")
75
- @char_no = idx + 1
76
- else
77
- @char_no = @base_char_no + @readed.size
67
+ loop do
68
+ @continue = false
69
+ prompt
70
+ tk = token
71
+ break if tk.nil? # This is the patch
72
+ if @ltype or @continue or @indent >= 0
73
+ next
74
+ end
75
+ break if tk.kind_of?(TkRBRACE)
78
76
  end
79
- else
80
- @char_no -= 1
77
+ ensure
78
+ @continue = reserve_continue
79
+ @ltype = reserve_ltype
80
+ @indent = reserve_indent
81
+ @indent_stack = reserve_indent_stack
82
+ @lex_state = reserve_state
83
+ @quoted = reserve_quoted
81
84
  end
82
- end
85
+ end
86
+
83
87
  end
84
88
  $VERBOSE = old_verbose
85
89
 
@@ -1,12 +1,12 @@
1
1
  # encoding: ascii-8bit
2
2
 
3
- COSMOS_VERSION = '4.4.0'
3
+ COSMOS_VERSION = '4.4.1'
4
4
  module Cosmos
5
5
  module Version
6
6
  MAJOR = '4'
7
7
  MINOR = '4'
8
- PATCH = '0'
9
- BUILD = '30bd354efce074e6684f2fb4f4df8dc12d2f3df5'
8
+ PATCH = '1'
9
+ BUILD = 'f8e9c89b2d7fcd0c558806ff6c9dd59d167786e4'
10
10
  end
11
- VERSION = '4.4.0'
11
+ VERSION = '4.4.1'
12
12
  end
@@ -31,8 +31,10 @@ module Cosmos
31
31
 
32
32
  # Build a lookup table based on the first column
33
33
  @lkup = {}
34
- @data.each do |row|
35
- @lkup[row[0]] = row[1..-1]
34
+ if @data
35
+ @data.each do |row|
36
+ @lkup[row[0]] = row[1..-1]
37
+ end
36
38
  end
37
39
  end
38
40
 
@@ -70,23 +72,27 @@ module Cosmos
70
72
  File.chmod(0444, archive) # Mark read-only
71
73
  end
72
74
 
73
- excel = WIN32OLE.new('excel.application')
74
- excel.visible = false
75
- wb = excel.workbooks.open(filename)
75
+ begin
76
+ excel = WIN32OLE.new('excel.application')
77
+ excel.visible = false
78
+ wb = excel.workbooks.open(filename)
76
79
 
77
- @worksheets = []
78
- @lkup = {}
79
- count = wb.worksheets.count
80
- count.times do |index|
81
- ws = wb.worksheets(index + 1)
82
- @worksheets << ExcelWorksheet.new(ws)
83
- @lkup[ws.name] = @worksheets[-1]
80
+ @worksheets = []
81
+ @lkup = {}
82
+ count = wb.worksheets.count
83
+ count.times do |index|
84
+ ws = wb.worksheets(index + 1)
85
+ @worksheets << ExcelWorksheet.new(ws)
86
+ @lkup[ws.name] = @worksheets[-1]
87
+ end
88
+ ensure
89
+ if excel
90
+ excel.DisplayAlerts = false
91
+ excel.quit
92
+ end
93
+ excel = nil
94
+ GC.start
84
95
  end
85
-
86
- excel.DisplayAlerts = false
87
- excel.quit
88
- excel = nil
89
- GC.start
90
96
  end
91
97
 
92
98
  # @return [Array<String>] Array of all the worksheet names
@@ -1,5 +1,6 @@
1
1
  call bundle exec ruby autohotkey\tools\CmdExtractorAHK --defaultsize
2
2
  call bundle exec ruby autohotkey\tools\CmdSenderAHK -w 650 -t 650
3
+ call bundle exec ruby autohotkey\tools\CmdSenderAHK2 -w 650 -t 650 -p "INST COLLECT" --production
3
4
  call bundle exec ruby autohotkey\tools\CmdSequenceAHK -w 650 -t 650
4
5
  call bundle exec ruby autohotkey\tools\CmdSequenceAHK2 -w 650 -t 650 -r run_sequence.txt -o procedures
5
6
  call bundle exec ruby autohotkey\tools\CmdTlmServerAHK -x 50 -y 50 -w 900 -t 1000
@@ -27,7 +27,7 @@ describe Socket do
27
27
  it "returns the hostname for the ip address" do
28
28
  if !ENV['APPVEYOR']
29
29
  ipaddr = Resolv.getaddress "localhost"
30
- expect(Socket.lookup_hostname_from_ip(ipaddr)).to match("localhost")
30
+ expect(Socket.lookup_hostname_from_ip(ipaddr)).to_not be_nil
31
31
  end
32
32
  end
33
33
  end
@@ -15,6 +15,25 @@ module Cosmos
15
15
  OPENGL = %w(STL_FILE TEXTURE_MAPPED_SPHERE TIP_TEXT POSITION ROTATION_X ROTATION_Y ROTATION_Z)
16
16
  OPENGL.concat(%w(ZOOM ORIENTATION CENTER BOUNDS))
17
17
 
18
+ def process_line(line)
19
+ line.split(',').each do |item|
20
+ item.strip!
21
+ if (item[0] == "'" || item[0] == '"') && (item[-1] == "'" || item[-1] == '"')
22
+ @src_keywords << item[1..-2]
23
+ end
24
+ end
25
+ end
26
+
27
+ def process_continuation(line)
28
+ if line[-1] == "\\"
29
+ continuation = true
30
+ line = line[0..-2] # remove the continuation character
31
+ else
32
+ continuation = false
33
+ end
34
+ return continuation
35
+ end
36
+
18
37
  def get_src_keywords
19
38
  @src_keywords = []
20
39
  path = File.expand_path(File.join(File.dirname(__FILE__), "../../lib/**/*.rb"))
@@ -27,15 +46,16 @@ module Cosmos
27
46
  part = data.split('handle_keyword(parser, keyword, parameters)')[1..-1].join
28
47
  end
29
48
  if part
49
+ continuation = false
30
50
  part.split("\n").each do |line|
51
+ if continuation
52
+ continuation = process_continuation(line)
53
+ process_line(line)
54
+ end
31
55
  if match = line.match(/when (.*)/)
32
56
  line = match.captures[0]
33
- line.split(',').each do |item|
34
- item.strip!
35
- if (item[0] == "'" || item[0] == '"') && (item[-1] == "'" || item[-1] == '"')
36
- @src_keywords << item[1..-2]
37
- end
38
- end
57
+ continuation = process_continuation(line)
58
+ process_line(line)
39
59
  end
40
60
  end
41
61
  end
@@ -160,6 +160,45 @@ module Cosmos
160
160
  expect(packet.buffer.length).to eql 5
161
161
  end
162
162
 
163
+ it "raises an error with a packet length of 0" do
164
+ @interface.instance_variable_set(:@stream, LengthStream.new)
165
+ @interface.add_protocol(LengthProtocol, [
166
+ 16, # bit offset
167
+ 16, # bit size
168
+ 0, # length offset
169
+ 1, # bytes per count
170
+ 'BIG_ENDIAN'], :READ_WRITE)
171
+ $buffer = "\x00\x01\x00\x00\x03\x04\x05\x06\x07\x08\x09"
172
+ expect { @interface.read }.to raise_error(RuntimeError, /Calculated packet length of 0 bits/)
173
+ end
174
+
175
+ it "raises an error if packet length not enough to support offset and size" do
176
+ @interface.instance_variable_set(:@stream, LengthStream.new)
177
+ @interface.add_protocol(LengthProtocol, [
178
+ 16, # bit offset
179
+ 16, # bit size
180
+ 3, # length offset of 3 not enough to support 2 byte length field at offset 2 bytes
181
+ 1, # bytes per count
182
+ 'BIG_ENDIAN'], :READ_WRITE)
183
+ $buffer = "\x00\x01\x00\x00\x03\x04\x05\x06\x07\x08\x09"
184
+ expect { @interface.read }.to raise_error(RuntimeError, /Calculated packet length of 24 bits/)
185
+ end
186
+
187
+ it "processes a 0 length with a non-zero length offset" do
188
+ @interface.instance_variable_set(:@stream, LengthStream.new)
189
+ @interface.add_protocol(LengthProtocol, [
190
+ 0, # bit offset
191
+ 16, # bit size
192
+ 4, # length offset
193
+ 1, # bytes per count
194
+ 'BIG_ENDIAN'], :READ_WRITE)
195
+ $buffer = "\x00\x00\x01\x02\x00\x00\x03\x04"
196
+ packet = @interface.read
197
+ expect(packet.buffer).to eql "\x00\x00\x01\x02"
198
+ packet = @interface.read
199
+ expect(packet.buffer).to eql "\x00\x00\x03\x04"
200
+ end
201
+
163
202
  it "validates length against the maximum length" do
164
203
  @interface.instance_variable_set(:@stream, LengthStream.new)
165
204
  @interface.add_protocol(LengthProtocol, [
@@ -200,6 +200,20 @@ module Cosmos
200
200
  sleep(0.1)
201
201
  end
202
202
 
203
+ it "processes success requests with uppercase" do
204
+ class MyServer5
205
+ def my_method(param)
206
+ end
207
+ end
208
+
209
+ @json.start_service('127.0.0.1', 7777, MyServer5.new)
210
+ request_data = JsonRpcRequest.new('MY_METHOD', 'param', 1).to_json
211
+ _, error_code = @json.process_request(request_data, Time.now)
212
+ expect(error_code).to eq nil
213
+ @json.stop_service
214
+ sleep(0.1)
215
+ end
216
+
203
217
  it "does not allow dangerous methods" do
204
218
  @json.start_service('127.0.0.1', 7777, self)
205
219
  request_data = JsonRpcRequest.new('send', 'param', 1).to_json
@@ -50,6 +50,22 @@ if RUBY_ENGINE == 'ruby' or Gem.win_platform?
50
50
  expect { Win32SerialDriver.new('COM1',9600,:NONE,1,10,nil,0.01,1000,:NONE,8) }.to_not raise_error
51
51
  expect { Win32SerialDriver.new('COM1',9600,:NONE,1,10,nil,0.01,1000,:NONE,9) }.to raise_error(ArgumentError, "Invalid data bits: 9")
52
52
  end
53
+
54
+ it "calculates the correct timeouts" do
55
+ Win32::BAUD_RATES.each do |baud|
56
+ (5..8).each do |data_bits|
57
+ (1..2).each do |stop_bits|
58
+ [:EVEN, :ODD, :NONE].each do |parity|
59
+ # data_bits + 1 start bit + stop bits + potentially a parity bit
60
+ symbols = data_bits + 1 + stop_bits + (parity == :NONE ? 0 : 1)
61
+ delay = 1000.0 / (baud.to_f / symbols)
62
+ expect(Win32).to receive(:set_comm_timeouts).with(anything, 0xFFFFFFFF,0,0,delay.ceil,1000)
63
+ Win32SerialDriver.new('COM1',baud,parity,stop_bits,10,nil,0.01,1000,:NONE,data_bits)
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
53
69
  end
54
70
 
55
71
  describe "close, closed?" do
@@ -92,8 +108,6 @@ if RUBY_ENGINE == 'ruby' or Gem.win_platform?
92
108
  expect { driver.read }.to raise_error(Timeout::Error)
93
109
  end
94
110
  end
95
-
96
111
  end
97
112
  end
98
-
99
113
  end
@@ -121,7 +121,7 @@ module Cosmos
121
121
  file.write [pkt.buffer.length].pack('N')
122
122
  file.write pkt.buffer
123
123
  end
124
- expect(@plr.open(filename)).to eql [false, nil]
124
+ expect(@plr.open(filename)[0]).to eql false
125
125
  pkt1 = @plr.read
126
126
  expect(pkt1.target_name).to eql 'TGT1'
127
127
  expect(pkt1.packet_name).to eql 'PKT1'
@@ -149,7 +149,7 @@ module Cosmos
149
149
  file.write [pkt.buffer.length].pack('N')
150
150
  file.write pkt.buffer
151
151
  end
152
- expect(@plr.open(filename)).to eql [false, nil]
152
+ expect(@plr.open(filename)[0]).to eql false
153
153
  pkt1 = @plr.read
154
154
  expect(pkt1.target_name).to eql 'TGT1'
155
155
  expect(pkt1.packet_name).to eql 'PKT1'
@@ -185,6 +185,8 @@ module Cosmos
185
185
  expect(@s.defined_length).to eql 1
186
186
  si = StructureItem.new("test1",0,16,:INT,:BIG_ENDIAN)
187
187
  @s.define(si)
188
+ expect(@s.items.length).to eql 1
189
+ expect(@s.sorted_items.length).to eql 1
188
190
  expect(@s.sorted_items[0].name).to eql "TEST1"
189
191
  expect(@s.items["TEST1"].bit_size).to eql 16
190
192
  expect(@s.items["TEST1"].data_type).to eql :INT
@@ -290,6 +292,56 @@ module Cosmos
290
292
  end
291
293
  end
292
294
 
295
+ describe "delete_item" do
296
+ before(:each) do
297
+ @s = Structure.new(:BIG_ENDIAN)
298
+ @s.define_item("test1", 0, 8, :UINT)
299
+ end
300
+
301
+ it "removes the item and leaves a hole" do
302
+ @s.append_item("test2", 16, :UINT)
303
+ expect(@s.defined_length).to eql 3
304
+ @s.delete_item("test1")
305
+ expect { @s.get_item("test1") }.to raise_error(ArgumentError, "Unknown item: test1")
306
+ expect(@s.defined_length).to eql 3
307
+ expect(@s.items["TEST1"]).to be_nil
308
+ expect(@s.items["TEST2"]).not_to be_nil
309
+ expect(@s.sorted_items.length).to eql 1
310
+ expect(@s.sorted_items[0]).to eql(@s.get_item("test2"))
311
+ buffer = "\x01\x02\x03"
312
+ expect(@s.read("test2", :RAW, buffer)).to eql 0x0203
313
+ end
314
+
315
+ it "allows new items to be defined in place" do
316
+ @s.append_item("test2", 16, :UINT)
317
+ @s.append_item("test3", 8, :UINT)
318
+ expect(@s.defined_length).to eql 4
319
+ # Delete the first 2 items, note a 3 byte hole now exists
320
+ @s.delete_item("test1")
321
+ @s.delete_item("test2")
322
+ expect(@s.defined_length).to eql 4
323
+ expect(@s.items.length).to eql 1
324
+ expect(@s.sorted_items.length).to eql 1
325
+ # Fill the hole and overlap the last byte
326
+ @s.define_item("test4", 0, 16, :UINT)
327
+ @s.define_item("test5", 16, 16, :UINT)
328
+ @s.define_item("test6", 32, 32, :UINT)
329
+ buffer = "\x01\x02\x03\x04\x05\x06\x07\x08"
330
+ expect(@s.read("test4", :RAW, buffer)).to eql 0x0102
331
+ expect(@s.read("test5", :RAW, buffer)).to eql 0x0304
332
+ expect(@s.read("test6", :RAW, buffer)).to eql 0x05060708
333
+ # test3 is still defined
334
+ expect(@s.read("test3", :RAW, buffer)).to eql 0x04
335
+ expect(@s.items.length).to eql 4
336
+ expect(@s.sorted_items.length).to eql 4
337
+ # Check that everything is sorted correctly
338
+ expect(@s.sorted_items[0].name).to eql "TEST4"
339
+ expect(@s.sorted_items[1].name).to eql "TEST5"
340
+ expect(@s.sorted_items[2].name).to eql "TEST3"
341
+ expect(@s.sorted_items[3].name).to eql "TEST6"
342
+ end
343
+ end
344
+
293
345
  describe "read_item" do
294
346
  it "complains if no buffer given" do
295
347
  s = Structure.new
@@ -601,7 +653,5 @@ module Cosmos
601
653
  expect { s.test1 }.to raise_error(ArgumentError, "Unknown item: test1")
602
654
  end
603
655
  end
604
-
605
656
  end # describe Structure
606
-
607
657
  end