kronk 1.6.2 → 1.7.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.
Files changed (48) hide show
  1. data/History.rdoc +29 -1
  2. data/Manifest.txt +6 -1
  3. data/README.rdoc +74 -28
  4. data/Rakefile +4 -3
  5. data/TODO.rdoc +7 -5
  6. data/bin/kronk +2 -11
  7. data/lib/kronk/async/em_ext.rb +34 -0
  8. data/lib/kronk/async/request.rb +73 -0
  9. data/lib/kronk/async/response.rb +70 -0
  10. data/lib/kronk/async.rb +118 -0
  11. data/lib/kronk/cmd.rb +111 -43
  12. data/lib/kronk/constants.rb +1 -0
  13. data/lib/kronk/core_ext.rb +1 -1
  14. data/lib/kronk/data_string.rb +251 -0
  15. data/lib/kronk/diff/output.rb +132 -100
  16. data/lib/kronk/diff.rb +20 -24
  17. data/lib/kronk/path/matcher.rb +8 -4
  18. data/lib/kronk/path/path_match.rb +48 -4
  19. data/lib/kronk/path/transaction.rb +74 -53
  20. data/lib/kronk/path.rb +11 -6
  21. data/lib/kronk/player/benchmark.rb +11 -12
  22. data/lib/kronk/player/input_reader.rb +40 -3
  23. data/lib/kronk/player/request_parser.rb +4 -1
  24. data/lib/kronk/player/stream.rb +2 -2
  25. data/lib/kronk/player/suite.rb +16 -9
  26. data/lib/kronk/player.rb +93 -143
  27. data/lib/kronk/queue_runner.rb +238 -0
  28. data/lib/kronk/request.rb +25 -20
  29. data/lib/kronk/response.rb +39 -10
  30. data/lib/kronk/test/assertions.rb +2 -2
  31. data/lib/kronk/test/helper_methods.rb +1 -1
  32. data/lib/kronk.rb +56 -24
  33. data/test/test_assertions.rb +4 -4
  34. data/test/test_cmd.rb +38 -10
  35. data/test/test_data_string.rb +242 -1
  36. data/test/test_diff.rb +8 -303
  37. data/test/test_helper.rb +1 -1
  38. data/test/test_kronk.rb +21 -28
  39. data/test/test_path.rb +29 -0
  40. data/test/test_path_match.rb +47 -2
  41. data/test/test_path_matcher.rb +42 -1
  42. data/test/test_player.rb +71 -72
  43. data/test/test_request.rb +31 -6
  44. data/test/test_request_parser.rb +7 -1
  45. data/test/test_response.rb +1 -1
  46. data/test/test_transaction.rb +78 -30
  47. metadata +64 -8
  48. data/lib/kronk/data_renderer.rb +0 -219
@@ -18,14 +18,14 @@ class Kronk
18
18
 
19
19
  class Response
20
20
 
21
- class MissingParser < Exception; end
22
- class InvalidParser < Exception; end
21
+ class MissingParser < Kronk::Exception; end
22
+ class InvalidParser < Kronk::Exception; end
23
23
 
24
24
 
25
25
  ENCODING_MATCHER = /(^|;\s?)charset=(.*?)\s*(;|$)/
26
26
 
27
27
  ##
28
- # Read http response from a file and return a HTTPResponse instance.
28
+ # Read http response from a file and return a Kronk::Response instance.
29
29
 
30
30
  def self.read_file path
31
31
  file = File.open(path, "rb")
@@ -143,7 +143,7 @@ class Kronk
143
143
  # Ruby inspect.
144
144
 
145
145
  def inspect
146
- "#<#{self.class}:#{self.code} #{self['Content-Type']}>"
146
+ "#<#{self.class}:#{self.code} #{self['Content-Type']} #{total_bytes}bytes>"
147
147
  end
148
148
 
149
149
 
@@ -235,6 +235,16 @@ class Kronk
235
235
  end
236
236
 
237
237
 
238
+ ##
239
+ # Returns the location to redirect to. Prepends request url if location
240
+ # header is relative.
241
+
242
+ def location
243
+ return @_res['Location'] if !@request || !@request.uri
244
+ @request.uri.merge @_res['Location']
245
+ end
246
+
247
+
238
248
  ##
