dh_easy-core 0.2.2

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 (79) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.travis.yml +7 -0
  4. data/.yardopts +1 -0
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +6 -0
  7. data/LICENSE +21 -0
  8. data/README.md +20 -0
  9. data/Rakefile +22 -0
  10. data/dh_easy-core.gemspec +50 -0
  11. data/doc/DhEasy.html +117 -0
  12. data/doc/DhEasy/Core.html +1590 -0
  13. data/doc/DhEasy/Core/Config.html +311 -0
  14. data/doc/DhEasy/Core/Exception.html +117 -0
  15. data/doc/DhEasy/Core/Exception/OutdatedError.html +135 -0
  16. data/doc/DhEasy/Core/Helper.html +117 -0
  17. data/doc/DhEasy/Core/Helper/Cookie.html +1070 -0
  18. data/doc/DhEasy/Core/Mock.html +282 -0
  19. data/doc/DhEasy/Core/Mock/FakeDb.html +3779 -0
  20. data/doc/DhEasy/Core/Mock/FakeExecutor.html +3289 -0
  21. data/doc/DhEasy/Core/Mock/FakeFinisher.html +160 -0
  22. data/doc/DhEasy/Core/Mock/FakeParser.html +160 -0
  23. data/doc/DhEasy/Core/Mock/FakeSeeder.html +160 -0
  24. data/doc/DhEasy/Core/Plugin.html +117 -0
  25. data/doc/DhEasy/Core/Plugin/CollectionVault.html +299 -0
  26. data/doc/DhEasy/Core/Plugin/ConfigBehavior.html +541 -0
  27. data/doc/DhEasy/Core/Plugin/ContextIntegrator.html +445 -0
  28. data/doc/DhEasy/Core/Plugin/Executor.html +259 -0
  29. data/doc/DhEasy/Core/Plugin/ExecutorBehavior.html +344 -0
  30. data/doc/DhEasy/Core/Plugin/Finisher.html +265 -0
  31. data/doc/DhEasy/Core/Plugin/FinisherBehavior.html +142 -0
  32. data/doc/DhEasy/Core/Plugin/InitializeHook.html +220 -0
  33. data/doc/DhEasy/Core/Plugin/Parser.html +270 -0
  34. data/doc/DhEasy/Core/Plugin/ParserBehavior.html +235 -0
  35. data/doc/DhEasy/Core/Plugin/Seeder.html +674 -0
  36. data/doc/DhEasy/Core/Plugin/SeederBehavior.html +142 -0
  37. data/doc/DhEasy/Core/SmartCollection.html +1087 -0
  38. data/doc/_index.html +364 -0
  39. data/doc/class_list.html +51 -0
  40. data/doc/css/common.css +1 -0
  41. data/doc/css/full_list.css +58 -0
  42. data/doc/css/style.css +496 -0
  43. data/doc/file.README.html +91 -0
  44. data/doc/file_list.html +56 -0
  45. data/doc/frames.html +17 -0
  46. data/doc/index.html +91 -0
  47. data/doc/js/app.js +303 -0
  48. data/doc/js/full_list.js +216 -0
  49. data/doc/js/jquery.js +4 -0
  50. data/doc/method_list.html +939 -0
  51. data/doc/top-level-namespace.html +110 -0
  52. data/lib/dh_easy/core.rb +257 -0
  53. data/lib/dh_easy/core/config.rb +27 -0
  54. data/lib/dh_easy/core/exception.rb +8 -0
  55. data/lib/dh_easy/core/exception/outdated_error.rb +9 -0
  56. data/lib/dh_easy/core/helper.rb +8 -0
  57. data/lib/dh_easy/core/helper/cookie.rb +209 -0
  58. data/lib/dh_easy/core/mock.rb +45 -0
  59. data/lib/dh_easy/core/mock/fake_db.rb +561 -0
  60. data/lib/dh_easy/core/mock/fake_executor.rb +373 -0
  61. data/lib/dh_easy/core/mock/fake_finisher.rb +28 -0
  62. data/lib/dh_easy/core/mock/fake_parser.rb +33 -0
  63. data/lib/dh_easy/core/mock/fake_seeder.rb +28 -0
  64. data/lib/dh_easy/core/plugin.rb +19 -0
  65. data/lib/dh_easy/core/plugin/collection_vault.rb +23 -0
  66. data/lib/dh_easy/core/plugin/config_behavior.rb +43 -0
  67. data/lib/dh_easy/core/plugin/context_integrator.rb +60 -0
  68. data/lib/dh_easy/core/plugin/executor.rb +19 -0
  69. data/lib/dh_easy/core/plugin/executor_behavior.rb +32 -0
  70. data/lib/dh_easy/core/plugin/finisher.rb +19 -0
  71. data/lib/dh_easy/core/plugin/finisher_behavior.rb +9 -0
  72. data/lib/dh_easy/core/plugin/initialize_hook.rb +17 -0
  73. data/lib/dh_easy/core/plugin/parser.rb +19 -0
  74. data/lib/dh_easy/core/plugin/parser_behavior.rb +17 -0
  75. data/lib/dh_easy/core/plugin/seeder.rb +44 -0
  76. data/lib/dh_easy/core/plugin/seeder_behavior.rb +9 -0
  77. data/lib/dh_easy/core/smart_collection.rb +236 -0
  78. data/lib/dh_easy/core/version.rb +6 -0
  79. metadata +249 -0
