saper 0.5.2 → 0.5.3

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 (92) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -3
  3. data/Rakefile +7 -5
  4. data/bin/saper +51 -1
  5. data/lib/saper/actions/create_atom.rb +0 -5
  6. data/lib/saper/actions/nothing.rb +2 -0
  7. data/lib/saper/actions/remove_matching.rb +1 -1
  8. data/lib/saper/actions/run_recipe.rb +5 -5
  9. data/lib/saper/actions/run_recipe_and_save.rb +5 -5
  10. data/lib/saper/actions/select_matching.rb +1 -1
  11. data/lib/saper/actions/set_input.rb +0 -5
  12. data/lib/saper/core/action.rb +69 -53
  13. data/lib/saper/core/argument.rb +3 -0
  14. data/lib/saper/core/browser.rb +3 -2
  15. data/lib/saper/core/error.rb +4 -1
  16. data/lib/saper/core/keychain.rb +2 -2
  17. data/lib/saper/core/logger.rb +9 -54
  18. data/lib/saper/core/recipe.rb +36 -5
  19. data/lib/saper/core/result.rb +36 -5
  20. data/lib/saper/core/runtime.rb +17 -11
  21. data/lib/saper/core/stack.rb +17 -1
  22. data/lib/saper/items/html.rb +1 -1
  23. data/lib/saper/items/nothing.rb +9 -0
  24. data/lib/saper/items/xml.rb +5 -1
  25. data/lib/saper/version.rb +1 -1
  26. data/lib/tungsten/lib/README +5 -0
  27. data/lib/tungsten/lib/test.rb +18 -0
  28. data/lib/tungsten/lib/tungsten.rb +33 -0
  29. data/lib/tungsten/lib/tungsten/headers.rb +37 -0
  30. data/lib/tungsten/lib/tungsten/jar.rb +17 -0
  31. data/lib/tungsten/lib/tungsten/request.rb +102 -0
  32. data/lib/tungsten/lib/tungsten/response.rb +101 -0
  33. data/spec/actions/append_with_spec.rb +144 -21
  34. data/spec/actions/convert_to_html_spec.rb +126 -11
  35. data/spec/actions/convert_to_json_spec.rb +126 -11
  36. data/spec/actions/convert_to_markdown_spec.rb +126 -11
  37. data/spec/actions/convert_to_time_spec.rb +150 -15
  38. data/spec/actions/convert_to_xml_spec.rb +136 -11
  39. data/spec/actions/create_atom_spec.rb +116 -7
  40. data/spec/actions/fetch_spec.rb +110 -3
  41. data/spec/actions/find_first_spec.rb +149 -24
  42. data/spec/actions/find_spec.rb +167 -19
  43. data/spec/actions/get_attribute_spec.rb +145 -15
  44. data/spec/actions/get_contents_spec.rb +125 -4
  45. data/spec/actions/get_text_spec.rb +125 -4
  46. data/spec/actions/nothing_spec.rb +119 -4
  47. data/spec/actions/prepend_with_spec.rb +148 -22
  48. data/spec/actions/remove_after_spec.rb +160 -4
  49. data/spec/actions/remove_before_spec.rb +160 -4
  50. data/spec/actions/remove_matching_spec.rb +164 -4
  51. data/spec/actions/remove_tags_spec.rb +1 -1
  52. data/spec/actions/replace_spec.rb +1 -1
  53. data/spec/actions/run_recipe_and_save_spec.rb +1 -1
  54. data/spec/actions/run_recipe_spec.rb +1 -1
  55. data/spec/actions/save_spec.rb +1 -1
  56. data/spec/actions/select_matching_spec.rb +164 -4
  57. data/spec/actions/set_input_spec.rb +1 -1
  58. data/spec/actions/skip_tags_spec.rb +1 -1
  59. data/spec/actions/split_spec.rb +1 -1
  60. data/spec/arguments/attribute_spec.rb +1 -1
  61. data/spec/arguments/recipe_spec.rb +1 -1
  62. data/spec/arguments/text_spec.rb +1 -1
  63. data/spec/arguments/timezone_spec.rb +1 -1
  64. data/spec/arguments/variable_spec.rb +1 -1
  65. data/spec/arguments/xpath_spec.rb +1 -1
  66. data/spec/core/action_spec.rb +25 -13
  67. data/spec/core/argument_spec.rb +55 -31
  68. data/spec/core/browser_spec.rb +21 -11
  69. data/spec/core/dsl_spec.rb +1 -1
  70. data/spec/core/item_spec.rb +1 -1
  71. data/spec/core/keychain_spec.rb +1 -1
  72. data/spec/core/logger_spec.rb +1 -1
  73. data/spec/core/namespace_spec.rb +1 -1
  74. data/spec/core/recipe_spec.rb +85 -51
  75. data/spec/core/result_spec.rb +1 -1
  76. data/spec/core/runtime_spec.rb +45 -27
  77. data/spec/core/stack_spec.rb +1 -1
  78. data/spec/core/type_spec.rb +1 -1
  79. data/spec/integration/simple_invalid_spec.rb +46 -9
  80. data/spec/integration/simple_valid_spec.rb +9 -9
  81. data/spec/items/atom_spec.rb +7 -7
  82. data/spec/items/document_spec.rb +29 -29
  83. data/spec/items/html_spec.rb +80 -48
  84. data/spec/items/json_spec.rb +17 -11
  85. data/spec/items/markdown_spec.rb +30 -18
  86. data/spec/items/nothing_spec.rb +1 -1
  87. data/spec/items/text_spec.rb +12 -10
  88. data/spec/items/time_spec.rb +35 -21
  89. data/spec/items/url_spec.rb +1 -1
  90. data/spec/items/xml_spec.rb +75 -42
  91. data/spec/spec_helper.rb +90 -2
  92. metadata +51 -16
