http-cookie 1.0.0.pre12 → 1.0.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2a70ec83e62018ae7621d1eb7ba75f08eea1d696
4
- data.tar.gz: 9ed2b81801d89bb7adf3f6d97b087421406f4acf
3
+ metadata.gz: aacf47668ef161f9e46f07ed44bd6e145c805c14
4
+ data.tar.gz: 92c544f479f357ad08e66a8a3827e1edaca35c2e
5
5
  SHA512:
6
- metadata.gz: f1ba260a8757b9076df6645368f761005cc665ef1c4ae357f102982132ed66253ae7cb49d163430bd3070225524c0cd4a988b2abbc4252e3e68e8376eea68542
7
- data.tar.gz: bca8c545043e5b4975e32350dcf37f1519a183e3d207bb2692313863104884750ef656ed568106b69beab35e53b0536c36b677846255b1d477af95d022c74bfe
6
+ metadata.gz: 7cc1fc98627c5167e3eb410359b00a868f849d10458ca0b1881efdb6ab94bf51d300f732f9b3de52edec2e21934553f937cb38e416af18e103ca923e70285c58
7
+ data.tar.gz: 3fef65c59da56daba7cb4d571b034cecab3b66cb656811fe9644d99404a152b5656dc04d2a501a3a6b74cf75cb5bcdde91c87f3d5b470d8ba1ffcd515498c421
@@ -87,7 +87,7 @@ class HTTP::Cookie
87
87
  # The Expires attribute value as a Time object.
88
88
  #
89
89
  # The setter method accepts a Time object, a string representation
90
- # of date/time, or `nil`.
90
+ # of date/time that Time.parse can understand, or `nil`.
91
91
  #
92
92
  # Setting this value resets #max_age to nil. When #max_age is
93
93
  # non-nil, #expires returns `created_at + max_age`.
@@ -111,12 +111,11 @@ class HTTP::Cookie
111
111
  # new(**attr_hash)
112
112
  #
113
113
  # Creates a cookie object. For each key of `attr_hash`, the setter
114
- # is called if defined. Each key can be either a symbol or a
115
- # string of downcased attribute names.
116
- #
117
- # This methods accepts any attribute name for which a setter method
118
- # is defined. Beware, however, any error (typically ArgumentError)
119
- # a setter method raises will be passed through.
114
+ # is called if defined and any error (typically ArgumentError or
115
+ # TypeError) that is raised will be passed through. Each key can be
116
+ # either a downcased symbol or a string that may be mixed case.
117
+ # Support for the latter may, however, be obsoleted in future when
118
+ # Ruby 2.0's keyword syntax is adopted.
120
119
  #
121
120
  # If `value` is omitted or it is nil, an expiration cookie is
122
121
  # created unless `max_age` or `expires` (`expires_at`) is given.
@@ -157,8 +156,8 @@ class HTTP::Cookie
157
156
  end
158
157
  for_domain = false
159
158
  domain = max_age = origin = nil