239
249
  # Check if this is a redirect response.
240
250
 
@@ -249,7 +259,7 @@ class Kronk
249
259
 
250
260
  def follow_redirect opts={}
251
261
  return if !redirect?
252
- Request.new(@_res['Location'], opts).retrieve
262
+ Request.new(self.location, opts).retrieve
253
263
  end
254
264
 
255
265
 
@@ -277,8 +287,19 @@ class Kronk
277
287
  # :no_body:: Bool - Don't return the body; default nil
278
288
  # :show_headers:: Bool/String/Array - Return headers; default nil
279
289
  # :parser:: Object - The parser to use for the body; default nil
290
+ # :transform:: Array - Action/path(s) pairs to modify data.
291
+ #
292
+ # Deprecated Options:
280
293
  # :ignore_data:: String/Array - Removes the data from given data paths
281
294
  # :only_data:: String/Array - Extracts the data from given data paths
295
+ #
296
+ # Example:
297
+ # response.selective_data :transform => [:delete, ["foo/0", "bar/1"]]
298
+ # response.selective_data do |trans|
299
+ # trans.delete "foo/0", "bar/1"
300
+ # end
301
+ #
302
+ # See Kronk::Path::Transaction for supported transform actions.
282
303
 
283
304
  def selective_data options={}
284
305
  data = nil
@@ -294,8 +315,13 @@ class Kronk
294
315
  end
295
316
 
296
317
  Path::Transaction.run data, options do |t|
297
- t.select(*options[:only_data])
298
- t.delete(*options[:ignore_data])
318
+ # Backward compatibility support
319
+ t.select(*options[:only_data]) if options[:only_data]
320
+ t.delete(*options[:ignore_data]) if options[:ignore_data]
321
+
322
+ t.actions.concat options[:transform] if options[:transform]
323
+
324
+ yield t if block_given?
299
325
  end
300
326
  end
301
327
 
@@ -311,13 +337,16 @@ class Kronk
311
337
  # :raw:: Boolean - Force using the unparsed raw response
312
338
  # :keep_indicies:: Boolean - indicies of modified arrays display as hashes.
313
339
  # :show_headers:: Boolean/String/Array - defines which headers to include
340
+ #
341
+ # If block is given, yields a Kronk::Path::Transaction instance to make
342
+ # transformations on the data. See Kronk::Response#selective_data
314
343
 
315
- def stringify options={}
344
+ def stringify options={}, &block
316
345
  options = options.empty? ? @stringify_opts : merge_stringify_opts(options)
317
346
 
318
347
  if !options[:raw] && (options[:parser] || @parser || options[:no_body])
319
- data = selective_data options
320
- Diff.ordered_data_string data, options[:struct]
348
+ data = selective_data options, &block
349
+ DataString.new data, options
321
350
  else
322
351
  selective_string options
323
352
  end
@@ -83,8 +83,8 @@ class Kronk
83
83
  # Supports all options of Kronk.compare.
84
84
 
85
85
  def assert_equal_responses uri1, uri2, options={}
86
- resp1 = Kronk.retrieve(uri1, options).stringify
87
- resp2 = Kronk.retrieve(uri2, options).stringify
86
+ resp1 = Kronk.request(uri1, options).stringify
87
+ resp2 = Kronk.request(uri2, options).stringify
88
88
 
89
89
  assert_equal resp1, resp2
90
90
  end
@@ -52,7 +52,7 @@ class Kronk
52
52
 
53
53
  @kronk = Kronk.new options
54
54
 
55
- uri2 ? @kronk.compare(uri1, uri2) : @kronk.retrieve(uri1)
55
+ uri2 ? @kronk.compare(uri1, uri2) : @kronk.request(uri1)
56
56
 
57
57
  @responses = @kronk.responses
58
58
  @response = @kronk.response
data/lib/kronk.rb CHANGED
@@ -14,9 +14,10 @@ require 'yaml'
14
14
  class Kronk
15
15
 
16
16
  # This gem's version.