@@ -0,0 +1,37 @@
1
+ module Tungsten
2
+ class Headers
3
+
4
+ include Enumerable
5
+
6
+ def initialize(hash)
7
+ @hash = hash
8
+ end
9
+
10
+ def has?(name)
11
+ @hash.key?(name.downcase)
12
+ end
13
+
14
+ def [](name)
15
+ has?(name) ? @hash[name.downcase].join(', ') : nil
16
+ end
17
+
18
+ def each(&block)
19
+ @hash.each { |k,v| yield capitalize(k), v.join(', ') }
20
+ end
21
+
22
+ def to_s
23
+ map { |k,v| "%s: %s" % [k, self[k]] }.join("\n")
24
+ end
25
+
26
+ def size
27
+ to_s.size
28
+ end
29
+
30
+ private
31
+
32
+ def capitalize(name)
33
+ name.split(/-/).map {|s| s.capitalize }.join('-')
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,17 @@
1
+ module Tungsten
2
+ class Jar
3
+
4
+ def any?(uri)
5
+ false
6
+ end
7
+
8
+ def for(uri)
9
+ ""
10
+ end
11
+
12
+ def add_from_response(http)
13
+
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,102 @@
1
+ module Tungsten
2
+ class Request
3
+
4
+ attr_reader :method
5
+
6
+ attr_reader :data
7
+
8
+ attr_reader :jar
9
+
10
+ def initialize(method, uri, data: nil, jar: nil, agent: :tungsten)
11
+ @method = method.to_s.upcase
12
+ @uri = URI.parse(uri)
13
+ @jar = jar || Jar.new
14
+ @agent = agent
15
+ @data = data.to_s
16
+ @data = data.read if data.is_a?(IO)
17
+ @req = net_http_request
18
+ end
19
+
20
+ def response
21
+ http = Net::HTTP.new(host, port)
22
+ http.use_ssl = true if ssl?
23
+ resp = http.request(@req)
24
+ jar.add_from_response(resp)
25
+ Response.new(@uri, resp)
26
+ rescue => exception
27
+ puts 'ERROR: %s' % exception
28
+ nil
29
+ end
30
+
31
+ def headers
32
+ Headers.new(@req.to_hash)
33
+ end
34
+
35
+ def scheme
36
+ @uri.scheme
37
+ end
38
+
39
+ def port
40
+ @uri.port
41
+ end
42
+
43
+ def host
44
+ @uri.host
45
+ end
46
+
47
+ def path
48
+ @uri.path.empty? ? "/" : @uri.path
49
+ end
50
+
51
+ def query
52
+ @uri.query
53
+ end
54
+
55
+ def fragment
56
+ @uri.fragment
57
+ end
58
+
59
+ def uri
60
+ @uri.to_s
61
+ end
62
+
63
+ def size
64
+ headers.size + data.size
65
+ end
66
+
67
+ def user_agent
68
+ AGENTS[@agent.to_sym] || @agent.to_s
69
+ end
70
+
71
+ def has_data?
72
+ not @data.empty?
73
+ end
74
+
75
+ def ssl?
76
+ port == 443
77
+ end
78
+
79
+ private
80
+
81
+ def cookie_header
82
+ jar.any?(uri) ? { "Cookie" => jar.for(@uri) } : {}
83
+ end
84
+
85
+ def custom_headers
86
+ cookie_header.merge({ "User-Agent" => user_agent })
87
+ end
88
+
89
+ def req_body?
90
+ %w(GET POST PUT DELETE TRACE PATCH PROPFIND PROPPATCH MKCOL COPY MOVE LOCK UNLOCK).include?(method)
91
+ end
92
+
93
+ def resp_body?
94
+ %w(POST PUT PATCH PROPFIND PROPPATCH MKCOL LOCK UNLOCK).include?(method)
95
+ end
96
+
97
+ def net_http_request
98
+ req = Net::HTTPGenericRequest.new(method, req_body?, resp_body?, path, custom_headers); req.body = data if has_data?; req
99
+ end
100
+
101
+ end
102
+ end
@@ -0,0 +1,101 @@
1
+ module Tungsten
2
+ class Response
3
+
4
+ def initialize(uri, http)
5
+ @uri, @http = uri, http
6
+ end
7
+
8
+ def headers
9
+ Headers.new(@http.to_hash)
10
+ end
11
+
12
+ def uri
13
+ @uri.to_s
14
+ end
15
+
16
+ def code
17
+ @http.code.to_i
18
+ end
19
+
20
+ def message
21
+ @http.message
22
+ end
23
+
24
+ def body
25
+ @http.body
26
+ end
27
+
28
+ def size
29
+ headers.to_s.size + body.to_s.size
30
+ end
31
+
32
+ def ok?
33
+ code == 200
34
+ end
35
+
36
+ def created?
37
+ code == 201
38
+ end
39
+
40
+ def accepted?
41
+ code == 202
42
+ end
43
+
44
+ def no_content?
45
+ code == 204
46
+ end
47
+
48
+ def moved_permanently?
49
+ code == 301
50
+ end
51
+
52
+ def moved_temporarily?
53
+ code == 302 || code == 307
54
+ end
55
+
56
+ def see_other?
57
+ code == 303
58
+ end
59
+
60
+ def not_modified?
61
+ code == 304
62
+ end
63
+
64
+ def redirect?
65
+ moved_permanently? || moved_temporarily? || see_other?
66
+ end
67
+
68
+ def bad_request?
69
+ code == 400
70
+ end
71
+
72
+ def unauthorized?
73
+ code == 401
74
+ end
75
+
76
+ def forbidden?
77
+ code == 403
78
+ end
79
+
80
+ def not_found?
81
+ code == 404
82
+ end
83
+
84
+ def method_not_allowed?
85
+ code == 406
86
+ end
87
+
88
+ def client_error?
89
+ code > 399 && code < 500
90
+ end
91
+
92
+ def server_error?
93
+ code > 499
94
+ end
95
+
96
+ def error?
97
+ client_error? || server_error?
98
+ end
99
+
100
+ end
101
+ end
@@ -1,37 +1,160 @@
1
1
  require './spec/spec_helper'