160
- attr_hash.each_pair { |key, val|
161
- case key.to_sym
159
+ attr_hash.each_pair { |okey, val|
160
+ case key ||= okey
162
161
  when :name
163
162
  self.name = val
164
163
  when :value
@@ -180,23 +179,21 @@ class HTTP::Cookie
180
179
  @httponly = val
181
180
  when :secure, :secure?
182
181
  @secure = val
183
- when /[A-Z]/
184
- warn "keyword should be downcased: #{key}" if $VERBOSE
185
- key = key.downcase
186
- redo
187
182
  when Symbol
188
183
  setter = :"#{key}="
189
184
  if respond_to?(setter)
190
185
  __send__(setter, val)
191
186
  else
192
- warn "unknown keyword: #{key}" if $VERBOSE
187
+ warn "unknown attribute name: #{okey.inspect}" if $VERBOSE
188
+ next
193
189
  end
194
190
  when String
195
- key = key.to_sym
191
+ warn "use downcased symbol for keyword: #{okey.inspect}" if $VERBOSE
192
+ key = key.downcase.to_sym
196
193
  redo
197
194
  else
198
- key = key.to_s
199
- redo
195
+ warn "invalid keyword ignored: #{okey.inspect}" if $VERBOSE
196
+ next
200
197
  end
201
198
  }
202
199
  if @name.nil?
@@ -343,7 +340,7 @@ class HTTP::Cookie
343
340
  attr_reader :name
344
341
 
345
342
  # See #name.
346
- def name=(name)
343
+ def name= name
347
344
  name = (String.try_convert(name) or
348
345
  raise TypeError, "#{name.class} is not a String")
349
346
  if name.empty?
@@ -360,7 +357,7 @@ class HTTP::Cookie
360
357
  attr_reader :value
361
358
 
362
359
  # See #value.
363
- def value=(value)
360
+ def value= value
364
361
  if value.nil?
365
362
  self.expires = UNIX_EPOCH
366
363
  return @value = ''
@@ -379,7 +376,7 @@ class HTTP::Cookie
379
376
  attr_reader :domain
380
377
 
381
378
  # See #domain.
382
- def domain=(domain)
379
+ def domain= domain
383
380
  case domain
384
381
  when nil
385
382
  @for_domain = false
@@ -437,7 +434,7 @@ class HTTP::Cookie
437
434
  attr_reader :path
438
435
 
439
436
  # See #path.
440
- def path=(path)
437
+ def path= path
441
438
  path = (String.try_convert(path) or
442
439
  raise TypeError, "#{path.class} is not a String")
443
440
  @path = path.start_with?('/') ? path : '/'
@@ -446,7 +443,7 @@ class HTTP::Cookie
446
443
  attr_reader :origin
447
444
 
448
445
  # See #origin.
449
- def origin=(origin)
446
+ def origin= origin
450
447
  return origin if origin == @origin
451
448
  @origin.nil? or
452
449
  raise ArgumentError, "origin cannot be changed once it is set"
@@ -482,7 +479,7 @@ class HTTP::Cookie
482
479
  end
483
480
 
484
481
  # See #expires.
485
- def expires=(t)
482
+ def expires= t
486
483
  case t
487
484
  when nil, Time
488
485
  else
@@ -499,7 +496,7 @@ class HTTP::Cookie
499
496
  attr_reader :max_age
500
497
 
501
498
  # See #max_age.
502
- def max_age=(sec)
499
+ def max_age= sec
503
500
  @expires = nil
504
501
  case sec
505
502
  when Integer, nil
@@ -635,7 +632,7 @@ class HTTP::Cookie
635
632
 
636
633
  # Compares the cookie with another. When there are many cookies with
637
634
  # the same name for a URL, the value of the smallest must be used.
638
- def <=>(other)
635
+ def <=> other
639
636
  # RFC 6265 5.4
640
637
  # Precedence: 1. longer path 2. older creation
641
638
  (@name <=> other.name).nonzero? ||
@@ -1,5 +1,5 @@
1
1
  class Array
2
- def select!
2
+ def select! # :yield: x
3
3
  i = 0
4
4
  each_with_index { |x, j|
5
5
  yield x or next
@@ -10,6 +10,10 @@ class Array
10
10
  self[i..-1] = []
11
11
  self
12
12
  end unless method_defined?(:select!)
13
+
14
+ def sort_by!(&block) # :yield: x
15
+ replace(sort_by(&block))
16
+ end unless method_defined?(:sort_by!)
13
17
  end
14
18
 
15
19
  class Hash
@@ -152,13 +152,6 @@ class HTTP::Cookie::Scanner < StringScanner
152
152
  end
153
153
 
154
154
  def scan_set_cookie
155
- unless block_given?
156
- scan_set_cookie { |*values|
157
- return values
158
- }
159
- return
160
- end
161
-
162
155
  # RFC 6265 4.1.1 & 5.2
163
156
  until eos?
164
157
  start = pos
@@ -221,13 +214,6 @@ class HTTP::Cookie::Scanner < StringScanner
221
214
  end
222
215
 
223
216
  def scan_cookie
224
- unless block_given?
225
- scan_cookie { |*values|
226
- return values
227
- }
228
- return
229
- end
230
-
231
217
  # RFC 6265 4.1.1 & 5.4
232
218
  until eos?
233
219
  skip_wsp
@@ -1,5 +1,5 @@
1
1
  module HTTP
2
2
  class Cookie
3
- VERSION = "1.0.0.pre12"
3
+ VERSION = "1.0.0"
4
4
  end
5
5
  end
@@ -6,9 +6,6 @@ require 'http/cookie'
6
6
  # any particular website.
7
7
 
8
8
  class HTTP::CookieJar
9
- require 'http/cookie_jar/abstract_store'
10
- require 'http/cookie_jar/abstract_saver'
11
-
12
9
  class << self
13
10
  def const_missing(name)
14
11
  case name.to_s
@@ -62,6 +59,7 @@ class HTTP::CookieJar
62
59
  end
63
60
  end
64
61
 
62
+ # The copy constructor. Not all backend store classes support cloning.
65
63
  def initialize_copy(other)
66
64
  @store = other.instance_eval { @store.dup }
67
65
  end
@@ -94,7 +92,7 @@ class HTTP::CookieJar
94
92
  begin
95
93
  cookie.acceptable?
96
94
  rescue RuntimeError => e
97
- raise ArgumentError, e.message
95
+ raise ArgumentError, e.message
98
96
  end
99
97
  self
100
98
  end
@@ -139,7 +137,7 @@ class HTTP::CookieJar
139
137
  #
140
138
  # If (and only if) the `uri` option is given, last access time of
141
139
  # each cookie is updated to the current time.
142
- def each(uri = nil, &block)
140
+ def each(uri = nil, &block) # :yield: cookie
143
141
  block_given? or return enum_for(__method__, uri)
144
142
 
145
143
  if uri
@@ -210,7 +208,7 @@ class HTTP::CookieJar
210
208
  # </dl>
211
209
  #
212
210
  # All options given are passed through to the underlying cookie
213
- # saver module.
211
+ # saver module's constructor.
214
212
  def save(writable, *options)
215
213
  opthash = {
216
214
  :format => :yaml,
@@ -269,7 +267,7 @@ class HTTP::CookieJar
269
267
  # </dl>
270
268
  #
271
269
  # All options given are passed through to the underlying cookie
272
- # saver module.
270
+ # saver module's constructor.
273
271
  def load(readable, *options)
274
272
  opthash = {
275
273
  :format => :yaml,
@@ -314,7 +312,8 @@ class HTTP::CookieJar
314
312
  self
315
313
  end
316
314
 
317
- # Removes expired cookies and returns self.
315
+ # Removes expired cookies and returns self. If `session` is true,
316
+ # all session cookies are removed as well.
318
317
  def cleanup(session = false)
319
318
  @store.cleanup session
320
319
  self
@@ -1,3 +1,6 @@
1
+ # :markup: markdown
2
+
3
+ # An abstract superclass for all saver classes.
1
4
  class HTTP::CookieJar::AbstractSaver
2
5
  class << self
3
6
  @@class_map = {}
@@ -16,20 +19,25 @@ class HTTP::CookieJar::AbstractSaver
16
19
  end
17
20
  end
18
21
 
19
- def inherited(subclass)
22
+ def inherited(subclass) # :nodoc:
20
23
  @@class_map[class_to_symbol(subclass)] = subclass
21
24
  end
22
25
 
23
- def class_to_symbol(klass)
26
+ def class_to_symbol(klass) # :nodoc:
24
27
  klass.name[/[^:]+?(?=Saver$|$)/].downcase.to_sym
25
28
  end
26
29
  end
27
30
 
31
+ # Defines options and their default values.
28
32
  def default_options
29
33
  # {}
30
34
  end
31
35
  private :default_options
32
36
 
37
+ # :call-seq:
38
+ # new(**options)
39
+ #
40
+ # Called by the constructor of each subclass using super().
33
41
  def initialize(options = nil)
34
42
  options ||= {}
35
43
  @logger = options[:logger]
@@ -41,10 +49,16 @@ class HTTP::CookieJar::AbstractSaver
41
49
  }
42
50
  end
43
51
 
52
+ # Implements HTTP::CookieJar#save().
53
+ #
54
+ # This is an abstract method that each subclass must override.
44
55
  def save(io, jar)
45
56
  # self
46
57
  end
47
58
 
59
+ # Implements HTTP::CookieJar#load().
60
+ #
61
+ # This is an abstract method that each subclass must override.
48
62
  def load(io, jar)
49
63
  # self
50
64
  end
@@ -1,5 +1,7 @@
1
+ # :markup: markdown
1
2
  require 'monitor'
2
3
 
4
+ # An abstract superclass for all store classes.
3
5
  class HTTP::CookieJar::AbstractStore
4
6
  include MonitorMixin
5
7
 
@@ -20,20 +22,25 @@ class HTTP::CookieJar::AbstractStore
20
22
  end
21
23
  end
22
24
 
23
- def inherited(subclass)
25
+ def inherited(subclass) # :nodoc:
24
26
  @@class_map[class_to_symbol(subclass)] = subclass
25
27
  end
26
28
 
27
- def class_to_symbol(klass)
29
+ def class_to_symbol(klass) # :nodoc:
28
30
  klass.name[/[^:]+?(?=Store$|$)/].downcase.to_sym
29
31
  end
30
32
  end
31
33
 
34
+ # Defines options and their default values.
32
35
  def default_options
33
36
  # {}
34
37
  end
35
38
  private :default_options
36
39
 
40
+ # :call-seq:
41
+ # new(**options)
42
+ #
43
+ # Called by the constructor of each subclass using super().
37
44
  def initialize(options = nil)
38
45
  super() # MonitorMixin
39
46
  options ||= {}
@@ -45,14 +52,21 @@ class HTTP::CookieJar::AbstractStore
45
52
  }
46
53
  end
47
54
 
55
+ # This is an abstract method that each subclass must override.
48
56
  def initialize_copy(other)
49
57
  # self
50
58
  end
51
59
 
60
+ # Implements HTTP::CookieJar#add().
61
+ #
62
+ # This is an abstract method that each subclass must override.
52
63
  def add(cookie)
53
64
  # self
54
65
  end
55
66
 
67
+ # Implements HTTP::CookieJar#delete().
68
+ #
69
+ # This is an abstract method that each subclass must override.
56
70
  def delete(cookie)
57
71
  # self
58
72
  end
@@ -66,7 +80,9 @@ class HTTP::CookieJar::AbstractStore
66
80
  #
67
81
  # If (and only if) the +uri+ option is given, last access time of
68
82
  # each cookie is updated to the current time.
69
- def each(uri = nil, &block)
83
+ #
84
+ # This is an abstract method that each subclass must override.
85
+ def each(uri = nil, &block) # :yield: cookie
70
86
  # if uri
71
87
  # ...
72
88
  # else
@@ -78,14 +94,22 @@ class HTTP::CookieJar::AbstractStore
78
94
  end
79
95
  include Enumerable
80
96
 
97
+ # Implements HTTP::CookieJar#empty?().
81
98
  def empty?
82
- # true or false
99
+ each { return false }
100
+ true
83
101
  end
84
102
 
103
+ # Implements HTTP::CookieJar#clear().
104
+ #
105
+ # This is an abstract method that each subclass must override.
85
106
  def clear
86
107
  # self
87
108
  end
88
109
 
110
+ # Implements HTTP::CookieJar#cleanup().
111
+ #
112
+ # This is an abstract method that each subclass must override.
89
113
  def cleanup(session = false)
90
114
  # if session
91
115
  # select { |cookie| cookie.session? || cookie.expired? }
@@ -1,9 +1,25 @@
1
+ # :markup: markdown
1
2
  require 'http/cookie_jar'
2
3
 
3
4
  # CookiestxtSaver saves and loads cookies in the cookies.txt format.
4
5
  class HTTP::CookieJar::CookiestxtSaver < HTTP::CookieJar::AbstractSaver
5
- True = "TRUE"
6
- False = "FALSE"
6
+ # :singleton-method: new
7
+ # :call-seq:
8
+ # new(**options)
9
+ #
10
+ # Available option keywords are below:
11
+ #
12
+ # * `:header`
13
+ #
14
+ # Specifies the header line not including a line feed, which is
15
+ # only used by #save(). None is output if nil is
16
+ # given. (default: `"# HTTP Cookie File"`)
17
+ #
18
+ # * `:linefeed`
19
+ #
20
+ # Specifies the line separator (default: `"\n"`).
21
+
22
+ ##
7
23
 
8
24
  def save(io, jar)
9
25
  io.puts @header if @header
@@ -28,8 +44,13 @@ class HTTP::CookieJar::CookiestxtSaver < HTTP::CookieJar::AbstractSaver
28
44
  }
29
45
  end
30
46
 
47
+ # :stopdoc:
48
+ True = "TRUE"
49
+ False = "FALSE"
50
+
31
51
  HTTPONLY_PREFIX = '#HttpOnly_'
32
52
  RE_HTTPONLY_PREFIX = /\A#{HTTPONLY_PREFIX}/
53
+ # :startdoc:
33
54
 
34
55
  # Serializes the cookie into a cookies.txt line.
35
56
  def cookie_to_record(cookie)
@@ -1,13 +1,6 @@
1
+ # :markup: markdown
1
2
  require 'http/cookie_jar'
2
3
 
3
- # :stopdoc:
4
- class Array
5
- def sort_by!(&block)
6
- replace(sort_by(&block))
7
- end unless method_defined?(:sort_by!)
8
- end
9
- # :startdoc:
10
-
11
4
  class HTTP::CookieJar
12
5
  # A store class that uses a hash-based cookie store.
13
6
  #
@@ -26,6 +19,9 @@ class HTTP::CookieJar
26
19
  }
