kronk 1.0.1 → 1.0.2

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.
data/History.txt CHANGED
@@ -1,3 +1,17 @@
1
+ === 1.0.2 / 2010-12
2
+
3
+ * Enhancements:
4
+
5
+ * Added support for custom diff formatters.
6
+
7
+ * Added verbose mode.
8
+
9
+ * Added diff count.
10
+
11
+ * Bugfixes:
12
+
13
+ * Support for ruby-1.9.2
14
+
1
15
  === 1.0.1 / 2010-12-06
2
16
 
3
17
  * Bugfixes:
data/README.txt CHANGED
@@ -7,7 +7,7 @@
7
7
  Kronk runs diffs against data from live and cached http responses.
8
8
  Kronk was made possible by the sponsoring of AT&T Interactive.
9
9
 
10
- == FEATURES/PROBLEMS:
10
+ == FEATURES:
11
11
 
12
12
  * Parse and diff data from http response body and/or headers.
13
13
 
@@ -17,10 +17,10 @@ Kronk was made possible by the sponsoring of AT&T Interactive.
17
17
 
18
18
  * Support for custom data parsers.
19
19
 
20
- == FUTURE:
21
-
22
20
  * Line numbered and custom diff output.
23
21
 
22
+ == FUTURE:
23
+
24
24
  * Auto-queryer with optional param randomizing.
25
25
 
26
26
  * Support for test suites.
data/lib/kronk.rb CHANGED
@@ -17,7 +17,7 @@ require 'yaml'
17
17
  class Kronk
18
18
 
19
19
  # This gem's version.
20
- VERSION = '1.0.1'
20
+ VERSION = '1.0.2'
21
21
 
22
22
 
23
23
  require 'kronk/data_set'
@@ -49,6 +49,7 @@ class Kronk
49
49
  DEFAULT_CONFIG = {
50
50
  :content_types => DEFAULT_CONTENT_TYPES.dup,
51
51
  :diff_format => :ascii_diff,
52
+ :show_lines => false,
52
53
  :cache_file => DEFAULT_CACHE_FILE,
53
54
  :requires => []
54
55
  }
@@ -103,7 +104,7 @@ class Kronk
103
104
  # Find a fully qualified ruby namespace/constant.
104
105
 
105
106
  def self.find_const namespace
106
- consts = namespace.split "::"
107
+ consts = namespace.to_s.split "::"
107
108
  curr = self
108
109
 
109
110
  until consts.empty? do
@@ -120,8 +121,8 @@ class Kronk
120
121
  def self.parser_for content_type
121
122
  parser_pair =
122
123
  config[:content_types].select do |key, value|
