sinew 2.0.2 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +26 -0
  3. data/.rubocop.yml +9 -6
  4. data/.vscode/settings.json +0 -10
  5. data/Gemfile +9 -0
  6. data/README.md +62 -54
  7. data/Rakefile +33 -18
  8. data/bin/sinew +2 -0
  9. data/lib/sinew.rb +0 -1
  10. data/lib/sinew/connection.rb +52 -0
  11. data/lib/sinew/connection/log_formatter.rb +22 -0
  12. data/lib/sinew/connection/rate_limit.rb +29 -0
  13. data/lib/sinew/core_ext.rb +1 -1
  14. data/lib/sinew/dsl.rb +10 -6
  15. data/lib/sinew/main.rb +29 -56
  16. data/lib/sinew/output.rb +7 -16
  17. data/lib/sinew/request.rb +22 -87
  18. data/lib/sinew/response.rb +8 -57
  19. data/lib/sinew/runtime_options.rb +4 -4
  20. data/lib/sinew/version.rb +1 -1
  21. data/sample.sinew +2 -2
  22. data/sinew.gemspec +16 -18
  23. metadata +38 -110
  24. data/.travis.yml +0 -4
  25. data/lib/sinew/cache.rb +0 -79
  26. data/test/legacy/eu.httpbin.org/head/redirect,3 +0 -51
  27. data/test/legacy/eu.httpbin.org/head/status,500 +0 -1
  28. data/test/legacy/eu.httpbin.org/redirect,3 +0 -11
  29. data/test/legacy/eu.httpbin.org/status,500 +0 -1
  30. data/test/legacy/legacy.sinew +0 -2
  31. data/test/recipes/array_header.sinew +0 -6
  32. data/test/recipes/basic.sinew +0 -8
  33. data/test/recipes/dups.sinew +0 -7
  34. data/test/recipes/implicit_header.sinew +0 -5
  35. data/test/recipes/limit.sinew +0 -11
  36. data/test/recipes/noko.sinew +0 -9
  37. data/test/recipes/uri.sinew +0 -11
  38. data/test/recipes/xml.sinew +0 -8
  39. data/test/test.html +0 -45
  40. data/test/test_cache.rb +0 -69
  41. data/test/test_helper.rb +0 -123
  42. data/test/test_legacy.rb +0 -23
  43. data/test/test_main.rb +0 -34
  44. data/test/test_nokogiri_ext.rb +0 -18
  45. data/test/test_output.rb +0 -56
  46. data/test/test_recipes.rb +0 -60
  47. data/test/test_requests.rb +0 -135
  48. data/test/test_utf8.rb +0 -39