17
- VERSION = '1.6.2'
17
+ VERSION = '1.7.0'
18
18
 
19
19
  require 'kronk/constants'
20
+ require 'kronk/queue_runner'
20
21
  require 'kronk/player'
21
22
  require 'kronk/player/output'
22
23
  require 'kronk/player/suite'
@@ -29,7 +30,7 @@ class Kronk
29
30
  require 'kronk/path/path_match'
30
31
  require 'kronk/path/matcher'
31
32
  require 'kronk/path/transaction'
32
- require 'kronk/data_renderer'
33
+ require 'kronk/data_string'
33
34
  require 'kronk/diff/ascii_format'
34
35
  require 'kronk/diff/color_format'
35
36
  require 'kronk/diff/output'
@@ -54,18 +55,40 @@ class Kronk
54
55
  def self.load_config filepath=DEFAULT_CONFIG_FILE
55
56
  conf = YAML.load_file filepath
56
57
 
57
- self.config[:requires].concat [*conf.delete(:requires)] if conf[:requires]
58
+ conf.each do |key, value|
59
+ skey = key.to_sym
58
60
 
59
- [:content_types, :uri_options, :user_agents].each do |key|
60
- self.config[key].merge! conf.delete(key) if conf[key]
61
- end
61
+ case skey
62
+ when :content_types, :user_agents
63
+ conf[key].each{|k,v| self.config[skey][k.to_s] = v }
64
+
65
+ when :requires
66
+ self.config[skey].concat Array(value)
67
+
68
+ when :uri_options
69
+ conf[key].each do |matcher, opts|
70
+ self.config[skey][matcher.to_s] = opts
71
+ opts.keys.each{|k| opts[k.to_sym] = opts.delete(k) if String === k}
72
+ end
62
73
 
63
- self.config.merge! conf
74
+ else
75
+ self.config[skey] = value
76
+ end
77
+ end
64
78
  end
65
79
 
66
80
 
67
81
  ##
68
- # Find a fully qualified ruby namespace/constant.
82
+ # Find a fully qualified ruby namespace/constant. Supports file paths,
83
+ # constants, or path:Constant combinations:
84
+ # Kronk.find_const "json"
85
+ # #=> JSON
86
+ #
87
+ # Kronk.find_const "namespace/mylib"
88
+ # #=> Namespace::MyLib
89
+ #
90
+ # Kronk.find_const "path/to/somefile.rb:Namespace::MyLib"
91
+ # #=> Namespace::MyLib
69
92
 
70
93
  def self.find_const name_or_file, case_insensitive=false
71
94
  return name_or_file unless String === name_or_file
@@ -161,7 +184,7 @@ class Kronk
161
184
 
162
185
 
163
186
  ##
164
- # Load the saved cookies file.
187
+ # Load the saved cookies file. Defaults to Kronk::config[:cookies_file].
165
188
 
166
189
  def self.load_cookie_jar file=nil
167
190
  file ||= config[:cookies_file]
@@ -216,13 +239,16 @@ class Kronk
216
239
 
217
240
 
218
241
  ##
219
- # See Kronk#retrieve. Short for:
220
- # Kronk.new(opts).retrieve(uri)
242
+ # See Kronk#request. Short for:
243
+ # Kronk.new(opts).request(uri)
221
244
 
222
- def self.retrieve uri, opts={}
223
- new(opts).retrieve uri
245
+ def self.request uri, opts={}
246
+ new(opts).request uri
224
247
  end
225
248
 
249
+ class << self
250
+ alias retrieve request
251
+ end
226
252
 
227
253
  attr_accessor :diff, :options, :response, :responses
228
254
 
@@ -240,12 +266,15 @@ class Kronk
240
266
  # :user_agent:: String - user agent string or alias; defaults to 'kronk'
241
267
  # :auth:: Hash - must contain :username and :password; defaults to nil
242
268
  # :proxy:: Hash/String - http proxy to use; defaults to nil
243
- # :only_data:: String/Array - extracts the data from given data paths
244
- # :ignore_data:: String/Array - defines which data points to exclude
245
269
  # :keep_indicies:: Boolean - indicies of modified arrays display as hashes