27
20
  end
28
21
 
22
+ # :call-seq:
23
+ # new(**options)
24
+ #
29
25
  # Generates a hash based cookie store.
30
26
  #
31
27
  # Available option keywords are as below:
@@ -50,6 +46,7 @@ class HTTP::CookieJar
50
46
  @gc_index = 0
51
47
  end
52
48
 
49
+ # The copy constructor. This store class supports cloning.
53
50
  def initialize_copy(other)
54
51
  @jar = Marshal.load(Marshal.dump(other.instance_variable_get(:@jar)))
55
52
  end
@@ -67,7 +64,7 @@ class HTTP::CookieJar
67
64
  self
68
65
  end
69
66
 
70
- def each(uri = nil)
67
+ def each(uri = nil) # :yield: cookie
71
68
  now = Time.now
72
69
  if uri
73
70
  thost = DomainName.new(uri.host)
@@ -113,10 +110,6 @@ class HTTP::CookieJar
113
110
  self
114
111
  end
115
112
 
116
- def empty?
117
- @jar.empty?
118
- end
119
-
120
113
  def cleanup(session = false)
121
114
  now = Time.now
122
115
  all_cookies = []
@@ -68,6 +68,9 @@ class HTTP::CookieJar
68
68
  end
69
69
  # :startdoc:
70
70
 
71
+ # :call-seq:
72
+ # new(**options)
73
+ #
71
74
  # Generates a Mozilla cookie store. If the file does not exist,
72
75
  # it is created. If it does and its schema is old, it is
73
76
  # automatically upgraded with a new schema keeping the existing
@@ -109,6 +112,7 @@ class HTTP::CookieJar
109
112
  @gc_index = 0
110
113
  end
111
114
 
115
+ # Raises TypeError. Cloning is inhibited in this store class.
112
116
  def initialize_copy(other)
113
117
  raise TypeError, 'can\'t clone %s' % self.class
114
118
  end
@@ -138,7 +142,7 @@ class HTTP::CookieJar
138
142
 
139
143
  protected
140
144
 
141
- def schema_version=(version)
145
+ def schema_version= version
142
146
  @db.execute("PRAGMA user_version = %d" % version)
143
147
  @schema_version = version
144
148
  end
@@ -329,7 +333,7 @@ class HTTP::CookieJar
329
333
  expiry >= :expiry
330
334
  SQL
331
335
 
332
- def each(uri = nil, &block)
336
+ def each(uri = nil, &block) # :yield: cookie
333
337
  now = Time.now
334
338
  if uri
335
339
  thost = DomainName.new(uri.host)
@@ -398,19 +402,6 @@ class HTTP::CookieJar
398
402
  self
