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 +14 -0
- data/README.txt +3 -3
- data/lib/kronk.rb +29 -8
- data/lib/kronk/diff.rb +113 -36
- data/lib/kronk/request.rb +6 -2
- data/lib/kronk/response.rb +2 -0
- data/test/test_diff.rb +63 -12
- data/test/test_kronk.rb +3 -0
- metadata +4 -14
data/History.txt
CHANGED
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
|
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.
|
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
|
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
|
-
|
361
|
-
|
362
|
-
|
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
|
-
|
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
|
69
|
-
@str2
|
70
|
-
@char
|
71
|
-
@diff_ary
|
72
|
-
@
|
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
|
151
|
-
|
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
|
-
|
155
|
-
|
156
|
-
|
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
|
-
|
241
|
+
when Array
|
242
|
+
item = item.dup
|
161
243
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
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
|
-
#
|
263
|
+
# Returns the number of diffs found.
|
178
264
|
|
179
|
-
def
|
180
|
-
|
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
|
data/lib/kronk/response.rb
CHANGED
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,
|
311
|
+
assert_equal diff_302_301_color,
|
312
|
+
@diff.formatted(:formatter => Kronk::Diff::ColorFormat)
|
301
313
|
|
302
|
-
@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,
|
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
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
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
|
-
-
|
10
|
-
version: 1.0.
|
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-
|
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:
|
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"
|