246
270
  # :show_headers:: Boolean/String/Array - which headers to show in output
247
271
  # :parser:: Object/String - the parser to use for the body; default nil
248
272
  # :raw:: Boolean - run diff on raw strings
273
+ # :transform:: Array - Action/path(s) pairs to modify data.
274
+ #
275
+ # Deprecated Options:
276
+ # :ignore_data:: String/Array - Removes the data from given data paths
277
+ # :only_data:: String/Array - Extracts the data from given data paths
249
278
 
250
279
  def initialize opts={}
251
280
  @options = opts
@@ -260,19 +289,19 @@ class Kronk
260
289
  # Query arguments may be set to the special value :cache to use the
261
290
  # last live http response retrieved.
262
291
  #
263
- # Returns a diff object.
292
+ # Assigns @response, @responses, @diff. Returns the Diff instance.
264
293
 
265
294
  def compare uri1, uri2
266
295
  str1 = str2 = ""
267
296
  res1 = res2 = nil
268
297
 
269
298
  t1 = Thread.new do
270
- res1 = retrieve uri1
299
+ res1 = request uri1
271
300
  str1 = res1.stringify
272
301
  end
273
302
 
274
303
  t2 = Thread.new do
275
- res2 = retrieve uri2
304
+ res2 = request uri2
276
305
  str2 = res2.stringify
277
306
  end
278
307
 
@@ -289,8 +318,9 @@ class Kronk
289
318
 
290
319
  ##
291
320
  # Returns a Response instance from a url, file, or IO as a String.
321
+ # Assigns @response, @responses, @diff.
292
322
 
293
- def retrieve uri
323
+ def request uri
294
324
  options = Kronk.config[:no_uri_options] ? @options : options_for_uri(uri)
295
325
 
296
326
  if IO === uri || StringIO === uri
@@ -311,11 +341,11 @@ class Kronk
311
341
  resp.parser = options[:parser] if options[:parser]
312
342
  resp.stringify_opts = options
313
343
 
314
- max_rdir = options[:follow_redirects]
315
- while resp.redirect? && (max_rdir == true || max_rdir.to_s.to_i > 0)
316
- Cmd.verbose "Following redirect..."
317
- resp = resp.follow_redirect
318
- max_rdir = max_rdir - 1 if Fixnum === max_rdir
344
+ rdir = options[:follow_redirects]
345
+ while resp.redirect? && (rdir == true || rdir.to_s.to_i > 0)
346
+ Cmd.verbose "Following redirect to #{resp.location}"
347
+ resp = resp.follow_redirect options_for_uri(resp.location)
348
+ rdir = rdir - 1 if Fixnum === rdir
319
349
  end
320
350
 
321
351
  @responses = [resp]
@@ -331,6 +361,8 @@ class Kronk
331
361
  raise TimeoutError, "#{uri} took too long to respond"
332
362
  end
333
363
 
364
+ alias retrieve request
365
+
334
366
 
335
367
  ##
336
368
  # Returns merged config-defined options for a given uri.
@@ -61,7 +61,7 @@ class TestAssertions < Test::Unit::TestCase
61
61
  io = StringIO.new mock_resp("200_response.json")
62
62
  mock_resp = Kronk::Response.new io
63
63
 
64
- Kronk.expects(:retrieve).times(2).
64
+ Kronk.expects(:request).times(2).
65
65
  with("host.com", :foo => "bar").returns mock_resp
66
66
 
67
67
  assert_equal_responses "host.com", "host.com", :foo => "bar"
@@ -75,13 +75,13 @@ class TestAssertions < Test::Unit::TestCase
75
75
  mock_resp2 = Kronk::Response.new \
76
76
  StringIO.new mock_resp("301_response.txt")
77
77
 
78
- Kronk.expects(:retrieve).
78
+ Kronk.expects(:request).
79
79
  with("host1.com", :foo => "bar").returns mock_resp1
80
80
 
81
- Kronk.expects(:retrieve).
81
+ Kronk.expects(:request).
82
82
  with("host2.com", :foo => "bar").returns mock_resp2