399
403
  end
400
404
 
401
- SQL[:count] = <<-'SQL'
402
- SELECT COUNT(id) FROM moz_cookies
403
- SQL
404
-
405
- def count
406
- @stmt[:count].execute.first[0]
407
- end
408
- protected :count
409
-
410
- def empty?
411
- @sjar.empty? && count == 0
412
- end
413
-
414
405
  SQL[:delete_expired] = <<-'SQL'
415
406
  DELETE FROM moz_cookies WHERE expiry < :expiry
416
407
  SQL
@@ -1,9 +1,20 @@
1
+ # :markup: markdown
1
2
  require 'http/cookie_jar'
2
3
  require 'psych' if !defined?(YAML) && RUBY_VERSION == "1.9.2"
3
4
  require 'yaml'
4
5
 
5
- # YAMLSaver saves and loads cookies in the YAML format.
6
+ # YAMLSaver saves and loads cookies in the YAML format. It can load a
7
+ # YAML file saved by Mechanize, but the saving format is not
8
+ # compatible with older versions of Mechanize (< 2.7).
6
9
  class HTTP::CookieJar::YAMLSaver < HTTP::CookieJar::AbstractSaver
10
+ # :singleton-method: new
11
+ # :call-seq:
12
+ # new(**options)
13
+ #
14
+ # There is no option keyword supported at the moment.
15
+
16
+ ##
17
+
7
18
  def save(io, jar)