2
2
 
3
- describe Saper::Actions::AppendWith do
3
+ RSpec.describe Saper::Actions::AppendWith do
4
4
  let :subject do
5
5
  Saper::Actions::AppendWith.new('!')
6
6
  end
7
- it ".new(nil) raises InvalidArgument" do
8
- lambda { Saper::Actions::AppendWith.new(nil) }.must_raise(Saper::InvalidArgument)
7
+ context ".type" do
8
+ it "returns append_with" do
9
+ expect(described_class.type).to eq 'append_with'
10
+ end
9
11
  end
10
- it ".new(Numeric) raises InvalidArgument" do
11
- lambda { Saper::Actions::AppendWith.new(2) }.must_raise(Saper::InvalidArgument)
12
+ context ".accepts?(:atom)" do
13
+ it "returns false" do
14
+ expect(described_class.accepts?(:atom)).to be false
15
+ end
12
16
  end
13
- it ".new(Hash) raises InvalidArgumenth" do
14
- lambda { Saper::Actions::AppendWith.new({}) }.must_raise(Saper::InvalidArgument)
17
+ context ".accepts?(:document)" do
18
+ it "returns false" do
19
+ expect(described_class.accepts?(:document)).to be false
20
+ end
15
21
  end
16
- it ".new(Array) raises InvalidArgument" do
17
- lambda { Saper::Actions::AppendWith.new([]) }.must_raise(Saper::InvalidArgument)
22
+ context ".accepts?(:html)" do
23
+ it "returns false" do
24
+ expect(described_class.accepts?(:html)).to be false
25
+ end
18
26
  end