83
83
 
84
- left = Kronk::Diff.ordered_data_string mock_resp1.selective_data
84
+ left = Kronk::DataString.new mock_resp1.selective_data
85
85
  right = mock_resp2.body
86
86
 
87
87
  assert_not_equal left, right
data/test/test_cmd.rb CHANGED
@@ -98,8 +98,8 @@ class TestCmd < Test::Unit::TestCase
98
98
  argv = %w{opt1 opt2 -- path1 path2 -path3}
99
99
  Kronk::Cmd.parse_data_path_args opts, argv
100
100
 
101
- assert_equal %w{path1 path2}, opts[:only_data]
102
- assert_equal %w{path3}, opts[:ignore_data]
101
+ assert_equal [:select, %w{path1 path2}], opts[:transform][0]
102
+ assert_equal [:delete, %w{path3}], opts[:transform][1]
103
103
  end
104
104
 
105
105
 
@@ -113,6 +113,34 @@ class TestCmd < Test::Unit::TestCase
113
113
  end
114
114
 
115
115
 
116
+ def test_parse_data_path_args_double
117
+ options = {}
118
+ argv = %w{this is --argv -- one -two -- -three four}
119
+
120
+ options = Kronk::Cmd.parse_data_path_args options, argv
121
+
122
+ assert_equal [:select, %w{one}], options[:transform][0]
123
+ assert_equal [:delete, %w{two - three}], options[:transform][1]
124
+ assert_equal [:select, %w{four}], options[:transform][2]
125
+
126
+ assert_equal %w{this is --argv}, argv
127
+ end
128
+
129
+
130
+ def test_parse_data_path_args_select_and_map_join
131
+ options = {}
132
+ argv = %w{this is --argv -- one two>foo -three four}
133
+
134
+ options = Kronk::Cmd.parse_data_path_args options, argv
135
+
136
+ assert_equal [:map, ['one', ['two', 'foo']]], options[:transform][0]
137
+ assert_equal [:delete, %w{three}], options[:transform][1]
138
+ assert_equal [:select, %w{four}], options[:transform][2]
139
+
140
+ assert_equal %w{this is --argv}, argv
141
+ end
142
+
143
+
116
144
  def test_query_password
117
145
  $stderr.expects(:<<).with "Password: "
118
146
  $stdin.expects(:gets).returns "mock_password\n"
@@ -322,7 +350,7 @@ class TestCmd < Test::Unit::TestCase
322
350
  assert_equal "bar", opts[:query]
323
351
  assert_equal "/tail", opts[:uri_suffix]
324
352
  assert_equal "PUT", opts[:http_method]
325
- assert_equal({:address => "example.com", :port => "2000"}, opts[:proxy])
353
+ assert_equal({:host => "example.com", :port => "2000"}, opts[:proxy])
326
354
 
327
355
  opts = Kronk::Cmd.parse_args %w{uri -L 3}
328
356
  assert_equal 3, opts[:follow_redirects]
@@ -348,8 +376,8 @@ class TestCmd < Test::Unit::TestCase
348
376
 
349
377
  def test_parse_args_paths
350
378
  opts = Kronk::Cmd.parse_args %w{uri -- path1 path2 -path3}
351
- assert_equal %w{path3}, opts[:ignore_data]
352
- assert_equal %w{path1 path2}, opts[:only_data]
379
+ assert_equal [:delete, %w{path3}], opts[:transform][1]
380
+ assert_equal [:select, %w{path1 path2}], opts[:transform][0]
353
381
  end
354
382
 
355
383
 
@@ -550,7 +578,7 @@ class TestCmd < Test::Unit::TestCase
550
578
  kronk = Kronk.new
551
579
  io = StringIO.new(mock_200_response)
552
580
 
553
- kronk.retrieve io
581
+ kronk.request io
554
582
  expect_request_output mock_200_response, :times => 2
555
583
 
556
584
  assert_equal Kronk::Cmd.render_response(kronk.response),
@@ -622,7 +650,7 @@ class TestCmd < Test::Unit::TestCase
622
650
 
623
651
  def test_render_response
624
652
  kronk = Kronk.new