@@ -1,18 +0,0 @@
1
- require_relative 'test_helper'
2
-
3
- class TestNokogiriExt < MiniTest::Test
4
- def test_inner_text
5
- assert_equal('hello world', noko.css('li').inner_text)
6
- assert_equal('<li>hello</li> <li>world</li>', noko.css('ul').inner_html.squish)
7
- end
8
-
9
- def test_just_me
10
- assert_equal('a', noko.css('div').text_just_me.squish)
11
- assert_equal('b b', noko.css('p').text_just_me.squish)
12
- end
13
-
14
- def noko
15
- @noko ||= Nokogiri::HTML(HTML).css('#nokogiri_ext')
16
- end
17
- protected :noko
18
- end
data/test/test_output.rb DELETED
@@ -1,56 +0,0 @@
1
- require_relative 'test_helper'
2
-
3
- class TestOutput < MiniTest::Test
4
- def test_filenames
5
- sinew = Sinew::Main.new(recipe: 'gub.sinew')
6
- assert_equal 'gub.csv', sinew.output.filename
7
- sinew = Sinew::Main.new(recipe: 'gub')
8
- assert_equal 'gub.csv', sinew.output.filename
9
- sinew = Sinew::Main.new(recipe: '/somewhere/gub.sinew')
10
- assert_equal '/somewhere/gub.csv', sinew.output.filename
11
- end
12
-
13
- def test_normalization
14
- output = Sinew::Output.new(nil)
15
-
16
- #
17
- # simple types
18
- #
19
-
20
- assert_equal '', output.send(:normalize, nil)
21
- assert_equal '', output.send(:normalize, '')
22
- assert_equal 'text', output.send(:normalize, 'text')
23
- assert_equal '123', output.send(:normalize, 123)
24
- assert_equal('1|2', output.send(:normalize, [ 1, 2 ]))
25
-
26
- #
27
- # nokogiri
28
- #
29
-
30
- noko = Nokogiri::HTML(HTML)
31
-
32
- # node => text
33
- assert_equal('text', output.send(:normalize, noko.css('#element')))
34
- # nodes => text joined with space
35
- assert_equal('text1 text2', output.send(:normalize, noko.css('.e')))
36
-
37
- #
38
- # string cleanups
39
- #
40
-
41
- # strip_html_tags
42
- assert_equal('gub', output.send(:normalize, '<tag>gub</tag>'))
43
- # strip_html_tags and replace with spaces
44
- assert_equal('hello world', output.send(:normalize, '<tag>hello<br>world</tag>'))
45
- # convert_smart_punctuation
46
- assert_equal('"gub"', output.send(:normalize, "\302\223gub\302\224"))
47
- # convert_accented_html_entities
48
- assert_equal('a', output.send(:normalize, '&aacute;'))
49
- # convert_miscellaneous_html_entities
50
- assert_equal('<>', output.send(:normalize, '&lt;&gt;'))
51
- # to_ascii
52
- assert_equal('cafe', output.send(:normalize, "caf\xc3\xa9"))
53
- # squish
54
- assert_equal('hello world', output.send(:normalize, "\nhello \t \rworld"))
55
- end
56
- end
data/test/test_recipes.rb DELETED
@@ -1,60 +0,0 @@
1
- require_relative 'test_helper'
2
-
3
- class TestRecipe < MiniTest::Test
4
- DIR = File.expand_path('recipes', __dir__)
5
- TEST_SINEW = "#{TMP}/test.sinew".freeze
6
- TEST_CSV = "#{TMP}/test.csv".freeze
7
-
8
- def test_recipes
9
- Dir.chdir(DIR) do
10
- Dir['*.sinew'].sort.each do |filename|
11
- recipe = IO.read(filename)
12
-
13
- # get ready
14
- IO.write(TEST_SINEW, recipe)
15
- sinew = Sinew::Main.new(cache: TMP, quiet: true, recipe: TEST_SINEW)
16
-
17
- # read OPTIONS
18
- if options = options_from(recipe)
19
- options.each do |key, value|
20
- sinew.options[key] = value
21
- end
22
- end
23
-
24
- # read OUTPUT
25
- output = output_from(recipe, filename)
26
-
27
- # run
28
- sinew.run
29
-
30
- # assert
31
- csv = IO.read(TEST_CSV)
32
- assert_equal(output, csv, "Output didn't match for recipes/#{filename}")
33
- end
34
- end
35
- end
36
-
37
- def options_from(recipe)
38
- if options = recipe[/^#\s*OPTIONS\s*(\{.*\})/, 1]
39
- # rubocop:disable Security/Eval
40
- eval(options)
41
- # rubocop:enable Security/Eval
42
- end
43
- end
44
- protected :options_from
45
-
46
- def output_from(recipe, filename)
47
- lines = recipe.split("\n")
48
- first_line = lines.index { |i| i =~ /^# OUTPUT/ }
49
- if !first_line
50
- raise "# OUTPUT not found in recipes/#{filename}"
51
- end
52
-
53
- output = lines[first_line + 1..-1]
54
- output = output.map { |i| i.gsub(/^# /, '') }
55
- output = output.join("\n")
56
- output += "\n"
57
- output
58
- end
59
- protected :output_from
60
- end
@@ -1,135 +0,0 @@
1
- require_relative 'test_helper'
2
-
3
- class TestRequests < MiniTest::Test
4
- def test_user_agent
5
- sinew.dsl.get('http://httpbin.org/get', a: 1, b: 2)
6
- assert_match(/sinew/, sinew.dsl.json[:headers][:'User-Agent'])
7
- end
8
-
9
- def test_basic_methods
10
- sinew.dsl.get('http://httpbin.org/get', a: 1, b: 2)
11
- assert_equal({ a: '1', b: '2' }, sinew.dsl.json[:args])
12
-
13
- sinew.dsl.post('http://httpbin.org/post', a: 1, b: 2)
14
- assert_equal({ a: '1', b: '2' }, sinew.dsl.json[:form])
15
-
16
- sinew.dsl.post_json('http://httpbin.org/post', a: 1, b: 2)
17
- assert_equal({ a: 1, b: 2 }, sinew.dsl.json[:json])
18
- end
19
-
20
- def test_custom_headers
21
- sinew.dsl.http('get', 'http://httpbin.org/get', headers: { "User-Agent": '007' })
22
- assert_match(/007/, sinew.dsl.json[:headers][:'User-Agent'])
23
- end
24
-
25
- def test_redirects
26
- # absolute redirect
27
- sinew.dsl.get('http://httpbin.org/redirect/2')
28
- assert_equal 'http://httpbin.org/get', sinew.dsl.url
29
-
30
- # and relative redirect
31
- sinew.dsl.get('http://httpbin.org/relative-redirect/2')
32
- assert_equal 'http://httpbin.org/get', sinew.dsl.url
33
- end
34
-
35
- def test_errors
36
- skip if test_network?
37
-
38
- # 500
39
- assert_output(/failed with 500/) do
40
- sinew.dsl.get('http://httpbin.org/status/500')
41
- assert_equal '500', sinew.dsl.raw
42
- end
43
-
44
- # timeout
45
- assert_output(/failed with 999/) do
46
- sinew.dsl.get('http://httpbin.org/delay/1')
47
- assert_equal 'timeout', sinew.dsl.raw
48
- end
49
- end
50
-
51
- def test_retry_timeout
52
- skip if test_network?
53
-
54
- errors = 2
55
- stub_request(:get, %r{http://[^/]+/error}).to_return do
56
- if errors > 0
57
- errors -= 1
58
- raise Timeout::Error
59
- end
60
- { body: 'done', status: 200 }
61
- end
62
- sinew.dsl.get('http://httpbin.org/error')
63
- assert_equal 0, errors
64
- assert_equal 'done', sinew.dsl.raw
65
- end
66
-
67
- def test_retry_500
68
- skip if test_network?
69
-
70
- errors = 2
71
- stub_request(:get, %r{http://[^/]+/error}).to_return do
72
- if errors > 0
73
- errors -= 1
74
- return { status: 500 }
75
- end
76
- { body: 'done', status: 200 }
77
- end
78
- sinew.dsl.get('http://httpbin.org/error')
79
- assert_equal 0, errors
80
- assert_equal 'done', sinew.dsl.raw
81
- end
82
-
83
- def test_cache_key
84
- # empty
85
- req = Sinew::Request.new(sinew, 'get', 'http://host')
86
- assert_equal req.cache_key, 'host/_root_'
87
-
88
- # path
89
- req = Sinew::Request.new(sinew, 'get', 'http://host/path')
90
- assert_equal req.cache_key, 'host/path'
91
-
92
- # query
93
- req = Sinew::Request.new(sinew, 'get', 'http://host/path', query: { a: 'b' })
94
- assert_equal req.cache_key, 'host/path,a=b'
95
-
96
- # post with body
97
- req = Sinew::Request.new(sinew, 'post', 'http://host/path', body: { c: 'd' })
98
- assert_equal req.cache_key, 'host/post,path,c=d'
99
-
100
- # too long should turn into digest
101
- path = 'xyz' * 123
102
- req = Sinew::Request.new(sinew, 'get', "http://host/#{path}")
103
- assert_equal "host/#{Digest::MD5.hexdigest(path)}", req.cache_key
104
- end
105
-
106
- def test_before_generate_cache_key
107
- sinew.runtime_options.before_generate_cache_key = method(:redact_cache_key)
108
- req = Sinew::Request.new(sinew, 'get', 'http://host', query: { secret: 'xyz' })
109
- assert_equal 'host/secret=redacted', req.cache_key
110
- end
111
-
112
- def test_urls
113
- # simple
114
- req = Sinew::Request.new(sinew, 'get', 'https://host')
115
- assert_equal 'https://host', req.uri.to_s
116
-
117
- # with query
118
- req = Sinew::Request.new(sinew, 'get', 'https://host', query: { a: 1 })
119
- assert_equal 'https://host?a=1', req.uri.to_s
120
-
121
- # entity decoding
122
- req = Sinew::Request.new(sinew, 'get', 'https://host?a=&lt;5')
123
- assert_equal 'https://host?a=%3C5', req.uri.to_s
124
-
125
- # sloppy urls
126
- req = Sinew::Request.new(sinew, 'get', 'https://host?a=b c&d=f\'g')
127
- assert_equal 'https://host?a=b%20c&d=f%27g', req.uri.to_s
128
- end
129
-
130
- def redact_cache_key(key)
131
- key[:query].gsub!(/secret=[^&]+/, 'secret=redacted')
132
- key
133
- end
134
- protected :redact_cache_key
135
- end
data/test/test_utf8.rb DELETED
@@ -1,39 +0,0 @@
1
- require_relative 'test_helper'
2
-
3
- class TestRequests < MiniTest::Test
4
- def test_get
5
- # network (or stub)
6
- sinew.dsl.get('http://httpbin.org/get')
7
- assert_equal 'UTF-8', sinew.dsl.raw.encoding.name
8
-
9
- # disk
10
- sinew.dsl.get('http://httpbin.org/get')
11
- assert_equal 'UTF-8', sinew.dsl.raw.encoding.name
12
- end
13
-
14
- def test_utf8
15
- skip if !test_network?
16
-
17
- # network
18
- sinew.dsl.get('http://httpbin.org/encoding/utf8')
19
- assert_equal 'UTF-8', sinew.dsl.raw.encoding.name
20
- assert_match(/∑/, sinew.dsl.raw)
21
-
22
- # disk
23
- sinew.dsl.get('http://httpbin.org/encoding/utf8')
24
- assert_equal 'UTF-8', sinew.dsl.raw.encoding.name
25
- assert_match(/∑/, sinew.dsl.raw)
26
- end
27
-
28
- def test_encode
29
- skip if !test_network?
30
-
31
- # network
32
- sinew.dsl.get('https://www.google.co.jp')
33
- assert_equal 'UTF-8', sinew.dsl.raw.encoding.name
34
-
35
- # disk
36
- sinew.dsl.get('https://www.google.co.jp')
37
- assert_equal 'UTF-8', sinew.dsl.raw.encoding.name
38
- end
39
- end