123
- (content_type =~ %r{#{key}}) && value
124
- end
124
+ (content_type =~ %r{#{key}([^\w]|$)}) && value
125
+ end.to_a
125
126
 
126
127
  return if parser_pair.empty?
127
128
 
@@ -210,7 +211,8 @@ class Kronk
210
211
 
211
212
  if uri1 && uri2
212
213
  diff = compare uri1, uri2, options
213
- puts diff.formatted(config[:diff_format])
214
+ puts diff.formatted
215
+ verbose "\n\nFound #{diff.count} diff(s).\n"
214
216
 
215
217
  elsif options[:raw]
216
218
  puts Request.retrieve(uri1, options).selective_string(options)
@@ -226,6 +228,14 @@ class Kronk
226
228
  end
227
229
 
228
230
 
231
+ ##
232
+ # Print string only if verbose
233
+
234
+ def self.verbose str
235
+ $stdout << "#{str}\n" if config[:verbose]
236
+ end
237
+
238
+
229
239
  ##
230
240
  # Parse ARGV
231
241
 
@@ -357,9 +367,20 @@ Kronk runs diffs against data from live and cached http responses.
357
367
  end
358
368
 
359
369
 
360
- #opt.on('-v', '--verbose', 'Make the operation more talkative') do
361
- # options[:verbose] = true
362
- #end
370
+ opt.on('--format STR', String,
371
+ 'Use a custom diff formatter') do |value|
372
+ config[:diff_format] = value
373
+ end
374
+
375
+
376
+ opt.on('--lines', 'Show line numbers') do
377
+ config[:show_lines] = true
378
+ end
379
+
380
+
381
+ opt.on('-V', '--verbose', 'Make the operation more talkative') do
382
+ config[:verbose] = true
383
+ end
363
384
 
364
385
  opt.separator nil
365
386
  end
data/lib/kronk/diff.rb CHANGED
@@ -7,6 +7,60 @@ class Kronk
7
7
 
8
8
  class Diff
9
9
 
10
+ ##
11
+ # Format diff with ascii
12
+
13
+ class AsciiFormat
14
+
15
+ def self.lines d_line, a_line, col_width
16
+ "#{d_line.to_s.rjust(col_width)}|#{a_line.to_s.rjust(col_width)} "
17
+ end
18
+
19
+
20
+ def self.deleted str
21
+ "- #{str}"
22
+ end
23
+
24
+
25
+ def self.added str
26
+ "+ #{str}"
27
+ end
28
+
29
+
30
+ def self.common str
31
+ " #{str}"
32
+ end
33
+ end
34
+
35
+
36
+ ##
37
+ # Format diff with ascii
38
+
39
+ class ColorFormat
40
+
41
+ def self.lines d_line, a_line, col_width
42
+ d_line = d_line.to_s.rjust col_width
43
+ a_line = a_line.to_s.rjust col_width
44
+
45
+ "\033[7;31m#{d_line}\033[32m#{a_line.to_s.rjust(col_width)}\033[0m "
46
+ end
47
+
48
+
49
+ def self.deleted str
50
+ "\033[31m#{str}\033[0m"
51
+ end
52
+
53
+
54
+ def self.added str
55
+ "\033[32m#{str}\033[0m"
56
+ end
57
+
58
+
59
+ def self.common str
60
+ str
61
+ end
62
+ end
63
+
10
64
 
11
65
  ##
12
66
  # Creates a new diff from two data objects.
@@ -62,14 +116,26 @@ class Kronk
62
116
  end
63
117
 
64
118
 
65
- attr_accessor :str1, :str2, :char, :format
119
+ ##
120
+ # Returns a formatter from a symbol or string. Returns nil if not found.
121
+
122
+ def self.formatter name
123
+ return AsciiFormat if name == :ascii_diff
124
+ return ColorFormat if name == :color_diff
125
+ Kronk.find_const name rescue name
126
+ end
127
+
128
+
129
+ attr_accessor :str1, :str2, :char, :formatter, :show_lines
66
130
 
67
131
  def initialize str1, str2, char=/\r?\n/
68
- @str1 = str1
69
- @str2 = str2
70
- @char = char
71
- @diff_ary = nil
72
- @format = Kronk.config[:diff_format] || :ascii_diff
132
+ @str1 = str1
133
+ @str2 = str2
134
+ @char = char
135
+ @diff_ary = nil
136
+ @show_lines = Kronk.config[:show_lines]
137
+ @formatter =
138
+ self.class.formatter(Kronk.config[:diff_format]) || AsciiFormat
73
139
  end
74
140
 
75
141
 
@@ -147,46 +213,57 @@ class Kronk
147
213
  # Returns a formatted output as a string.
148
214
  # Custom formats may be achieved by passing a block.
149
215
 
150
- def formatted format=@format, join_char="\n", &block
151
- block ||= method format
216
+ def formatted options={}
217
+ options = {
218
+ :join_char => "\n",
219
+ :show_lines => @show_lines,
220
+ :formatter => @formatter
221
+ }.merge options
222
+
223
+ format = options[:formatter]
224
+
225
+ line1 = line2 = 0
226
+
227
+ lines1 = @str1.lines.count
228
+ lines2 = @str2.lines.count
229
+
230
+ width = (lines1 > lines2 ? lines1 : lines2).to_s.length
152
231
 
153
232
  diff_array.map do |item|
154
- block.call item.dup
155
- end.flatten.join join_char
156
- end
233
+ case item
234
+ when String
235
+ line1 = line1.next
236
+ line2 = line2.next
157
237
 
238
+ lines = format.lines line1, line2, width if options[:show_lines]
239
+ "#{lines}#{format.common item}"
158
240
 
159
- ##
160
- # Formats a single diff element to the default diff format.
241
+ when Array
242
+ item = item.dup
161
243
 
162
- def ascii_diff item
163
- case item
164
- when String
165
- " #{item}"
166
- when Array
167
- item[0] = item[0].map{|str| "- #{str}"}
168
- item[1] = item[1].map{|str| "+ #{str}"}
169
- item
170
- else
171
- " #{item.inspect}"
172
- end
244
+ item[0] = item[0].map do |str|
245
+ line1 = line1.next
246
+ lines = format.lines line1, nil, width if options[:show_lines]
247
+ "#{lines}#{format.deleted str}"
248
+ end
249
+
250
+ item[1] = item[1].map do |str|
251
+ line2 = line2.next
252
+ lines = format.lines nil, line2, width if options[:show_lines]
253
+ "#{lines}#{format.added str}"
254
+ end
255
+
256
+ item
257
+ end
258
+ end.flatten.join options[:join_char]
173
259
  end
174
260
 
175
261
 
176
262
  ##
177
- # Formats a single diff element with colors.
263
+ # Returns the number of diffs found.
178
264
 
179
- def color_diff item
180
- case item
181
- when String
182
- item
183
- when Array
184
- item[0] = item[0].map{|str| "\033[31m#{str}\033[0m"}
185
- item[1] = item[1].map{|str| "\033[32m#{str}\033[0m"}
186
- item
187
- else
188
- item.inspect
189
- end
265
+ def count
266
+ diff_array.select{|i| Array === i }.length
190
267
  end
191
268
 
192
269
 
data/lib/kronk/request.rb CHANGED
@@ -12,6 +12,8 @@ class Kronk
12
12
  # number of redirects left if it's an Integer.
13
13
 
14
14
  def self.follow_redirect resp, options={}
15
+ Kronk.verbose "Following redirect..."
16
+
15
17
  rdir = options[:follow_redirects]
16
18
  rdir = rdir - 1 if Integer === rdir && rdir > 0
17
19
 
@@ -35,8 +37,6 @@ class Kronk
35
37
  # :follow_redirects:: Integer/Bool - number of times to follow redirects
36
38
  # :headers:: Hash - extra headers to pass to the request
37
39
  # :http_method:: Symbol - the http method to use; defaults to :get
38
- #
39
- # TODO: Log request speed.
40
40
 
41
41
  def self.retrieve query, options={}
42
42
  resp =
@@ -72,6 +72,8 @@ class Kronk
72
72
  # Read http response from a file and return a HTTPResponse instance.
73
73
 
74
74
  def self.retrieve_file path, options={}
75
+ Kronk.verbose "\nReading file:\n#{path}\n"
76
+
75
77
  options = options.dup
76
78
 
77
79
  path = Kronk::DEFAULT_CACHE_FILE if path == :cache
@@ -107,6 +109,8 @@ class Kronk
107
109
  # to using a post request.
108
110
 
109
111
  def self.retrieve_uri uri, options={}
112
+ Kronk.verbose "\nRetrieving URL: #{uri}#{options[:uri_suffix]}\n"
113
+
110
114
  options = options.dup
111
115
  http_method = options.delete(:http_method)
112
116
  http_method ||= options[:data] ? :post : :get
@@ -84,6 +84,8 @@ class Kronk
84
84
  # the Content-Type, or will return the cached parsed body if available.
85
85
 
86
86
  def parsed_body parser=nil
87
+ @parsed_body ||= nil
88
+
87
89
  return @parsed_body if @parsed_body && !parser
88
90
  parser ||= Kronk.parser_for self['Content-Type']
89
91
 
data/test/test_diff.rb CHANGED
@@ -291,36 +291,56 @@ STR
291
291
  end
292
292
 
293
293
 
294
+ def test_count
295
+ assert_equal 4, @diff.count
296
+ end
297
+
298
+
294
299
  def test_formatted
295
300
  assert_equal diff_302_301_str, @diff.formatted
296
301
  end
297
302
 
298
303
 
304
+ def test_formatted_lines
305
+ output = @diff.formatted :show_lines => true
306
+ assert_equal diff_302_301_str_lines, output
307
+ end
308
+
309
+
299
310
  def test_formatted_color
300
- assert_equal diff_302_301_color, @diff.formatted(:color_diff)
311
+ assert_equal diff_302_301_color,
312
+ @diff.formatted(:formatter => Kronk::Diff::ColorFormat)
301
313
 
302
- @diff.format = :color_diff
314
+ @diff.formatter = Kronk::Diff::ColorFormat
303
315
  assert_equal diff_302_301_color, @diff.formatted
304
316
  end
305
317
 
306
318
 
307
319
  def test_formatted_join_char
308
320
  expected = diff_302_301_str.gsub(/\n/, "\r\n")
309
- assert_equal expected, @diff.formatted(:ascii_diff, "\r\n")
321
+ assert_equal expected,
322
+ @diff.formatted(
323
+ :formatter => Kronk::Diff::AsciiFormat,
324
+ :join_char => "\r\n")
310
325
  end
311
326
 
312
327
 
313
- def test_formatted_block
314
- str_diff = @diff.formatted do |item|
315
- if Array === item
316
- item[0].map!{|str| "<<<302<<< #{str}"}
317
- item[1].map!{|str| ">>>301>>> #{str}"}
318
- item
319
- else
320
- item.to_s
321
- end
328
+ class CustomFormat
329
+ def self.added str
330
+ ">>>301>>> #{str}"
331
+ end
332
+
333
+ def self.deleted str
334
+ "<<<302<<< #{str}"
335
+ end
336
+
337
+ def self.common str
338
+ str.to_s
322
339
  end
340
+ end
323
341
 
342
+ def test_formatted_custom
343
+ str_diff = @diff.formatted :formatter => CustomFormat
324
344
  expected = diff_302_301_str.gsub(/^\+/, ">>>301>>>")
325
345
  expected = expected.gsub(/^\-/, "<<<302<<<")
326
346
  expected = expected.gsub(/^\s\s/, "")
@@ -397,6 +417,37 @@ STR
397
417
  str.strip
398
418
  end
399
419
 
420
+
421
+ def diff_302_301_str_lines
422
+ str = <<STR
423
+ 1| - HTTP/1.1 302 Found
424
+ 2| - Location: http://igoogle.com/
425
+ | 1 + HTTP/1.1 301 Moved Permanently
426
+ | 2 + Location: http://www.google.com/
427
+ 3| 3 Content-Type: text/html; charset=UTF-8
428
+ 4| 4 Date: Fri, 26 Nov 2010 16:14:45 GMT
429
+ 5| 5 Expires: Sun, 26 Dec 2010 16:14:45 GMT
430
+ 6| 6 Cache-Control: public, max-age=2592000
431
+ 7| 7 Server: gws
432
+ 8| - Content-Length: 260
433
+ | 8 + Content-Length: 219
434
+ 9| 9 X-XSS-Protection: 1; mode=block
435
+ 10|10
436
+ 11|11 <HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
437
+ 12| - <TITLE>302 Found</TITLE></HEAD><BODY>
438
+ 13| - <H1>302 Found</H1>
439
+ |12 + <TITLE>301 Moved</TITLE></HEAD><BODY>
440
+ |13 + <H1>301 Moved</H1>
441
+ 14|14 The document has moved
442
+ 15|15 <A HREF="http://www.google.com/">here</A>.
443
+ 16| - <A HREF="http://igoogle.com/">here</A>.
444
+ 17|16 </BODY></HTML>
445
+ STR
446
+
447
+ str.rstrip
448
+ end
449
+
450
+
400
451
  def diff_302_301_color
401
452
  str = <<STR
402
453
  \033[31mHTTP/1.1 302 Found\033[0m
data/test/test_kronk.rb CHANGED
@@ -12,6 +12,7 @@ class TestKronk < Test::Unit::TestCase
12
12
  },
13
13
  :cache_file => Kronk::DEFAULT_CACHE_FILE,
14
14
  :diff_format => :ascii_diff,
15
+ :show_lines => false,
15
16
  :requires => []
16
17
  }
17
18
 
@@ -27,6 +28,7 @@ class TestKronk < Test::Unit::TestCase
27
28
  },
28
29
  :ignore_headers => ["Content-Type"],
29
30
  :cache_file => Kronk::DEFAULT_CACHE_FILE,
31
+ :show_lines => false,
30
32
  :requires => [],
31
33
  :foo => :bar
32
34
  }
@@ -47,6 +49,7 @@ class TestKronk < Test::Unit::TestCase
47
49
  :diff_format => :ascii_diff,
48
50
  :cache_file => Kronk::DEFAULT_CACHE_FILE,
49
51
  :requires => [],
52
+ :show_lines => false,
50
53
  :ignore_headers => ["Content-Type"],
51
54
  :foo => :bar
52
55
  }
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kronk
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
5
4
  prerelease: false
6
5
  segments:
7
6
  - 1
8
7
  - 0
9
- - 1
10
- version: 1.0.1
8
+ - 2
9
+ version: 1.0.2
11
10
  platform: ruby
12
11
  authors:
13
12
  - Jeremie Castagna
@@ -15,7 +14,7 @@ autorequire:
15
14
  bindir: bin
16
15
  cert_chain: []
17
16
 
18
- date: 2010-12-06 00:00:00 -08:00
17
+ date: 2010-12-07 00:00:00 -08:00
19
18
  default_executable:
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
@@ -26,7 +25,6 @@ dependencies:
26
25
  requirements:
27
26
  - - ">="
28
27
  - !ruby/object:Gem::Version
29
- hash: 3
30
28
  segments:
31
29
  - 3
32
30
  - 1
@@ -42,7 +40,6 @@ dependencies:
42
40
  requirements:
43
41
  - - ">="
44
42
  - !ruby/object:Gem::Version
45
- hash: 31
46
43
  segments:
47
44
  - 1
48
45
  - 2
@@ -58,7 +55,6 @@ dependencies:
58
55
  requirements:
59
56
  - - ">="
60
57
  - !ruby/object:Gem::Version
61
- hash: 29
62
58
  segments:
63
59
  - 1
64
60
  - 3
@@ -74,7 +70,6 @@ dependencies:
74
70
  requirements:
75
71
  - - ">="
76
72
  - !ruby/object:Gem::Version
77
- hash: 11
78
73
  segments:
79
74
  - 0
80
75
  - 5
@@ -90,7 +85,6 @@ dependencies:
90
85
  requirements:
91
86
  - - ">="
92
87
  - !ruby/object:Gem::Version
93
- hash: 15
94
88
  segments:
95
89
  - 2
96
90
  - 0
@@ -106,7 +100,6 @@ dependencies:
106
100
  requirements:
107
101
  - - ">="
108
102
  - !ruby/object:Gem::Version
109
- hash: 7
110
103
  segments:
111
104
  - 2
112
105
  - 0
@@ -122,7 +115,6 @@ dependencies:
122
115
  requirements:
123
116
  - - ">="
124
117
  - !ruby/object:Gem::Version
125
- hash: 47
126
118
  segments:
127
119
  - 0
128
120
  - 9
@@ -138,7 +130,6 @@ dependencies:
138
130
  requirements:
139
131
  - - ">="
140
132
  - !ruby/object:Gem::Version
141
- hash: 19
142
133
  segments:
143
134
  - 2
144
135
  - 6
@@ -195,7 +186,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
195
186
  requirements:
196
187
  - - ">="
197
188
  - !ruby/object:Gem::Version
198
- hash: 3
189
+ hash: 1889693282695565885
199
190
  segments:
200
191
  - 0
201
192
  version: "0"
@@ -204,7 +195,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
204
195
  requirements:
205
196
  - - ">="
206
197
  - !ruby/object:Gem::Version
207
- hash: 3
208
198
  segments:
209
199
  - 0
210
200
  version: "0"