8
19
  YAML.dump(@session ? jar.to_a : jar.reject(&:session?), io)
9
20
  end
@@ -42,7 +53,11 @@ class HTTP::CookieJar::YAMLSaver < HTTP::CookieJar::AbstractSaver
42
53
  # YAML::Object of Syck
43
54
  cookie_hash = cookie_hash.ivars
44
55
  end
45
- cookie = HTTP::Cookie.new(cookie_hash)
56
+ cookie = HTTP::Cookie.new({}.tap { |hash|
57
+ cookie_hash.each_pair { |key, value|
58
+ hash[key.to_sym] = value
59
+ }
60
+ })
46
61
  jar.add(cookie)
47
62
  }
48
63
  }
@@ -3,6 +3,30 @@ require 'test-unit'
3
3
  require 'uri'
4
4
  require 'http/cookie'
5
5
 
6
+ module Test
7
+ module Unit
8
+ module Assertions
9
+ def assert_warn(pattern, message = nil, &block)
10
+ class << (output = "")
11
+ alias write <<
12
+ end
13
+ stderr, $stderr = $stderr, output
14
+ yield
15
+ assert_match(pattern, output, message)
16
+ ensure
17
+ $stderr = stderr
18
+ end
19
+
20
+ def assert_warning(pattern, message = nil, &block)
21
+ verbose, $VERBOSE = $VERBOSE, true
22
+ assert_warn(pattern, message, &block)
23
+ ensure
24
+ $VERBOSE = verbose
25
+ end
26
+ end
27
+ end
28
+ end
29
+
6
30
  module Enumerable
7
31
  def combine
8
32
  masks = inject([[], 1]){|(ar, m), e| [ar << m, m << 1 ] }[0]
@@ -23,3 +47,9 @@ end
23
47
  def test_file(filename)
24
48
  File.expand_path(filename, File.dirname(__FILE__))
25
49
  end
50
+
51
+ def sleep_until(time)
52
+ if (s = time - Time.now) > 0
53
+ sleep s
54
+ end
55
+ end
@@ -2,13 +2,6 @@
2
2
  require File.expand_path('helper', File.dirname(__FILE__))
3
3
 
4
4
  class TestHTTPCookie < Test::Unit::TestCase
5
- def silently
6
- warn_level, $VERBOSE = $VERBOSE, false
7
- yield
8
- ensure
9
- $VERBOSE = warn_level
10
- end
11
-
12
5
  def setup
13
6
  httpdate = 'Sun, 27-Sep-2037 00:00:00 GMT'
14
7
 
@@ -46,12 +39,10 @@ class TestHTTPCookie < Test::Unit::TestCase
46
39
 
47
40
  dates.each do |date|
48
41
  cookie = "PREF=1; expires=#{date}"
49
- silently do
50
- assert_equal 1, HTTP::Cookie.parse(cookie, url) { |c|
51
- assert c.expires, "Tried parsing: #{date}"
52
- assert_send [c.expires, :<, yesterday]
53
- }.size
54
- end
42
+ assert_equal 1, HTTP::Cookie.parse(cookie, url) { |c|
43
+ assert c.expires, "Tried parsing: #{date}"
44
+ assert_send [c.expires, :<, yesterday]
45
+ }.size
55
46
  end
56
47
 
57
48
  [
@@ -177,14 +168,12 @@ class TestHTTPCookie < Test::Unit::TestCase
177
168
  "20/06/95 21:07",
178
169
  ]
179
170
 
180
- silently do
181
- dates.each do |date|
182
- cookie = "PREF=1; expires=#{date}"
183
- assert_equal 1, HTTP::Cookie.parse(cookie, url) { |c|
184
- assert_equal(true, c.expires.nil?)
185
- }.size
186
- end
187
- end
171
+ dates.each { |date|
172
+ cookie = "PREF=1; expires=#{date}"
173
+ assert_equal 1, HTTP::Cookie.parse(cookie, url) { |c|
174
+ assert_equal(true, c.expires.nil?)
175
+ }.size
176
+ }
188
177
  end