625
- kronk.retrieve StringIO.new(mock_200_response)
653
+ kronk.request StringIO.new(mock_200_response)
626
654
 
627
655
  $stdout.expects(:puts).with kronk.response.stringify
628
656
  assert Kronk::Cmd.render_response(kronk.response),
@@ -633,7 +661,7 @@ class TestCmd < Test::Unit::TestCase
633
661
  def test_render_response_lines
634
662
  with_config :show_lines => true do
635
663
  kronk = Kronk.new
636
- kronk.retrieve StringIO.new(mock_200_response)
664
+ kronk.request StringIO.new(mock_200_response)
637
665
 
638
666
  expected = Kronk::Diff.insert_line_nums kronk.response.stringify
639
667
  $stdout.expects(:puts).with expected
@@ -650,7 +678,7 @@ class TestCmd < Test::Unit::TestCase
650
678
  io = StringIO.new(mock_200_response)
651
679
 
652
680
  $stdout.expects(:<<).with "Reading IO #{io}\n"
653
- kronk.retrieve io
681
+ kronk.request io
654
682
 
655
683
  expected = kronk.response.stringify
656
684
  $stdout.expects(:puts).with expected
@@ -664,7 +692,7 @@ class TestCmd < Test::Unit::TestCase
664
692
 
665
693
  def test_render_response_failed
666
694
  kronk = Kronk.new
667
- kronk.retrieve StringIO.new(mock_302_response)
695
+ kronk.request StringIO.new(mock_302_response)
668
696
 
669
697
  $stdout.expects(:puts).with kronk.response.stringify
670
698
  assert !Kronk::Cmd.render_response(kronk.response),
@@ -3,7 +3,8 @@ require 'test/test_helper'
3
3
  class TestDataString < Test::Unit::TestCase
4
4
 
5
5
  def setup
6
- @dstr = Kronk::DataString.new "foobar", "data0"
6
+ @dstr = Kronk::DataString.new
7
+ @dstr.append "foobar", "data0"
7
8
  end
8
9
 
9
10
 
@@ -55,4 +56,244 @@ class TestDataString < Test::Unit::TestCase
55
56
  assert_equal [@dstr.meta[i]], dstr.meta
56
57
  end
57
58
  end
