http-cookie 1.0.0.pre12 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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