189
178
 
190
179
  def test_parse_domain_dot
@@ -537,6 +526,30 @@ class TestHTTPCookie < Test::Unit::TestCase
537
526
  cookie.acceptable?
538
527
  }
539
528
 
529
+ # various keywords
530
+ [
531
+ ["Expires", /use downcased symbol/],
532
+ ].each { |key, pattern|
533
+ assert_warning(pattern, "warn of key: #{key.inspect}") {
534
+ cookie = HTTP::Cookie.new(:value => 'value', :name => 'key', key => expires.dup)
535
+ assert_equal 'key', cookie.name
536
+ assert_equal 'value', cookie.value
537
+ assert_equal expires, cookie.expires, "key: #{key.inspect}"
538
+ }
539
+ }
540
+ [
541
+ [:Expires, /unknown attribute name/],
542
+ [:expires?, /unknown attribute name/],
543
+ [[:expires], /invalid keyword/],
544
+ ].each { |key, pattern|
545
+ assert_warning(pattern, "warn of key: #{key.inspect}") {
546
+ cookie = HTTP::Cookie.new(:value => 'value', :name => 'key', key => expires.dup)
547
+ assert_equal 'key', cookie.name
548
+ assert_equal 'value', cookie.value
549
+ assert_equal nil, cookie.expires, "key: #{key.inspect}"
550
+ }
551
+ }
552
+
540
553
  cookie = HTTP::Cookie.new(:value => 'value', :name => 'key', :expires => expires.dup)
541
554
  assert_equal 'key', cookie.name
542
555
  assert_equal 'value', cookie.value
@@ -2,11 +2,63 @@ require File.expand_path('helper', File.dirname(__FILE__))
2
2
  require 'tmpdir'
3
3
 
4
4
  module TestHTTPCookieJar
5
+ class TestAutoloading < Test::Unit::TestCase
6
+ def test_nonexistent_store
7
+ assert_raises(NameError) {
8
+ HTTP::CookieJar::NonexistentStore
9
+ }
10
+ end
11
+
12
+ def test_erroneous_store
13
+ Dir.mktmpdir { |dir|
14
+ Dir.mkdir(File.join(dir, 'http'))
15
+ Dir.mkdir(File.join(dir, 'http', 'cookie_jar'))
16
+ rb = File.join(dir, 'http', 'cookie_jar', 'erroneous_store.rb')
17
+ File.open(rb, 'w').close
18
+ $LOAD_PATH.unshift(dir)
19
+
20
+ assert_raises(NameError) {
21
+ HTTP::CookieJar::ErroneousStore
22
+ }
23
+ if RUBY_VERSION >= "1.9"
24
+ assert_includes $LOADED_FEATURES, rb
25
+ else
26
+ assert_includes $LOADED_FEATURES, rb[(dir.size + 1)..-1]
27
+ end
28
+ }
29
+ end
30
+
31
+ def test_nonexistent_saver
32
+ assert_raises(NameError) {
33
+ HTTP::CookieJar::NonexistentSaver
34
+ }
35
+ end
36
+
37
+ def test_erroneous_saver
38
+ Dir.mktmpdir { |dir|
39
+ Dir.mkdir(File.join(dir, 'http'))
40
+ Dir.mkdir(File.join(dir, 'http', 'cookie_jar'))
41
+ rb = File.join(dir, 'http', 'cookie_jar', 'erroneous_saver.rb')
42
+ File.open(rb, 'w').close
43
+ $LOAD_PATH.unshift(dir)
44
+
45
+ assert_raises(NameError) {
46
+ HTTP::CookieJar::ErroneousSaver
47
+ }
48
+ if RUBY_VERSION >= "1.9"
49
+ assert_includes $LOADED_FEATURES, rb
50
+ else
51
+ assert_includes $LOADED_FEATURES, rb[(dir.size + 1)..-1]
52
+ end
53
+ }
54
+ end
55
+ end
56
+
5
57
  module CommonTests
6
58
  def setup(options = nil, options2 = nil)
