kronk 1.0.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.
- data/.autotest +23 -0
- data/History.txt +6 -0
- data/Manifest.txt +14 -0
- data/README.txt +118 -0
- data/Rakefile +20 -0
- data/bin/kronk +13 -0
- data/lib/kronk.rb +404 -0
- data/lib/kronk/data_set.rb +230 -0
- data/lib/kronk/diff.rb +210 -0
- data/lib/kronk/plist_parser.rb +15 -0
- data/lib/kronk/request.rb +191 -0
- data/lib/kronk/response.rb +226 -0
- data/lib/kronk/xml_parser.rb +108 -0
- data/test/test_data_set.rb +410 -0
- data/test/test_diff.rb +427 -0
- data/test/test_helper.rb +37 -0
- data/test/test_kronk.rb +192 -0
- data/test/test_request.rb +225 -0
- data/test/test_response.rb +258 -0
- data/test/test_xml_parser.rb +101 -0
- metadata +225 -0
data/test/test_helper.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
require "kronk"
|
3
|
+
require "mocha"
|
4
|
+
|
5
|
+
|
6
|
+
def mock_200_response
|
7
|
+
@mock_200 ||= File.read 'test/mocks/200_response.txt'
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
def mock_301_response
|
12
|
+
@mock_301 ||= File.read 'test/mocks/301_response.txt'
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
def mock_302_response
|
17
|
+
@mock_302 ||= File.read 'test/mocks/302_response.txt'
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
def mock_data
|
22
|
+
{
|
23
|
+
"root" => [
|
24
|
+
["B1", "B2"],
|
25
|
+
["A1", "A2"],
|
26
|
+
["C1", "C2", ["C3a", "C3b"]],
|
27
|
+
{:tests=>["D3a", "D3b"],
|
28
|
+
"test"=>[["D1a\nContent goes here", "D1b"], "D2"]}
|
29
|
+
],
|
30
|
+
"acks"=>[[56, 78], ["12", "34"]],
|
31
|
+
"tests"=>{
|
32
|
+
:foo => :bar,
|
33
|
+
"test"=>[[1, 2], 2.123]
|
34
|
+
},
|
35
|
+
"subs"=>["a", "b"]
|
36
|
+
}
|
37
|
+
end
|
data/test/test_kronk.rb
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
require 'test/test_helper'
|
2
|
+
|
3
|
+
class TestKronk < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_default_config
|
6
|
+
expected = {
|
7
|
+
:content_types => {
|
8
|
+
'js' => 'JSON',
|
9
|
+
'json' => 'JSON',
|
10
|
+
'plist' => 'PlistParser',
|
11
|
+
'xml' => 'XMLParser'
|
12
|
+
},
|
13
|
+
:cache_file => Kronk::DEFAULT_CACHE_FILE,
|
14
|
+
:diff_format => :ascii_diff,
|
15
|
+
:requires => []
|
16
|
+
}
|
17
|
+
|
18
|
+
assert_equal expected, Kronk::DEFAULT_CONFIG
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
def test_load_config
|
23
|
+
mock_config = {
|
24
|
+
:content_types => {
|
25
|
+
'soap' => "SOAPParser",
|
26
|
+
'js' => "JsEngine"
|
27
|
+
},
|
28
|
+
:ignore_headers => ["Content-Type"],
|
29
|
+
:cache_file => Kronk::DEFAULT_CACHE_FILE,
|
30
|
+
:requires => [],
|
31
|
+
:foo => :bar
|
32
|
+
}
|
33
|
+
|
34
|
+
YAML.expects(:load_file).with(Kronk::DEFAULT_CONFIG_FILE).
|
35
|
+
returns mock_config
|
36
|
+
|
37
|
+
Kronk.load_config
|
38
|
+
|
39
|
+
expected = {
|
40
|
+
:content_types => {
|
41
|
+
'soap' => "SOAPParser",
|
42
|
+
'js' => "JsEngine",
|
43
|
+
'json' => "JSON",
|
44
|
+
'plist' => "PlistParser",
|
45
|
+
'xml' => "XMLParser"
|
46
|
+
},
|
47
|
+
:diff_format => :ascii_diff,
|
48
|
+
:cache_file => Kronk::DEFAULT_CACHE_FILE,
|
49
|
+
:requires => [],
|
50
|
+
:ignore_headers => ["Content-Type"],
|
51
|
+
:foo => :bar
|
52
|
+
}
|
53
|
+
|
54
|
+
assert_equal expected, Kronk.config
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
def test_make_config_file
|
59
|
+
file = mock 'file'
|
60
|
+
file.expects(:<<).with Kronk::DEFAULT_CONFIG.to_yaml
|
61
|
+
File.expects(:open).with(Kronk::DEFAULT_CONFIG_FILE, "w+").yields file
|
62
|
+
|
63
|
+
Kronk.make_config_file
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
def test_parser_for
|
68
|
+
assert_equal JSON, Kronk.parser_for('json')
|
69
|
+
assert_equal Kronk::XMLParser, Kronk.parser_for('xml')
|
70
|
+
assert_equal Kronk::PlistParser, Kronk.parser_for('plist')
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
def test_load_requires
|
75
|
+
old_requires = Kronk.config[:requires]
|
76
|
+
Kronk.config[:requires] = ["mock_lib1"]
|
77
|
+
|
78
|
+
assert_raises LoadError do
|
79
|
+
Kronk.load_requires
|
80
|
+
end
|
81
|
+
|
82
|
+
Kronk.config[:requires] = old_requires
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
def test_load_requires_nil
|
87
|
+
old_requires = Kronk.config[:requires]
|
88
|
+
Kronk.config[:requires] = nil
|
89
|
+
|
90
|
+
assert_nil Kronk.load_requires
|
91
|
+
|
92
|
+
Kronk.config[:requires] = old_requires
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
def test_find_const
|
97
|
+
assert_equal Nokogiri::XML::Document,
|
98
|
+
Kronk.find_const("Nokogiri::XML::Document")
|
99
|
+
|
100
|
+
assert_equal JSON, Kronk.find_const("JSON")
|
101
|
+
|
102
|
+
assert_equal Kronk::XMLParser, Kronk.find_const("XMLParser")
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
def test_compare_raw
|
107
|
+
diff = Kronk.compare "test/mocks/200_response.json",
|
108
|
+
"test/mocks/200_response.xml",
|
109
|
+
:with_headers => true,
|
110
|
+
:raw => true
|
111
|
+
|
112
|
+
resp1 = Kronk::Request.retrieve "test/mocks/200_response.json",
|
113
|
+
:with_headers => true,
|
114
|
+
:raw => true
|
115
|
+
|
116
|
+
resp2 = Kronk::Request.retrieve "test/mocks/200_response.xml",
|
117
|
+
:with_headers => true,
|
118
|
+
:raw => true
|
119
|
+
|
120
|
+
exp_diff = Kronk::Diff.new resp1.selective_string(:with_headers => true),
|
121
|
+
resp2.selective_string(:with_headers => true)
|
122
|
+
|
123
|
+
assert_equal exp_diff.formatted, diff.formatted
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
def test_compare_data
|
128
|
+
diff = Kronk.compare "test/mocks/200_response.json",
|
129
|
+
"test/mocks/200_response.xml",
|
130
|
+
:with_headers => true
|
131
|
+
|
132
|
+
resp1 = Kronk::Request.retrieve "test/mocks/200_response.json",
|
133
|
+
:with_headers => true
|
134
|
+
|
135
|
+
resp2 = Kronk::Request.retrieve "test/mocks/200_response.xml",
|
136
|
+
:with_headers => true
|
137
|
+
|
138
|
+
exp_diff = Kronk::Diff.new_from_data \
|
139
|
+
resp1.selective_data(:with_headers => true),
|
140
|
+
resp2.selective_data(:with_headers => true)
|
141
|
+
|
142
|
+
assert_equal exp_diff.formatted, diff.formatted
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_raw_diff
|
146
|
+
diff = Kronk.raw_diff "test/mocks/200_response.json",
|
147
|
+
"test/mocks/200_response.xml",
|
148
|
+
:with_headers => true
|
149
|
+
|
150
|
+
resp1 = Kronk::Request.retrieve "test/mocks/200_response.json",
|
151
|
+
:with_headers => true,
|
152
|
+
:raw => true
|
153
|
+
|
154
|
+
resp2 = Kronk::Request.retrieve "test/mocks/200_response.xml",
|
155
|
+
:with_headers => true,
|
156
|
+
:raw => true
|
157
|
+
|
158
|
+
exp_diff = Kronk::Diff.new resp1.selective_string(:with_headers => true),
|
159
|
+
resp2.selective_string(:with_headers => true)
|
160
|
+
|
161
|
+
assert_equal exp_diff.formatted, diff.formatted
|
162
|
+
end
|
163
|
+
|
164
|
+
|
165
|
+
def test_data_diff
|
166
|
+
diff = Kronk.data_diff "test/mocks/200_response.json",
|
167
|
+
"test/mocks/200_response.xml",
|
168
|
+
:with_headers => true
|
169
|
+
|
170
|
+
resp1 = Kronk::Request.retrieve "test/mocks/200_response.json",
|
171
|
+
:with_headers => true
|
172
|
+
|
173
|
+
resp2 = Kronk::Request.retrieve "test/mocks/200_response.xml",
|
174
|
+
:with_headers => true
|
175
|
+
|
176
|
+
exp_diff = Kronk::Diff.new_from_data \
|
177
|
+
resp1.selective_data(:with_headers => true),
|
178
|
+
resp2.selective_data(:with_headers => true)
|
179
|
+
|
180
|
+
assert_equal exp_diff.formatted, diff.formatted
|
181
|
+
end
|
182
|
+
|
183
|
+
|
184
|
+
def test_parse_data_path_args
|
185
|
+
argv = %w{this is --argv -- one -two -- -three four}
|
186
|
+
|
187
|
+
assert_equal [%w{one four}, %w{two - three}],
|
188
|
+
Kronk.parse_data_path_args(argv)
|
189
|
+
|
190
|
+
assert_equal %w{this is --argv}, argv
|
191
|
+
end
|
192
|
+
end
|
@@ -0,0 +1,225 @@
|
|
1
|
+
require 'test/test_helper'
|
2
|
+
|
3
|
+
class TestRequest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_follow_redirect
|
6
|
+
resp = mock "resp"
|
7
|
+
resp.expects(:[]).with("Location").returns "http://example.com"
|
8
|
+
|
9
|
+
options = {:follow_redirects => true}
|
10
|
+
Kronk::Request.expects(:retrieve_uri).with("http://example.com", options)
|
11
|
+
|
12
|
+
Kronk::Request.follow_redirect resp, options
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
def test_num_follow_redirect
|
17
|
+
resp = mock "resp"
|
18
|
+
resp.expects(:[]).with("Location").returns "http://example.com"
|
19
|
+
|
20
|
+
options = {:follow_redirects => 1}
|
21
|
+
Kronk::Request.expects(:retrieve_uri).
|
22
|
+
with "http://example.com", :follow_redirects => 0
|
23
|
+
|
24
|
+
Kronk::Request.follow_redirect resp, options
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def test_follow_redirect?
|
29
|
+
resp = mock "resp"
|
30
|
+
resp.expects(:code).returns "300"
|
31
|
+
|
32
|
+
assert Kronk::Request.follow_redirect?(resp, true)
|
33
|
+
|
34
|
+
resp = mock "resp"
|
35
|
+
resp.expects(:code).returns "300"
|
36
|
+
|
37
|
+
assert Kronk::Request.follow_redirect?(resp, 1)
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
def test_dont_follow_redirect?
|
42
|
+
resp = mock "resp"
|
43
|
+
resp.expects(:code).returns "300"
|
44
|
+
|
45
|
+
assert !Kronk::Request.follow_redirect?(resp, false)
|
46
|
+
|
47
|
+
resp = mock "resp"
|
48
|
+
resp.expects(:code).returns "300"
|
49
|
+
|
50
|
+
assert !Kronk::Request.follow_redirect?(resp, 0)
|
51
|
+
|
52
|
+
resp = mock "resp"
|
53
|
+
resp.expects(:code).returns "200"
|
54
|
+
|
55
|
+
assert !Kronk::Request.follow_redirect?(resp, true)
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
def test_retrieve_live
|
60
|
+
query = "http://example.com"
|
61
|
+
options = {:foo => "bar"}
|
62
|
+
Kronk::Request.expects(:retrieve_uri).with query, options
|
63
|
+
|
64
|
+
Kronk::Request.retrieve query, options
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
def test_retrieve_cached
|
69
|
+
query = "path/to/file.txt"
|
70
|
+
options = {:foo => "bar"}
|
71
|
+
Kronk::Request.expects(:retrieve_file).with query, options
|
72
|
+
|
73
|
+
Kronk::Request.retrieve query, options
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
def test_retrieve_file
|
78
|
+
resp = Kronk::Request.retrieve_file "test/mocks/200_response.txt"
|
79
|
+
assert_equal mock_200_response, resp.raw
|
80
|
+
assert_equal "200", resp.code
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
def test_retrieve_file_cache
|
85
|
+
File.expects(:open).with(Kronk::DEFAULT_CACHE_FILE, "r").
|
86
|
+
yields StringIO.new(mock_200_response)
|
87
|
+
|
88
|
+
resp = Kronk::Request.retrieve_file :cache
|
89
|
+
assert_equal mock_200_response, resp.raw
|
90
|
+
assert_equal "200", resp.code
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
def test_retrieve_file_redirect
|
95
|
+
resp2 = Kronk::Request.retrieve_file "test/mocks/200_response.txt"
|
96
|
+
Kronk::Request.expects(:follow_redirect).returns resp2
|
97
|
+
|
98
|
+
resp = Kronk::Request.retrieve_file "test/mocks/301_response.txt",
|
99
|
+
:follow_redirects => true
|
100
|
+
|
101
|
+
assert_equal mock_200_response, resp.raw
|
102
|
+
assert_equal "200", resp.code
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
def test_retrieve_uri
|
107
|
+
expect_request "GET", "http://example.com/request/path?foo=bar"
|
108
|
+
Kronk::Request.retrieve_uri "http://example.com/request/path?foo=bar"
|
109
|
+
end
|
110
|
+
|
111
|
+
|
112
|
+
def test_retrieve_uri_redirect
|
113
|
+
resp = expect_request "GET", "http://example.com/request/path?foo=bar",
|
114
|
+
:status => '301'
|
115
|
+
|
116
|
+
Kronk::Request.expects(:follow_redirect).
|
117
|
+
with resp, :follow_redirects => true
|
118
|
+
|
119
|
+
Kronk::Request.retrieve_uri "http://example.com/request/path?foo=bar",
|
120
|
+
:follow_redirects => true
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
def test_retrieve_uri_redirect_3_times
|
125
|
+
resp = expect_request "POST", "http://example.com/request/path?foo=bar",
|
126
|
+
:status => '301', :data => "foo=bar"
|
127
|
+
|
128
|
+
Kronk::Request.expects(:follow_redirect).
|
129
|
+
with resp, :follow_redirects => 3, :data => {:foo => "bar"}
|
130
|
+
|
131
|
+
Kronk::Request.retrieve_uri "http://example.com/request/path?foo=bar",
|
132
|
+
:follow_redirects => 3, :data => {:foo => "bar"}
|
133
|
+
end
|
134
|
+
|
135
|
+
|
136
|
+
def test_retrieve_uri_redirect_none
|
137
|
+
expect_request "GET", "http://example.com/request/path?foo=bar",
|
138
|
+
:status => 301
|
139
|
+
|
140
|
+
Kronk::Request.expects(:follow_redirect).never
|
141
|
+
|
142
|
+
Kronk::Request.retrieve_uri "http://example.com/request/path?foo=bar"
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_retrieve_uri_post
|
146
|
+
expect_request "POST", "http://example.com/request/path?foo=bar",
|
147
|
+
:data => 'test=thing', :headers => {'X-THING' => 'thing'}
|
148
|
+
|
149
|
+
Kronk::Request.retrieve_uri "http://example.com/request/path?foo=bar",
|
150
|
+
:http_method => :post,
|
151
|
+
:data => {:test => "thing"},
|
152
|
+
:headers => {'X-THING' => 'thing'}
|
153
|
+
end
|
154
|
+
|
155
|
+
|
156
|
+
def test_call_post
|
157
|
+
expect_request "POST", "http://example.com/request/path?foo=bar",
|
158
|
+
:data => {'test' => 'thing'}, :headers => {'X-THING' => 'thing'}
|
159
|
+
|
160
|
+
resp = Kronk::Request.call :post, "http://example.com/request/path?foo=bar",
|
161
|
+
:data => 'test=thing', :headers => {'X-THING' => 'thing'}
|
162
|
+
|
163
|
+
assert_equal mock_200_response, resp.raw
|
164
|
+
end
|
165
|
+
|
166
|
+
|
167
|
+
def test_call_get
|
168
|
+
expect_request "GET", "http://example.com/request/path?foo=bar"
|
169
|
+
resp = Kronk::Request.call :get, "http://example.com/request/path?foo=bar"
|
170
|
+
|
171
|
+
assert_equal mock_200_response, resp.raw
|
172
|
+
end
|
173
|
+
|
174
|
+
|
175
|
+
def test_build_query_hash
|
176
|
+
hash = {
|
177
|
+
:foo => :bar,
|
178
|
+
:a => ['one', 'two'],
|
179
|
+
:b => {:b1 => [1,2], :b2 => "test"}
|
180
|
+
}
|
181
|
+
|
182
|
+
assert_equal "a[]=one&a[]=two&b[b1][]=1&b[b1][]=2&b[b2]=test&foo=bar",
|
183
|
+
Kronk::Request.build_query(hash)
|
184
|
+
end
|
185
|
+
|
186
|
+
|
187
|
+
def test_build_query_non_hash
|
188
|
+
assert_raises ArgumentError do
|
189
|
+
Kronk::Request.build_query [1,2,3]
|
190
|
+
end
|
191
|
+
|
192
|
+
assert_equal "q[]=1&q[]=2&q[]=3", Kronk::Request.build_query([1,2,3], "q")
|
193
|
+
assert_equal "key=val", Kronk::Request.build_query("val", "key")
|
194
|
+
end
|
195
|
+
|
196
|
+
|
197
|
+
private
|
198
|
+
|
199
|
+
def expect_request req_method, url, options={}
|
200
|
+
uri = URI.parse url
|
201
|
+
|
202
|
+
resp = mock 'resp'
|
203
|
+
resp.stubs(:code).returns(options[:status] || '200')
|
204
|
+
|
205
|
+
http = mock 'http'
|
206
|
+
socket = mock 'socket'
|
207
|
+
|
208
|
+
data = options[:data]
|
209
|
+
data &&= Hash === data ? Kronk::Request.build_query(data) : data.to_s
|
210
|
+
|
211
|
+
socket.expects(:debug_output=)
|
212
|
+
|
213
|
+
http.expects(:send_request).
|
214
|
+
with(req_method, uri.request_uri, data, options[:headers]).
|
215
|
+
returns resp
|
216
|
+
|
217
|
+
http.expects(:instance_variable_get).with("@socket").returns socket
|
218
|
+
|
219
|
+
Net::HTTP.expects(:start).with(uri.host, uri.port).yields(http).returns resp
|
220
|
+
|
221
|
+
Kronk::Response.expects(:read_raw_from).returns ["", mock_200_response, 0]
|
222
|
+
|
223
|
+
resp
|
224
|
+
end
|
225
|
+
end
|