sinew 2.0.2 → 3.0.1

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.
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