59
+
60
+
61
+ def test_ordered_data_string_json
62
+ expected = <<STR
63
+ {
64
+ "acks": [
65
+ [
66
+ 56,
67
+ 78
68
+ ],
69
+ [
70
+ "12",
71
+ "34"
72
+ ]
73
+ ],
74
+ "root": [
75
+ [
76
+ "B1",
77
+ "B2"
78
+ ],
79
+ [
80
+ "A1",
81
+ "A2"
82
+ ],
83
+ [
84
+ "C1",
85
+ "C2",
86
+ [
87
+ "C3a",
88
+ "C3b"
89
+ ]
90
+ ],
91
+ {
92
+ ":tests": [
93
+ "D3a",
94
+ "D3b"
95
+ ],
96
+ "test": [
97
+ [
98
+ "D1a\\nContent goes here",
99
+ "D1b"
100
+ ],
101
+ "D2"
102
+ ]
103
+ }
104
+ ],
105
+ "subs": [
106
+ "a",
107
+ "b"
108
+ ],
109
+ "tests": {
110
+ ":foo": ":bar",
111
+ "test": [
112
+ [
113
+ 1,
114
+ 2
115
+ ],
116
+ 2.123
117
+ ]
118
+ }
119
+ }
120
+ STR
121
+
122
+ assert_equal expected.strip, Kronk::DataString.new(mock_data)
123
+ end
124
+
125
+
126
+ def test_ordered_data_string_struct_json
127
+ expected = <<STR
128
+ {
129
+ "acks": [
130
+ [
131
+ "Fixnum",
132
+ "Fixnum"
133
+ ],
134
+ [
135
+ "String",
136
+ "String"
137
+ ]
138
+ ],
139
+ "root": [
140
+ [
141
+ "String",
142
+ "String"
143
+ ],
144
+ [
145
+ "String",
146
+ "String"
147
+ ],
148
+ [
149
+ "String",
150
+ "String",
151
+ [
152
+ "String",
153
+ "String"
154
+ ]
155
+ ],
156
+ {
157
+ ":tests": [
158
+ "String",
159
+ "String"
160
+ ],
161
+ "test": [
162
+ [
163
+ "String",
164
+ "String"
165
+ ],
166
+ "String"
167
+ ]
168
+ }
169
+ ],
170
+ "subs": [
171
+ "String",
172
+ "String"
173
+ ],
174
+ "tests": {
175
+ ":foo": "Symbol",
176
+ "test": [
177
+ [
178
+ "Fixnum",
179
+ "Fixnum"
180
+ ],
181
+ "Float"
182
+ ]
183
+ }
184
+ }
185
+ STR
186
+
187
+ assert_equal expected.strip,
188
+ Kronk::DataString.new(mock_data, :struct => true)
189
+
190
+ assert_equal Kronk::DataString.json(mock_data, :struct => true),
191
+ Kronk::DataString.new(mock_data, :struct => true)
192
+ end
193
+
194
+
195
+ def test_ordered_data_string_ruby_paths
196
+ with_config :render_lang => 'ruby', :render_paths => true do
197
+ expected = <<STR
198
+ {
199
+ "/acks/0/0" => 56,
200
+ "/acks/0/1" => 78,
201
+ "/acks/1/0" => "12",
202
+ "/acks/1/1" => "34",
203
+ "/root/0/0" => "B1",
204
+ "/root/0/1" => "B2",
205
+ "/root/1/0" => "A1",
206
+ "/root/1/1" => "A2",
207
+ "/root/2/0" => "C1",
208
+ "/root/2/1" => "C2",
209
+ "/root/2/2/0" => "C3a",
210
+ "/root/2/2/1" => "C3b",
211
+ "/root/3/test/0/0" => "D1a\\nContent goes here",
212
+ "/root/3/test/0/1" => "D1b",
213
+ "/root/3/test/1" => "D2",
214
+ "/root/3/tests/0" => "D3a",
215
+ "/root/3/tests/1" => "D3b",
216
+ "/subs/0" => "a",
217
+ "/subs/1" => "b",
218
+ "/tests/foo" => :bar,
219
+ "/tests/test/0/0" => 1,
220
+ "/tests/test/0/1" => 2,
221
+ "/tests/test/1" => 2.123
222
+ }
223
+ STR
224
+
225
+ assert_equal expected.strip, Kronk::DataString.new(mock_data)
226
+ end
227
+ end
228
+
229
+
230
+ def test_ordered_data_string_struct_ruby
231
+ with_config :render_lang => 'ruby' do
232
+ expected = <<STR
233
+ {
234
+ "acks" => [
235
+ [
236
+ Fixnum,
237
+ Fixnum
238
+ ],
239
+ [
240
+ String,
241
+ String
242
+ ]
243
+ ],
244
+ "root" => [
245
+ [
246
+ String,
247
+ String
248
+ ],
249
+ [
250
+ String,
251
+ String
252
+ ],
253
+ [
254
+ String,
255
+ String,
256
+ [
257
+ String,
258
+ String
259
+ ]
260
+ ],
261
+ {
262
+ :tests => [
263
+ String,
264
+ String
265
+ ],
266
+ "test" => [
267
+ [
268
+ String,
269
+ String
270
+ ],
271
+ String
272
+ ]
273
+ }
274
+ ],
275
+ "subs" => [
276
+ String,
277
+ String
278
+ ],
279
+ "tests" => {
280
+ :foo => Symbol,
281
+ "test" => [
282
+ [
283
+ Fixnum,
284
+ Fixnum
285
+ ],
286
+ Float
287
+ ]
288
+ }
289
+ }
290
+ STR
291
+
292
+ assert_equal expected.strip,
293
+ Kronk::DataString.new(mock_data, :struct => true)
294
+
295
+ assert_equal Kronk::DataString.ruby(mock_data, :struct => true),
296
+ Kronk::DataString.new(mock_data, :struct => true)
297
+ end
298
+ end
58
299
  end