rubycom 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +8 -8
  2. data/README.md +162 -146
  3. data/Rakefile +12 -12
  4. data/lib/rubycom.rb +156 -226
  5. data/lib/rubycom/arg_parse.rb +252 -0
  6. data/lib/rubycom/command_interface.rb +97 -0
  7. data/lib/rubycom/completions.rb +62 -0
  8. data/lib/rubycom/error_handler.rb +15 -0
  9. data/lib/rubycom/executor.rb +23 -0
  10. data/lib/rubycom/helpers.rb +98 -0
  11. data/lib/rubycom/output_handler.rb +15 -0
  12. data/lib/rubycom/parameter_extract.rb +262 -0
  13. data/lib/rubycom/singleton_commands.rb +78 -0
  14. data/lib/rubycom/sources.rb +99 -0
  15. data/lib/rubycom/version.rb +1 -1
  16. data/lib/rubycom/yard_doc.rb +146 -0
  17. data/rubycom.gemspec +14 -16
  18. data/test/rubycom/arg_parse_test.rb +247 -0
  19. data/test/rubycom/command_interface_test.rb +293 -0
  20. data/test/rubycom/completions_test.rb +94 -0
  21. data/test/rubycom/error_handler_test.rb +72 -0
  22. data/test/rubycom/executor_test.rb +64 -0
  23. data/test/rubycom/helpers_test.rb +467 -0
  24. data/test/rubycom/output_handler_test.rb +76 -0
  25. data/test/rubycom/parameter_extract_test.rb +141 -0
  26. data/test/rubycom/rubycom_test.rb +290 -548
  27. data/test/rubycom/singleton_commands_test.rb +122 -0
  28. data/test/rubycom/sources_test.rb +59 -0
  29. data/test/rubycom/util_test_bin.rb +8 -0
  30. data/test/rubycom/util_test_composite.rb +23 -20
  31. data/test/rubycom/util_test_module.rb +142 -112
  32. data/test/rubycom/util_test_no_singleton.rb +2 -2
  33. data/test/rubycom/util_test_sub_module.rb +13 -0
  34. data/test/rubycom/yard_doc_test.rb +165 -0
  35. metadata +61 -24
  36. data/lib/rubycom/arguments.rb +0 -133
  37. data/lib/rubycom/commands.rb +0 -63
  38. data/lib/rubycom/documentation.rb +0 -212
  39. data/test/rubycom/arguments_test.rb +0 -289
  40. data/test/rubycom/commands_test.rb +0 -51
  41. data/test/rubycom/documentation_test.rb +0 -186
  42. data/test/rubycom/util_test_job.yaml +0 -21
  43. data/test/rubycom/utility_tester.rb +0 -17
