kronk 1.0.1 → 1.0.2

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