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