7
59
  default_options = {
8
60
  :store => :hash,
9
- :gc_threshold => 150,
61
+ :gc_threshold => 1500, # increased by 10 for shorter test time
10
62
  }
11
63
  new_options = default_options.merge(options || {})
12
64
  new_options2 = new_options.merge(options2 || {})
@@ -692,7 +744,7 @@ module TestHTTPCookieJar
692
744
  @jar.cleanup
693
745
  count = @jar.to_a.size
694
746
  assert_equal limit_per_domain, count
695
- assert_equal [*1..41] + [*43..(limit_per_domain + 1)], @jar.map { |cookie|
747
+ assert_equal [*1..(limit_per_domain + 1)] - [42], @jar.map { |cookie|
696
748
  cookie.name[/(\d+)$/].to_i
697
749
  }.sort
698
750
 
@@ -749,6 +801,46 @@ module TestHTTPCookieJar
749
801
  assert_equal %w[Akinori Japan], cookies.map { |c| c.value }
750
802
  assert_equal %w[Japan Akinori], @jar.to_a.sort_by { |c| c.name }.map { |c| c.value }
751
803
  end
804
+
805
+ def test_expire_by_each_and_cleanup
806
+ uri = URI('http://www.example.org/')
807
+
808
+ ts = Time.now.to_f
809
+ if ts % 1 > 0.5
810
+ sleep 0.5
811
+ ts += 0.5
812
+ end
813
+ expires = Time.at(ts.floor)
814
+ time = expires
815
+
816
+ if mozilla_store?
817
+ # MozillaStore only has the time precision of seconds.
818
+ time = expires
819
+ expires -= 1
820
+ end
821
+
822
+ 0.upto(2) { |i|
823
+ c = HTTP::Cookie.new('Foo%d' % (3 - i), 'Bar', :expires => expires + i, :origin => uri)
824
+ @jar << c
825
+ @jar2 << c
826
+ }
827
+
828
+ assert_equal %w[Foo1 Foo2], @jar.cookies.map(&:name)
829
+ assert_equal %w[Foo1 Foo2], @jar2.cookies(uri).map(&:name)
830
+
831
+ sleep_until time + 1
832
+
833
+ assert_equal %w[Foo1], @jar.cookies.map(&:name)
834
+ assert_equal %w[Foo1], @jar2.cookies(uri).map(&:name)
835
+
836
+ sleep_until time + 2
837
+
838
+ @jar.cleanup
839
+ @jar2.cleanup
840
+
841
+ assert_send [@jar, :empty?]
842
+ assert_send [@jar2, :empty?]
843
+ end
752
844
  end
753
845
 
754
846
  class WithHashStore < Test::Unit::TestCase
@@ -770,6 +862,20 @@ module TestHTTPCookieJar
770
862
  }
771
863
  end
772
864
 
865
+ def test_clone
866
+ jar = @jar.clone
867
+ assert_not_send [
868
+ @jar.store,
869
+ :equal?,
870
+ jar.store
871
+ ]
872
+ assert_not_send [
873
+ @jar.store.instance_variable_get(:@jar),
874
+ :equal?,
875
+ jar.store.instance_variable_get(:@jar)
876
+ ]
877
+ assert_equal @jar.cookies, jar.cookies
878
+ end
773
879
  end
774
880
 
775
881
  class WithMozillaStore < Test::Unit::TestCase
@@ -789,6 +895,12 @@ module TestHTTPCookieJar
789
895
  jar.delete(HTTP::Cookie.new("name", :domain => 'rubyforge.org'))
790
896
  end
791
897
 
898
+ def test_clone
899
+ assert_raises(TypeError) {
900
+ @jar.clone
901
+ }
902
+ end
903
+
792
904
  def test_close
793
905
  add_and_delete(@jar)
794
906
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: http-cookie
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.pre12
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Akinori MUSHA
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2013-04-15 00:00:00.000000000 Z
14
+ date: 2013-04-17 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: domain_name
@@ -161,9 +161,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
161
161
  version: '0'
162
162
  required_rubygems_version: !ruby/object:Gem::Requirement
163
163
  requirements:
164
- - - '>'
164
+ - - '>='
165
165
  - !ruby/object:Gem::Version
166
- version: 1.3.1
166
+ version: '0'
167
167
  requirements: []
168
168
  rubyforge_project:
169
169
  rubygems_version: 2.0.3