19
- it ".new(String)returns Action instance" do
20
- Saper::Actions::AppendWith.new("!").must_be_kind_of(Saper::Action)
27
+ context ".accepts?(:json)" do
28
+ it "returns false" do
29
+ expect(described_class.accepts?(:json)).to be false
30
+ end
21
31
  end
22
- it "#run(nil) raises InvalidInput" do
23
- lambda { subject.run(nil) }.must_raise(Saper::InvalidInput)
32
+ context ".accepts?(:markdown)" do
33
+ it "returns false" do
34
+ expect(described_class.accepts?(:markdown)).to be false
35
+ end
24
36
  end
25
- it "#run(Numeric) returns valid output" do
26
- lambda { subject.run(1) }.must_raise(Saper::InvalidInput)
37
+ context ".accepts?(:nothing)" do
38
+ it "returns false" do
39
+ expect(described_class.accepts?(:nothing)).to be false
40
+ end
27
41
  end
28
- it "#run(String) returns valid output" do
29
- subject.run('string').must_be :==, 'string!'
42
+ context ".accepts?(:text)" do
43
+ it "returns true " do
44
+ expect(described_class.accepts?(:text)).to be true
45
+ end
30
46
  end
31
- it "#run(Text) returns valid output" do
32
- subject.run(Saper::Items::Text.new('string')).must_be :==, 'string!'
47
+ context ".accepts?(:time)" do
48
+ it "returns false" do
49
+ expect(described_class.accepts?(:time)).to be false
50
+ end
33
51
  end