@@ -0,0 +1,110 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>
7
+ Top Level Namespace
8
+
9
+ &mdash; Documentation by YARD 0.9.20
10
+
11
+ </title>
12
+
13
+ <link rel="stylesheet" href="css/style.css" type="text/css" charset="utf-8" />
14
+
15
+ <link rel="stylesheet" href="css/common.css" type="text/css" charset="utf-8" />
16
+
17
+ <script type="text/javascript" charset="utf-8">
18
+ pathId = "";
19
+ relpath = '';
20
+ </script>
21
+
22
+
23
+ <script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
24
+
25
+ <script type="text/javascript" charset="utf-8" src="js/app.js"></script>
26
+
27
+
28
+ </head>
29
+ <body>
30
+ <div class="nav_wrap">
31
+ <iframe id="nav" src="class_list.html?1"></iframe>
32
+ <div id="resizer"></div>
33
+ </div>
34
+
35
+ <div id="main" tabindex="-1">
36
+ <div id="header">
37
+ <div id="menu">
38
+
39
+ <a href="_index.html">Index</a> &raquo;
40
+
41
+
42
+ <span class="title">Top Level Namespace</span>
43
+
44
+ </div>
45
+
46
+ <div id="search">
47
+
48
+ <a class="full_list_link" id="class_list_link"
49
+ href="class_list.html">
50
+
51
+ <svg width="24" height="24">
52
+ <rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
53
+ <rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
54
+ <rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
55
+ </svg>
56
+ </a>
57
+
58
+ </div>
59
+ <div class="clear"></div>
60
+ </div>
61
+
62
+ <div id="content"><h1>Top Level Namespace
63
+
64
+
65
+
66
+ </h1>
67
+ <div class="box_info">
68
+
69
+
70
+
71
+
72
+
73
+
74
+
75
+
76
+
77
+
78
+
79
+ </div>
80
+
81
+ <h2>Defined Under Namespace</h2>
82
+ <p class="children">
83
+
84
+
85
+ <strong class="modules">Modules:</strong> <span class='object_link'><a href="DhEasy.html" title="DhEasy (module)">DhEasy</a></span>
86
+
87
+
88
+
89
+
90
+ </p>
91
+
92
+
93
+
94
+
95
+
96
+
97
+
98
+
99
+
100
+ </div>
101
+
102
+ <div id="footer">
103
+ Generated on Wed Dec 4 23:00:02 2019 by
104
+ <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
105
+ 0.9.20 (ruby-2.5.3).
106
+ </div>
107
+
108
+ </div>
109
+ </body>
110
+ </html>
@@ -0,0 +1,257 @@
1
+ require 'time'
2
+ require 'faker'
3
+ require 'datahen'
4
+ require 'dh_easy/core/smart_collection'
5
+ require 'dh_easy/core/exception'
6
+ require 'dh_easy/core/plugin'
7
+ require 'dh_easy/core/helper'
8
+ require 'dh_easy/core/config'
9
+ require 'dh_easy/core/mock'
10
+ require 'dh_easy/core/version'
11
+
12
+ module DhEasy
13
+ module Core
14
+ class << self
15
+ # Get dh_easy-core gem root directory path.
16
+ # @private
17
+ #
18
+ # @return [String]
19
+ def gem_root
20
+ File.expand_path File.join(File.dirname(__FILE__), '../..')
21
+ end
22
+
23
+ # Execute an action for all scripts within a directory.
24
+ #
25
+ # @param [String] dir Directory containing `.rb` scripts.
26
+ # @param [Hash] opts ({}) Configuration options.
27
+ # @option opts [Array] :except (nil) Literal file collection excluded from process.
28
+ #
29
+ # @yieldparam [String] path Script file path.
30
+ def all_scripts dir, opts = {}, &block
31
+ excluded_files = (opts[:except] || []).map{|f|File.expand_path File.join(dir, f)}
32
+ files = Dir[File.join(File.expand_path(dir), '*.rb')] - excluded_files
33
+ block ||= proc{}
34
+ files.sort.each &block
35
+ end
36
+
37
+ # Require all scripts within a directory.
38
+ #
39
+ # @param [String] dir Directory containing `.rb` scripts.
40
+ # @param [Hash] opts ({}) Configuration options.
41
+ # @option opts [Array] :except (nil) Literal file collection excluded from process.
42
+ def require_all dir, opts = {}
43
+ dir_list = real_dir_list = options = nil
44
+ real_except = (opts[:except] || []).map{|f| "#{f}.rb"}
45
+ options = opts.merge except: real_except
46
+ $LOAD_PATH.each do |load_path|
47
+ dir_list = Dir.glob File.join(load_path, dir)
48
+ dir_list.each do |real_dir|
49
+ next unless File.directory? real_dir
50
+ all_scripts(real_dir, options) {|file| require file}
51
+ end
52
+ end
53
+ end
54
+
55
+ # Require all relative scripts paths within a directory.
56
+ #
57
+ # @param [String] dir Directory containing `.rb` scripts.
58
+ # @param [Hash] opts ({}) Configuration options.
59
+ # @option opts [Array] :except (nil) Literal file collection excluded from process.
60
+ def require_relative_all dir, opts = {}
61
+ real_except = (opts[:except] || []).map{|f| "#{f}.rb"}
62
+ options = opts.merge except: real_except
63
+ dir_list = Dir.glob dir
64
+ dir_list.each do |relative_dir|
65
+ real_dir = File.expand_path relative_dir
66
+ all_scripts(real_dir, options) {|file| require file}
67
+ end
68
+ end
69
+
70
+ # Expose an environment into an object instance as methods.
71
+ #
72
+ # @param object Object instance to expose env into.
73
+ # @param [Array] env Hash with methods name as keys and blocks as actions.
74
+ #
75
+ # @return `object`
76
+ #
77
+ # @example
78
+ # class Foo
79
+ # def hello_person
80
+ # 'Hello person!'
81
+ # end
82
+ # end
83
+ #
84
+ # env = {
85
+ # hello_world: lambda{return 'Hello world!'},
86
+ # hello_sky: proc{return 'Hello sky!'}
87
+ # }
88
+ # my_object = Foo.new
89
+ # DhEasy::Core.expose_to my_object, env
90
+ #
91
+ # puts my_object.hello_world
92
+ # # => 'Hello world!'
93
+ # puts my_object.hello_sky
94
+ # # => 'Hello sky!'
95
+ # puts my_object.hello_person
96
+ # # => 'Hello person!'
97
+ def expose_to object, env
98
+ metaclass = class << object; self; end
99
+ env.each do |key, block|
100
+ metaclass.send(:define_method, key, block)
101
+ end
102
+ object
103
+ end
104
+
105
+ # Retrieve instance methods from an object.
106
+ #
107
+ # @param object Object with instance methods.
108
+ # @param class_only (false) Will get class only methods when `true`.
109
+ #
110
+ # @return [Array]
111
+ #
112
+ # @example
113
+ # class Foo
114
+ # def hello_world
115
+ # 'Hello world!'
116
+ # end
117
+ #
118
+ # def hello_person
119
+ # 'Hello person!'
120
+ # end
121
+ # end
122
+ #
123
+ # my_object = Foo.new
124
+ # DhEasy::Core.instance_methods_from my_object
125
+ # # => [:hello_world, :hello_person]
126
+ def instance_methods_from object, class_only = false
127
+ object.methods(!class_only) - Object.new.methods(!class_only)
128
+ end
129
+
130
+ # Mock instances methods from the origin into target object.
131
+ #
132
+ # @param origin Object with instance methods to mock.
133
+ # @param target Object instance to mock methods into.
134
+ #
135
+ # @example
136
+ # class Boo
137
+ # attr_accessor :message
138
+ # def initialize
139
+ # message = 'Hello world!'
140
+ # end
141
+ #
142
+ # def hello_world
143
+ # message
144
+ # end
145
+ # end
146
+ #
147
+ # class Foo
148
+ # def hello_person
149
+ # 'Hello person!'
150
+ # end
151
+ # end
152
+ #
153
+ # origin = Boo.new
154
+ # target = Foo.new
155
+ # DhEasy::Core.mock_instance_methods origin target
156
+ #
157
+ # puts target.hello_world
158
+ # # => 'Hello world!'
159
+ # puts target.hello_person
160
+ # # => 'Hello person!'
161
+ #
162
+ # origin.message = 'Hello world again!'
163
+ # puts target.hello_world
164
+ # # => 'Hello world again!'
165
+ def mock_instance_methods origin, target
166
+ # Get instance unique methods
167
+ method_list = instance_methods_from origin
168
+ method_list.delete :context_binding if method_list.include? :context_binding
169
+
170
+ # Build env reflecting origin unique methods
171
+ env = {}
172
+ method_list.each do |method|
173
+ env[method] = lambda{|*args|origin.send(method, *args)}
174
+ end
175
+
176
+ # Mock origin unique methods into target
177
+ expose_to target, env
178
+ end
179
+
180
+ # Generate a compatibility report from a origin and a fragment as a hash.
181
+ #
182
+ # @param [Array] origin Item collection to represent the universe.
183
+ # @param [Array] fragment Item collection to compare againt +origin+.
184
+ #
185
+ # @return [Hash]
186
+ # * `:missing [Array]` (`[]`) Methods on `fragment` only.
187
+ # * `:new [Array]` (`[]`) Methods on `origin` only.
188
+ # * `:is_compatible [Boolean]` true when all `fragment`'s methods are present on `origin`.
189
+ #
190
+ # @example Analyze when uncompatible `fragment` because of `origin` missing fields.
191
+ # DhEasy::Core.analyze_compatibility [1,2,3,4,5], [1,2,6]
192
+ # # => {missing: [6], new: [3,4,5], is_compatible: false}
193
+ #
194
+ # @example Analyze when compatible.
195
+ # DhEasy::Core.analyze_compatibility [1,2,3,4,5], [1,2,3]
196
+ # # => {missing: [], new: [4,5], is_compatible: true}
197
+ def analyze_compatibility origin, fragment
198
+ intersection = origin & fragment
199
+ {
200
+ missing: fragment - intersection,
201
+ new: origin - intersection,
202
+ is_compatible: (intersection.count == fragment.count)
203
+ }
204
+ end
205
+
206
+ # Deep stringify keys from a hash.
207
+ #
208
+ # @param [Hash] hash Source hash to stringify keys.
209
+ # @param [Boolean] should_clone (true) Target a hash clone to avoid affecting the same hash object.
210
+ #
211
+ # @return [Hash]
212
+ def deep_stringify_keys hash, should_clone = true
213
+ return hash unless hash.is_a? Hash
214
+ pair_collection = hash.map{|k,v| [k.to_s,v]}
215
+ target = should_clone ? {} : hash
216
+ target.clear
217
+ pair_collection.each do |pair|
218
+ key, value = pair
219
+ if value.is_a? Array
220
+ array = []
221
+ value.each do |item|
222
+ array << deep_stringify_keys(item, should_clone)
223
+ end
224
+ target[key] = array
225
+ next
226
+ end
227
+ target[key] = deep_stringify_keys(value, should_clone)
228
+ end
229
+ target
230
+ end
231
+
232
+ # Deep stringify all keys on hash object.
233
+ #
234
+ # @param [Hash] hash Hash to stringify keys.
235
+ #
236
+ # @return [Hash]
237
+ def deep_stringify_keys! hash
238
+ deep_stringify_keys hash, false
239
+ end
240
+
241
+ # Deep clone a hash while keeping it's values object references.
242
+ #
243
+ # @param [Hash] hash Hash to clone.
244
+ # @param [Boolean] should_clone (false) Clone values when true.
245
+ #
246
+ # @return [Hash] Hash clone.
247
+ def deep_clone hash, should_clone = false
248
+ target = {}
249
+ hash.each do |key, value|
250
+ value = value.is_a?(Hash) ? deep_clone(value, should_clone) : (should_clone ? value.clone : value)
251
+ target[key] = value
252
+ end
253
+ target
254
+ end
255
+ end
256
+ end
257
+ end
@@ -0,0 +1,27 @@
1
+ module DhEasy
2
+ module Core
3
+ # Configuration manager tool useful for global configuration data accross
4
+ # the scraping process.
5
+ class Config
6
+ include DhEasy::Core::Plugin::InitializeHook
7
+ include DhEasy::Core::Plugin::ConfigBehavior
8
+
9
+ # {DhEasy::Core::Plugin::ConfigBehavior#config_collection_key}
10
+ alias :collection_key :config_collection_key
11
+ # {DhEasy::Core::Plugin::ConfigBehavior#config_collection}
12
+ alias :collection :config_collection
13
+
14
+ # Initialize config object
15
+ #
16
+ # @param [Hash] opts ({}) Configuration options.
17
+ #
18
+ # @see DhEasy::Core::Plugin::ConfigBehavior#initialize_hook_core_config_behavior
19
+ def initialize opts = {}
20
+ opts = opts.merge(
21
+ config_collection: opts[:collection]
22
+ )
23
+ initialize_hooks opts
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,8 @@
1
+ require 'dh_easy/core/exception/outdated_error'
2
+
3
+ module DhEasy
4
+ module Core
5
+ module Exception
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ module DhEasy
2
+ module Core
3
+ module Exception
4
+ # Exception that indicates something is outdated error.
5
+ class OutdatedError < StandardError
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,8 @@
1
+ require 'dh_easy/core/helper/cookie'
2
+
3
+ module DhEasy
4
+ module Core
5
+ module Helper
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,209 @@
1
+ module DhEasy
2
+ module Core
3
+ module Helper
4
+ # Helper used for lower level cookie management.
5
+ class Cookie
6
+ class << self
7
+ # Parse request cookies on different formats.
8
+ #
9
+ # @param [String,Hash,Array] cookies Cookies to parse.
10
+ # @param [Hash] cookie_hash ({}) External hash to store parsed cookies.
11
+ #
12
+ # @return [Hash]
13
+ #
14
+ # @example Parse from string.
15
+ # parse_from_request 'aaa=111; bbb=222'
16
+ # # => {'aaa' => 111, 'bbb' => 222}
17
+ #
18
+ # @example Parse from array.
19
+ # cookies = [
20
+ # 'aaa=111',
21
+ # 'bbb=222'
22
+ # ]
23
+ # parse_from_response cookies
24
+ # # => {'aaa' => 111, 'bbb' => 222}
25
+ #
26
+ # @example Parse with `cookie_hash`.
27
+ # cookie_hash = {'ccc' => 333}
28
+ # parse_from_request 'aaa=111; bbb=222', cookie_hash
29
+ # cookie_hash
30
+ # # => {'aaa' => 1, 'bbb' => 2, 'ccc' => 333}
31
+ def parse_from_request cookies, cookie_hash = {}
32
+ # Retrieve from hash
33
+ if cookies.is_a? Hash
34
+ cookie_hash.merge! cookies
35
+ return cookie_hash
36
+ end
37
+
38
+ # Extract from string
39
+ cookies = cookies.split '; ' if cookies.is_a? String
40
+
41
+ # Extract from array
42
+ cookies&.each do |raw_cookie|
43
+ key, value = raw_cookie.split('=', 2)
44
+ cookie_hash[key] = value
45
+ end
46
+ cookie_hash
47
+ end
48
+
49
+ # Parse response cookies on different formats.
50
+ #
51
+ # @param [String,Hash,Array] cookies Cookies to parse.
52
+ # @param [Hash] cookie_hash ({}) External hash to store parsed cookies.
53
+ #
54
+ # @return [Hash]
55
+ #
56
+ # @example Parse from string
57
+ # parse_from_response 'aaa=111; bbb=222'
58
+ # # => {'aaa' => 111, 'bbb' => 222}
59
+ #
60
+ # @example Parse from array.
61
+ # cookies = [
62
+ # 'aaa=111; Expires=Thu, Jan 01 1970 00:00:00 UTC; path=/',
63
+ # 'bbb=222; path=/',
64
+ # 'ccc=333; path=/; expires=Wed, Jan 01 3000 00:00:00 UTC'
65
+ # ]
66
+ # parse_from_response cookies
67
+ # # => {'bbb' => 222, 'ccc' => 333}
68
+ #
69
+ # @example Parse with `cookie_hash`.
70
+ # cookie_hash = {'ccc' => 333}
71
+ # parse_from_response 'aaa=111; bbb=222', cookie_hash
72
+ # cookie_hash
73
+ # # => {'aaa' => 111, 'bbb' => 222, 'ccc' => 333}
74
+ def parse_from_response cookies, cookie_hash = {}
75
+ # Retrieve from hash
76
+ if cookies.is_a? Hash
77
+ cookie_hash.merge! cookies
78
+ return cookie_hash
79
+ end
80
+ # Retrieve from String
81
+ cookies = cookies.split '; ' if cookies.is_a? String
82
+
83
+ # Extract from array
84
+ info = cookie = expires = key = value = nil
85
+ cookies&.each do |raw_cookie|
86
+ # Extract cookie data
87
+ key_pair = raw_cookie.scan(/(?:;\s+([^\=]+)=([^;]*))/i) || []
88
+ cookie = key_pair.inject(Hash.new){|h,i|h[i[0].to_s.downcase] = i[1]; h}
89
+ cookie[:key], cookie[:value] = raw_cookie.match(/^\s*(?<key>[^\=]+)\=(?<value>[^;]*)/i)&.captures
90
+
91
+ # Check cookie expire
92
+ expires = cookie['expires'].nil? ? nil : Time.parse(cookie['expires'])
93
+ if !expires.nil? && Time.now > expires
94
+ cookie_hash.delete cookie[:key]
95
+ next
96
+ end
97
+
98
+ # Save cookie
99
+ cookie_hash[cookie[:key]] = cookie[:value]
100
+ end
101
+ cookie_hash
102
+ end
103
+
104
+ # Apply request and response cookies as a hash.
105
+ #
106
+ # @param [String,Array,Hash] request_cookies Cookies to parse.
107
+ # @param [String,Array,Hash] response_cookies Cookies to parse.
108
+ #
109
+ # @return [Hash]
110
+ #
111
+ # @example
112
+ # request_cookies = 'aaa=111; ddd=444'
113
+ # response_cookies = [
114
+ # 'aaa=111; Expires=Thu, Jan 01 1970 00:00:00 UTC; path=/',
115
+ # 'bbb=222; path=/',
116
+ # 'ccc=333; path=/; expires=Wed, Jan 01 3000 00:00:00 UTC'
117
+ # ]
118
+ # update_as_hash , response_cookies
119
+ # # => {'bbb' => 222, 'ccc' => 333, 'ddd' => 444}
120
+ def update_as_hash request_cookies, response_cookies
121
+ cookie_hash = {}
122
+ parse_from_request request_cookies, cookie_hash
123
+ parse_from_response response_cookies, cookie_hash
124
+ cookie_hash
125
+ end
126
+
127
+ # Encode cookies as request cookie string.
128
+ #
129
+ # @param [Hash] cookie_hash Hash with cookies.
130
+ #
131
+ # @return [String]
132
+ #
133
+ # @example
134
+ # cookie_hash = {
135
+ # 'aaa' => 111,
136
+ # 'bbb' => 222
137
+ # }
138
+ # encode_to_header cookie_hash
139
+ # # => 'aaa=111; bbb=222'
140
+ def encode_to_header cookie_hash
141
+ cookie_hash.map{|k,v| "#{k}=#{v}"}.join '; '
142
+ end
143
+
144
+ # Apply request and response cookies as a string with request format.
145
+ #
146
+ # @param [String,Array,Hash] request_cookies Cookies to parse.
147
+ # @param [String,Array,Hash] response_cookies Cookies to parse.
148
+ #
149
+ # @return [String]
150
+ #
151
+ # @example
152
+ # request_cookies = 'aaa=111; ddd=444'
153
+ # response_cookies = [
154
+ # 'aaa=111; Expires=Thu, Jan 01 1970 00:00:00 UTC; path=/',
155
+ # 'bbb=222; path=/',
156
+ # 'ccc=333; path=/; expires=Wed, Jan 01 3000 00:00:00 UTC'
157
+ # ]
158
+ # update_as_hash , response_cookies
159
+ # # => 'bbb=222; ccc=333; ddd=444'
160
+ def update request_cookies, response_cookies
161
+ cookie_hash = update_as_hash request_cookies, response_cookies
162
+ encode_to_header cookie_hash
163
+ end
164
+
165
+ # Compare if cookie is included into base cookie
166
+ #
167
+ # @param [Hash] base_cookie_hash Hash that represent universe.
168
+ # @param [Hash] cookie_hash Hash that represents to compare.
169
+ #
170
+ # @return [Boolean]
171
+ #
172
+ # @example Check a success match.
173
+ # base_cookie_hash = {
174
+ # 'aaa' => 111,
175
+ # 'bbb' => 222,
176
+ # 'ccc' => 333,
177
+ # 'ddd' => 444
178
+ # }
179
+ # cookie_hash = {
180
+ # 'bbb' => 222,
181
+ # 'ddd' => 444
182
+ # }
183
+ # include? base_cookie_hash, cookie_hash
184
+ # # => true
185
+ #
186
+ # @example Check with fail match.
187
+ # base_cookie_hash = {
188
+ # 'aaa' => 111,
189
+ # 'bbb' => 222,
190
+ # 'ccc' => 333,
191
+ # 'ddd' => 444
192
+ # }
193
+ # cookie_hash = {
194
+ # 'bbb' => 555,
195
+ # 'ddd' => 444
196
+ # }
197
+ # include? base_cookie_hash, cookie_hash
198
+ # # => false
199
+ def include? base_cookie_hash, cookie_hash
200
+ cookie_hash.each do |key, value|
201
+ return false unless base_cookie_hash.has_key?(key) && base_cookie_hash[key] == value
202
+ end
203
+ true
204
+ end
205
+ end
206
+ end
207
+ end
208
+ end
209
+ end