@@ -0,0 +1,64 @@
1
+ require "#{File.dirname(__FILE__)}/../../lib/rubycom/executor.rb"
2
+
3
+ require "#{File.dirname(__FILE__)}/util_test_module.rb"
4
+ require "#{File.dirname(__FILE__)}/util_test_composite.rb"
5
+ require "#{File.dirname(__FILE__)}/util_test_no_singleton.rb"
6
+
7
+ require 'test/unit'
8
+
9
+ class ExecutorTest < Test::Unit::TestCase
10
+
11
+ def capture_out(&block)
12
+ original_stdout = $stdout
13
+ $stdout = fake = StringIO.new
14
+ begin
15
+ yield
16
+ ensure
17
+ $stdout = original_stdout
18
+ end
19
+ fake.string
20
+ end
21
+
22
+ def test_execute_command
23
+ test_command = UtilTestModule.public_method(:test_command_with_return)
24
+ test_parameters = {:test_arg => "testing_argument", :test_option_int => 10}
25
+ result = Rubycom::Executor.execute_command(test_command, test_parameters)
26
+ expected = ["testing_argument", 10]
27
+ assert_equal(expected, result)
28
+ end
29
+
30
+ def test_execute_command_no_args
31
+ test_command = UtilTestModule.public_method(:test_command_with_return)
32
+ test_parameters = {}
33
+ result = nil
34
+ assert_raise(Rubycom::ExecutorError) { result = Rubycom::Executor.execute_command(test_command, test_parameters) }
35
+ expected = nil
36
+ assert_equal(expected, result)
37
+ end
38
+
39
+ def test_execute_command_none_required
40
+ test_command = UtilTestModule.public_method(:test_command)
41
+ test_parameters = {}
42
+ result = capture_out { Rubycom::Executor.execute_command(test_command, test_parameters) }
43
+ expected = "command test\n"
44
+ assert_equal(expected, result)
45
+ end
46
+
47
+ def test_execute_command_missing_missing_arg
48
+ test_command = UtilTestModule.public_method(:test_command_with_options)
49
+ test_parameters = {:test_option => 'testing_opt'}
50
+ result = nil
51
+ assert_raise(Rubycom::ExecutorError) { result = Rubycom::Executor.execute_command(test_command, test_parameters) }
52
+ expected = nil
53
+ assert_equal(expected, result)
54
+ end
55
+
56
+ def test_execute_command_too_many_args
57
+ test_command = UtilTestModule.public_method(:test_command_with_options)
58
+ test_parameters = {:test_arg => "testing_argument", :test_option => 'testing_opt', :test_extra_opt => 'extra'}
59
+ result = capture_out { Rubycom::Executor.execute_command(test_command, test_parameters) }
60
+ expected = "test_arg=testing_argument,test_option=testing_opt\n"
61
+ assert_equal(expected, result)
62
+ end
63
+
64
+ end
@@ -0,0 +1,467 @@
1
+ require "#{File.dirname(__FILE__)}/../../lib/rubycom/helpers.rb"
2
+
3
+ require "#{File.dirname(__FILE__)}/util_test_module.rb"
4
+ require "#{File.dirname(__FILE__)}/util_test_composite.rb"
5
+ require "#{File.dirname(__FILE__)}/util_test_no_singleton.rb"
6
+
7
+ require 'test/unit'
8
+
9
+ class HelpersTest < Test::Unit::TestCase
10
+
11
+ def test_format_tags_nil
12
+ tag_list = nil
13
+ desc_width = 90
14
+ result = Rubycom::Helpers.format_tags(tag_list, desc_width)
15
+ expected = {:others => [], :params => [], :returns => []}
16
+ assert_equal(expected, result)
17
+ end
18
+
19
+ def test_format_tags_empty
20
+ tag_list = []
21
+ desc_width = 90
22
+ result = Rubycom::Helpers.format_tags(tag_list, desc_width)
23
+ expected = {:others => [], :params => [], :returns => []}
24
+ assert_equal(expected, result)
25
+ end
26
+
27
+ def test_format_tags_wrong_type
28
+ tag_list = [[], 1, ""]
29
+ desc_width = 90
30
+ result = nil
31
+ assert_raise(ArgumentError) { result = Rubycom::Helpers.format_tags(tag_list, desc_width) }
32
+ expected = nil
33
+ assert_equal(expected, result)
34
+ end
35
+
36
+ def test_format_tags_incorrect_keys
37
+ tag_list = [{}]
38
+ desc_width = 90
39
+ result = nil
40
+ assert_raise(KeyError) { result = Rubycom::Helpers.format_tags(tag_list, desc_width) }
41
+ expected = nil
42
+ assert_equal(expected, result)
43
+ end
44
+
45
+ def test_format_tags_incorrect_value_types
46
+ tag_list = [
47
+ {name: '', tag_name: '', text: '', types: ''}
48
+ ]
49
+ desc_width = 90
50
+ result = nil
51
+ assert_raise(ArgumentError) { result = Rubycom::Helpers.format_tags(tag_list, desc_width) }
52
+ expected = nil
53
+ assert_equal(expected, result)
54
+ end
55
+
56
+ def test_format_tags_empty_values
57
+ tag_list = [
58
+ {name: '', tag_name: '', text: '', types: []}
59
+ ]
60
+ desc_width = 90
61
+ result = Rubycom::Helpers.format_tags(tag_list, desc_width)
62
+ expected = {
63
+ :others => [" - \n"],
64
+ :params => [],
65
+ :returns => []
66
+ }
67
+ assert_equal(expected, result)
68
+ end
69
+
70
+ def test_format_tags_single_other
71
+ tag_list = [
72
+ {name: 'test_opt', tag_name: 'See Also', text: 'a testing option', types: [String]}
73
+ ]
74
+ desc_width = 90
75
+ result = Rubycom::Helpers.format_tags(tag_list, desc_width)
76
+ expected = {
77
+ :others => ["[String] See Also: test_opt - a testing option\n"],
78
+ :params => [],
79
+ :returns => []
80
+ }
81
+ assert_equal(expected, result)
82
+ end
83
+
84
+ def test_format_tags_single_other_no_types
85
+ tag_list = [
86
+ {name: 'test_opt', tag_name: 'See Also', text: 'a testing option', types: []}
87
+ ]
88
+ desc_width = 90
89
+ result = Rubycom::Helpers.format_tags(tag_list, desc_width)
90
+ expected = {
91
+ :others => ["See Also: test_opt - a testing option\n"],
92
+ :params => [],
93
+ :returns => []
94
+ }
95
+ assert_equal(expected, result)
96
+ end
97
+
98
+ def test_format_tags_single_other_nil_name
99
+ tag_list = [
100
+ {name: nil, tag_name: 'See Also', text: 'a testing option', types: []}
101
+ ]
102
+ desc_width = 90
103
+ result = Rubycom::Helpers.format_tags(tag_list, desc_width)
104
+ expected = {
105
+ :others => [" - a testing option\n"],
106
+ :params => [],
107
+ :returns => []
108
+ }
109
+ assert_equal(expected, result)
110
+ end
111
+
112
+ def test_format_tags_single_param
113
+ tag_list = [
114
+ {name: 'test_opt', tag_name: 'param', text: 'a testing option', types: [String]}
115
+ ]
116
+ desc_width = 90
117
+ result = Rubycom::Helpers.format_tags(tag_list, desc_width)
118
+ expected = {
119
+ :others => [],
120
+ :params => ["[String] test_opt - a testing option\n"],
121
+ :returns => []
122
+ }
123
+ assert_equal(expected, result)
124
+ end
125
+
126
+ def test_format_tags_single_return
127
+ tag_list = [
128
+ {name: 'test_opt', tag_name: 'return', text: 'a testing option', types: [String]}
129
+ ]
130
+ desc_width = 90
131
+ result = Rubycom::Helpers.format_tags(tag_list, desc_width)
132
+ expected = {
133
+ :others => [],
134
+ :params => [],
135
+ :returns => ["[String] return - a testing option\n"]
136
+ }
137
+ assert_equal(expected, result)
138
+ end
139
+
140
+ def test_format_tags_multi_mixed
141
+ tag_list = [
142
+ {name: 'test_arg', tag_name: 'param', text: 'a testing argument', types: [String]},
143
+ {name: 'test_opt', tag_name: 'param', text: 'a testing option', types: [String]},
144
+ {name: 'test_ret', tag_name: 'return', text: 'a test return', types: [String]},
145
+ {name: 'Other_doc', tag_name: 'SeeAlso', text: 'some more test docs', types: []},
146
+ {name: 'Link', tag_name: 'link', text: 'a neat test link', types: [Object]},
147
+ ]
148
+ desc_width = 90
149
+ result = Rubycom::Helpers.format_tags(tag_list, desc_width)
150
+ expected = {
151
+ :others => [
152
+ "SeeAlso: Other_doc - some more test docs\n",
153
+ "[Object] link: Link - a neat test link\n"
154
+ ],
155
+ :params => [
156
+ "[String] test_arg - a testing argument\n",
157
+ "[String] test_opt - a testing option\n"
158
+ ],
159
+ :returns => [
160
+ "[String] return - a test return\n"
161
+ ]
162
+ }
163
+ assert_equal(expected, result)
164
+ end
165
+
166
+ def test_format_command_list_empty
167
+ command_doc_hsh = {}
168
+ desc_width = 90
169
+ result = Rubycom::Helpers.format_command_list(command_doc_hsh, desc_width)
170
+ expected = []
171
+ assert_equal(expected, result)
172
+ end
173
+
174
+ def test_format_command_list_non_string_values
175
+ tst_obj = Object.new
176
+ command_doc_hsh = {test: 'value', another: [123, {of: 'test'}, [tst_obj]]}
177
+ desc_width = 90
178
+ result = Rubycom::Helpers.format_command_list(command_doc_hsh, desc_width)
179
+ expected = [
180
+ "test - value\n",
181
+ "another - [123, {:of=>\"test\"}, [#{tst_obj}]]\n"
182
+ ]
183
+ assert_equal(expected, result)
184
+ end
185
+
186
+ def test_format_command_list_single
187
+ command_doc_hsh = {test_command: "a simple test command"}
188
+ desc_width = 90
189
+ result = Rubycom::Helpers.format_command_list(command_doc_hsh, desc_width)
190
+ expected = ["test_command - a simple test command\n"]
191
+ assert_equal(expected, result)
192
+ end
193
+
194
+ def test_format_command_list_multi
195
+ command_doc_hsh = {
196
+ test_command: "a simple test command which happens to have a rather overly verbose description expected to be "+
197
+ "wrapped in order to make said description fit in a nice column",
198
+ test_command_with_a_long_name_for_testing_things: 'a simple test command'
199
+ }
200
+ desc_width = 90
201
+ result = Rubycom::Helpers.format_command_list(command_doc_hsh, desc_width)
202
+ expected = [
203
+ "test_command - a simple test command which happens\n"+
204
+ " to have a rather overly verbose\n"+
205
+ " description expected to be wrapped in\n"+
206
+ " order to make said description fit in\n"+
207
+ " a nice column\n",
208
+ "test_command_with_a_long_name_for_testing_things - a simple test command\n"
209
+ ]
210
+ assert_equal(expected, result)
211
+ end
212
+
213
+ def test_format_command_list_missing_doc
214
+ command_doc_hsh = {
215
+ test_command: nil,
216
+ test_command_with_a_long_name_for_testing_things: 'a simple test command'
217
+ }
218
+ desc_width = 90
219
+ result = Rubycom::Helpers.format_command_list(command_doc_hsh, desc_width)
220
+ expected = [
221
+ "test_command - \n",
222
+ "test_command_with_a_long_name_for_testing_things - a simple test command\n"
223
+ ]
224
+ assert_equal(expected, result)
225
+ end
226
+
227
+ def test_format_command_list_missing_name
228
+ command_doc_hsh = {
229
+ nil => "some test command",
230
+ test_command_with_a_long_name_for_testing_things: 'a simple test command'
231
+ }
232
+ desc_width = 90
233
+ result = Rubycom::Helpers.format_command_list(command_doc_hsh, desc_width)
234
+ expected = [
235
+ " - some test command\n",
236
+ "test_command_with_a_long_name_for_testing_things - a simple test command\n"
237
+ ]
238
+ assert_equal(expected, result)
239
+ end
240
+
241
+ def test_format_command_list_missing_name_and_doc
242
+ command_doc_hsh = {
243
+ nil => nil,
244
+ test_command_with_a_long_name_for_testing_things: 'a simple test command'
245
+ }
246
+ desc_width = 90
247
+ result = Rubycom::Helpers.format_command_list(command_doc_hsh, desc_width)
248
+ expected = [
249
+ " - \n",
250
+ "test_command_with_a_long_name_for_testing_things - a simple test command\n"
251
+ ]
252
+ assert_equal(expected, result)
253
+ end
254
+
255
+ def test_get_separator_empty
256
+ name = ''
257
+ longest_name = ''
258
+ sep = ''
259
+ result = Rubycom::Helpers.get_separator(name, longest_name, sep)
260
+ assert(result.include?(sep), "calculated separator #{result} should include the given separator")
261
+ assert(result.gsub(sep, '').gsub(' ', '').empty?, "calculated separator should only consist of whitespace and the given separator")
262
+ assert("#{name}#{result}".length == longest_name.size+sep.size,
263
+ "name.length+result.length should be #{longest_name.length+sep.length} but was #{"#{name}#{result}".length}")
264
+ end
265
+
266
+ def test_get_separator
267
+ name = 'test_command'
268
+ longest_name = 'test_command_with_a_long_name_for_testing_things'
269
+ sep = ' - '
270
+ result = Rubycom::Helpers.get_separator(name, longest_name, sep)
271
+ assert(result.include?(sep), "calculated separator #{result} should include the given separator")
272
+ assert(result.gsub(sep, '').gsub(' ', '').empty?, "calculated separator should only consist of whitespace and the given separator")
273
+ assert("#{name}#{result}".length == longest_name.size+sep.size,
274
+ "name.length+result.length should be #{longest_name.length+sep.length} but was #{"#{name}#{result}".length}")
275
+ end
276
+
277
+ def test_get_separator_empty_sep
278
+ name = 'test_command'
279
+ longest_name = 'test_command_with_a_long_name_for_testing_things'
280
+ sep = ''
281
+ result = Rubycom::Helpers.get_separator(name, longest_name, sep)
282
+ assert(result.include?(sep), "calculated separator #{result} should include the given separator")
283
+ assert(result.gsub(sep, '').gsub(' ', '').empty?, "calculated separator should only consist of whitespace and the given separator")
284
+ assert("#{name}#{result}".length == longest_name.size+sep.size,
285
+ "name.length+result.length should be #{longest_name.length+sep.length} but was #{"#{name}#{result}".length}")
286
+ end
287
+
288
+ def test_get_separator_empty_name
289
+ name = ''
290
+ longest_name = 'test_command_with_a_long_name_for_testing_things'
291
+ sep = ' - '
292
+ result = Rubycom::Helpers.get_separator(name, longest_name, sep)
293
+ assert(result.include?(sep), "calculated separator #{result} should include the given separator")
294
+ assert(result.gsub(sep, '').gsub(' ', '').empty?, "calculated separator should only consist of whitespace and the given separator")
295
+ assert("#{name}#{result}".length == longest_name.size+sep.size,
296
+ "name.length+result.length should be #{longest_name.length+sep.length} but was #{"#{name}#{result}".length}")
297
+ end
298
+
299
+ def test_get_separator_name_longer_than_longest
300
+ name = 'test_command_with_a_long_name_for_testing_things'
301
+ longest_name = 'test_command'
302
+ sep = ' - '
303
+ result = Rubycom::Helpers.get_separator(name, longest_name, sep)
304
+ assert(result.include?(sep), "calculated separator #{result} should include the given separator")
305
+ assert(result.gsub(sep, '').gsub(' ', '').empty?, "calculated separator should only consist of whitespace and the given separator")
306
+ assert("#{name}#{result}".length == name.size+sep.size,
307
+ "name.length+result.length should be #{name.size+sep.size} but was #{"#{name}#{result}".length}")
308
+ end
309
+
310
+ def test_format_command_summary_empty
311
+ command_name = ''
312
+ command_description = ''
313
+ separator = ''
314
+ max_width = 90
315
+ result = Rubycom::Helpers.format_command_summary(command_name, command_description, separator, max_width)
316
+ expected = "\n"
317
+ assert_equal(expected, result)
318
+ end
319
+
320
+ def test_format_command_summary_short
321
+ command_name = 'test_command'
322
+ command_description = 'a simple test command'
323
+ separator = ' - '
324
+ max_width = 90
325
+ result = Rubycom::Helpers.format_command_summary(command_name, command_description, separator, max_width)
326
+ expected = "test_command - a simple test command\n"
327
+ assert_equal(expected, result)
328
+ end
329
+
330
+ def test_format_command_summary_long_name
331
+ command_name = 'test_command_with_a_long_name_for_testing_things'
332
+ command_description = 'a simple test command'
333
+ separator = ' - '
334
+ max_width = 90
335
+ result = Rubycom::Helpers.format_command_summary(command_name, command_description, separator, max_width)
336
+ expected = "test_command_with_a_long_name_for_testing_things - a simple test command\n"
337
+ assert_equal(expected, result)
338
+ end
339
+
340
+ def test_format_command_summary_name_over_max_width
341
+ command_name = 'test_command_with_a_long_name_for_testing_things'
342
+ command_description = 'a simple test command'
343
+ separator = ' - '
344
+ max_width = 10
345
+ result = nil
346
+ assert_raise(ArgumentError) { result = Rubycom::Helpers.format_command_summary(command_name, command_description, separator, max_width) }
347
+ expected = nil
348
+ assert_equal(expected, result)
349
+ end
350
+
351
+ def test_format_command_summary_name_sep_equal_max_width
352
+ command_name = 'test_command'
353
+ command_description = 'a simple test command'
354
+ separator = ' - '
355
+ max_width = command_name.size+separator.size
356
+ result = Rubycom::Helpers.format_command_summary(command_name, command_description, separator, max_width)
357
+ expected = "test_command - a\n simple\n test\n command\n"
358
+ assert_equal(expected, result)
359
+ end
360
+
361
+ def test_format_command_summary_long_desc
362
+ command_name = 'test_command'
363
+ command_description = "a simple test command which happens to have a rather overly verbose description expected to"+
364
+ " be wrapped in order to make said description fit in a nice column"
365
+ separator = ' - '
366
+ max_width = 70
367
+ result = Rubycom::Helpers.format_command_summary(command_name, command_description, separator, max_width)
368
+ expected = "test_command - a simple test command which happens to have a rather\n overly verbose "+
369
+ "description expected to be wrapped in\n order to make said description fit in a nice column\n"
370
+ assert_equal(expected, result)
371
+ end
372
+
373
+ def test_format_command_summary_long_desc_short_width
374
+ command_name = 'test_command'
375
+ command_description = "a simple test command which happens to have a rather overly verbose description expected"+
376
+ " to be wrapped in order to make said description fit in a nice column"
377
+ separator = ' - '
378
+ max_width = 16
379
+ result = Rubycom::Helpers.format_command_summary(command_name, command_description, separator, max_width)
380
+ expected = "test_command - a\n"+
381
+ " simple\n"+
382
+ " test\n"+
383
+ " command\n"+
384
+ " which\n"+
385
+ " happens\n"+
386
+ " to\n"+
387
+ " have\n"+
388
+ " a\n"+
389
+ " rather\n"+
390
+ " overly\n"+
391
+ " verbose\n"+
392
+ " description\n"+
393
+ " expected\n"+
394
+ " to\n"+
395
+ " be\n"+
396
+ " wrapped\n"+
397
+ " in\n"+
398
+ " order\n"+
399
+ " to\n"+
400
+ " make\n"+
401
+ " said\n"+
402
+ " description\n"+
403
+ " fit\n"+
404
+ " in\n"+
405
+ " a\n"+
406
+ " nice\n"+
407
+ " column\n"
408
+ assert_equal(expected, result)
409
+ end
410
+
411
+ def test_format_command_summary_long_separator
412
+ command_name = 'test_command'
413
+ command_description = 'a simple test command'
414
+ separator = ' ----------------------------------------------------------------------------------------------- '
415
+ max_width = 16
416
+ result = nil
417
+ assert_raise(ArgumentError) { result = Rubycom::Helpers.format_command_summary(command_name, command_description, separator, max_width) }
418
+ expected = nil
419
+ assert_equal(expected, result)
420
+ end
421
+
422
+ def test_word_wrap_empty
423
+ text = ''
424
+ line_width=10
425
+ prefix=''
426
+ result = Rubycom::Helpers.word_wrap(text, line_width, prefix)
427
+ expected = ''
428
+ assert_equal(expected, result)
429
+ end
430
+
431
+ def test_word_wrap_less_than_line_width
432
+ text = '1 2 3 4 5 6 7 8 9'
433
+ line_width = 17
434
+ prefix = ''
435
+ result = Rubycom::Helpers.word_wrap(text, line_width, prefix)
436
+ expected = '1 2 3 4 5 6 7 8 9'
437
+ assert_equal(expected, result)
438
+ end
439
+
440
+ def test_word_wrap_greater_than_line_width
441
+ text = '1 2 3 4 5 6 7 8 9'
442
+ line_width = 10
443
+ prefix = ''
444
+ result = Rubycom::Helpers.word_wrap(text, line_width, prefix)
445
+ expected = "1 2 3 4 5\n6 7 8 9"
446
+ assert_equal(expected, result)
447
+ end
448
+
449
+ def test_word_wrap_with_prefix
450
+ text = '1 2 3 4 5 6 7 8 9'
451
+ line_width = 10
452
+ prefix = ' '
453
+ result = Rubycom::Helpers.word_wrap(text, line_width, prefix)
454
+ expected = "1 2 3 4 5\n 6 7 8 9"
455
+ assert_equal(expected, result)
456
+ end
457
+
458
+ def test_word_wrap_with_long_prefix
459
+ text = '1 2 3 4 5 6 7 8 9'
460
+ line_width = 10
461
+ prefix = ' ' * 40
462
+ result = Rubycom::Helpers.word_wrap(text, line_width, prefix)
463
+ expected = "1 2 3 4 5\n 6 7 8 9"
464
+ assert_equal(expected, result)
465
+ end
466
+
467
+ end