34
- it "#run returns Text instance" do
35
- subject.run('string').must_be_instance_of(Saper::Items::Text)
52
+ context ".accepts?(:url)" do
53
+ it "returns false" do
54
+ expect(described_class.accepts?(:url)).to be false
55
+ end
56
+ end
57
+ context ".accepts?(:xml)" do
58
+ it "returns false" do
59
+ expect(described_class.accepts?(:xml)).to be false
60
+ end
61
+ end
62
+ context ".output_for(:atom)" do
63
+ it "returns :nothing" do
64
+ expect(described_class.output_for(:atom)).to be :nothing
65
+ end
66
+ end
67
+ context ".output_for(:document)" do
68
+ it "returns :nothing" do
69
+ expect(described_class.output_for(:document)).to be :nothing
70
+ end
71
+ end
72
+ context ".output_for(:html)" do
73
+ it "returns :nothing" do
74
+ expect(described_class.output_for(:html)).to be :nothing
75
+ end
76
+ end
77
+ context ".output_for(:json)" do
78
+ it "returns :nothing" do
79
+ expect(described_class.output_for(:json)).to be :nothing
80
+ end
81
+ end
82
+ context ".output_for(:markdown)" do
83
+ it "returns :nothing" do
84
+ expect(described_class.output_for(:markdown)).to be :nothing
85
+ end
86
+ end
87
+ context ".output_for(:text)" do
88
+ it "returns :text" do
89
+ expect(described_class.output_for(:text)).to be :text
90
+ end
91
+ end
92
+ context ".output_for(:time)" do
93
+ it "returns :nothing" do
94
+ expect(described_class.output_for(:time)).to be :nothing
95
+ end
96
+ end
97
+ context ".output_for(:url)" do
98
+ it "returns :nothing" do
99
+ expect(described_class.output_for(:url)).to be :nothing
100
+ end
101
+ end
102
+ context ".output_for(:xml)" do
103
+ it "returns :nothing" do
104
+ expect(described_class.output_for(:xml)).to be :nothing
105
+ end
106
+ end
107
+ context ".returns_multiple_items?" do
108
+ it "returns false" do
109
+ expect(described_class.returns_multiple_items?).to be false
110
+ end
111
+ end
112
+ context ".new(nil)" do
113
+ it "raises InvalidArgument" do
114
+ expect { described_class.new(nil) }.to raise_error Saper::InvalidArgument
115
+ end
116
+ end
117
+ context ".new(Numeric)" do
118
+ it "raises InvalidArgument" do
119
+ expect { described_class.new(2) }.to raise_error Saper::InvalidArgument
120
+ end
121
+ end
122
+ context ".new(Hash)" do
123
+ it "raises InvalidArgumenth" do
124
+ expect { described_class.new({}) }.to raise_error Saper::InvalidArgument
125
+ end
126
+ end
127
+ context ".new(Array)" do
128
+ it "raises InvalidArgument" do
129
+ expect { described_class.new([]) }.to raise_error Saper::InvalidArgument
130
+ end
131
+ end
132
+ context ".new(String)" do
133
+ it "returns Action instance" do
134
+ expect(described_class.new("!")).to be_a Saper::Action
135
+ end
136
+ end
137
+ context "#run(nil)" do
138
+ it "raises InvalidInput" do
139
+ expect { subject.run(nil) }.to raise_error Saper::InvalidInput
140
+ end
141
+ end
142
+ context "#run(Numeric)" do
143
+ it "raises InvalidInput" do
144
+ expect { subject.run(1) }.to raise_error Saper::InvalidInput
145
+ end
146
+ end
147
+ context "#run(String)" do
148
+ it "returns Text instance" do
149
+ expect(subject.run('string')).to be_a Saper::Items::Text
150
+ end
151
+ it "returns valid output" do
152
+ expect(subject.run('string').to_s).to eq 'string!'
153
+ end
154
+ end
155
+ context "#run(Text)" do
156
+ it "returns valid output" do
157
+ expect(subject.run(Saper::Items::Text.new('string'))).to eq 'string!'
158
+ end
36
159
  end
37
160
  end
@@ -1,22 +1,137 @@
1
1
  require './spec/spec_helper'
2
2
 
3
- describe Saper::Actions::ConvertToHTML do
3
+ RSpec.describe Saper::Actions::ConvertToHTML do
4
4
  let :subject do
5
5
  Saper::Actions::ConvertToHTML.new
6
6
  end
7
- it "#run(nil) raises InvalidInput" do
8
- lambda { subject.run(nil) }.must_raise(Saper::InvalidInput)
7
+ context ".type" do
8
+ it "returns convert_to_html" do
9
+ expect(described_class.type).to eq 'convert_to_html'
10
+ end
9
11
  end
10
- it "#run(Numeric) raises InvalidInput" do
11
- lambda { subject.run(2) }.must_raise(Saper::InvalidInput)
12
+ context ".accepts?(:atom)" do
13
+ it "returns false" do
14
+ expect(described_class.accepts?(:atom)).to be false
15
+ end
12
16
  end
13
- it "#run(invalid String) returns HTML instance" do
14
- subject.run("not html").must_be_instance_of(Saper::Items::HTML)
17
+ context ".accepts?(:document)" do
18
+ it "returns false" do
19
+ expect(described_class.accepts?(:document)).to be true
20
+ end
15
21
  end
16
- it "#run(valid String) returns HTML instance" do
17
- subject.run('<p>test</p>').must_be_instance_of(Saper::Items::HTML)
22
+ context ".accepts?(:html)" do
23
+ it "returns false" do
24
+ expect(described_class.accepts?(:html)).to be false
25
+ end
18
26
  end
19
- it "#run(valid Text) returns HTML instance" do
20
- subject.run(Saper::Items::Text.new('<p>test</p>')).must_be_instance_of(Saper::Items::HTML)
27
+ context ".accepts?(:json)" do
28
+ it "returns false" do
29
+ expect(described_class.accepts?(:json)).to be false
30
+ end
31
+ end
32
+ context ".accepts?(:markdown)" do
33
+ it "returns false" do
34
+ expect(described_class.accepts?(:markdown)).to be false
35
+ end
36
+ end
37
+ context ".accepts?(:nothing)" do
38
+ it "returns false" do
39
+ expect(described_class.accepts?(:nothing)).to be false
40
+ end
41
+ end
42
+ context ".accepts?(:text)" do
43
+ it "returns true " do
44
+ expect(described_class.accepts?(:text)).to be true
45
+ end
46
+ end
47
+ context ".accepts?(:time)" do
48
+ it "returns false" do
49
+ expect(described_class.accepts?(:time)).to be false
50
+ end
51
+ end
52
+ context ".accepts?(:url)" do
53
+ it "returns false" do
54
+ expect(described_class.accepts?(:url)).to be false
55
+ end
56
+ end
57
+ context ".accepts?(:xml)" do
58
+ it "returns false" do
59
+ expect(described_class.accepts?(:xml)).to be false
60
+ end
61
+ end
62
+ context ".output_for(:atom)" do
63
+ it "returns :nothing" do
64
+ expect(described_class.output_for(:atom)).to be :nothing
65
+ end
66
+ end
67
+ context ".output_for(:document)" do
68
+ it "returns :nothing" do
69
+ expect(described_class.output_for(:document)).to be :html
70
+ end
71
+ end
72
+ context ".output_for(:html)" do
73
+ it "returns :nothing" do
74
+ expect(described_class.output_for(:html)).to be :nothing
75
+ end
76
+ end
77
+ context ".output_for(:json)" do
78
+ it "returns :nothing" do
79
+ expect(described_class.output_for(:json)).to be :nothing
80
+ end
81
+ end
82
+ context ".output_for(:markdown)" do
83
+ it "returns :nothing" do
84
+ expect(described_class.output_for(:markdown)).to be :nothing
85
+ end
86
+ end
87
+ context ".output_for(:text)" do
88
+ it "returns :text" do
89
+ expect(described_class.output_for(:text)).to be :html
90
+ end
91
+ end
92
+ context ".output_for(:time)" do
93
+ it "returns :nothing" do
94
+ expect(described_class.output_for(:time)).to be :nothing
95
+ end
96
+ end
97
+ context ".output_for(:url)" do
98
+ it "returns :nothing" do
99
+ expect(described_class.output_for(:url)).to be :nothing
100
+ end
101
+ end
102
+ context ".output_for(:xml)" do
103
+ it "returns :nothing" do
104
+ expect(described_class.output_for(:xml)).to be :nothing
105
+ end
106
+ end
107
+ context ".returns_multiple_items?" do
108
+ it "returns false" do
109
+ expect(described_class.returns_multiple_items?).to be false
110
+ end
111
+ end
112
+ context "#run(nil)" do
113
+ it "raises InvalidInput" do
114
+ expect { subject.run(nil) }.to raise_error Saper::InvalidInput
115
+ end
116
+ end
117
+ context "#run(Numeric)" do
118
+ it "raises InvalidInput" do
119
+ expect { subject.run(2) }.to raise_error Saper::InvalidInput
120
+ end
121
+ end
122
+ context "#run(invalid String)" do
123
+ it "returns HTML instance" do
124
+ expect(subject.run("not html")).to be_a Saper::Items::HTML
125
+ end
126
+ end
127
+ context "#run(valid String)" do
128
+ it "returns HTML instance" do
129
+ expect(subject.run('<p>test</p>')).to be_a Saper::Items::HTML
130
+ end
131
+ end
132
+ context "#run(valid Text)" do
133
+ it "returns HTML instance" do
134
+ expect(subject.run(Saper::Items::Text.new('<p>test</p>'))).to be_a Saper::Items::HTML
135
+ end
21
136
  end
22
137
  end