acts_as_list_with_sti_support 1.0.1 → 1.0.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.
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acts_as_list_with_sti_support
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 21
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
- - 0
10
- version: 1.0.0
9
+ - 1
10
+ version: 1.0.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Coroutine
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2010-10-10 00:00:00 -05:00
19
+ date: 2010-11-05 00:00:00 -05:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
data/Rakefile CHANGED
@@ -1,28 +1,28 @@
1
- require 'rake'
2
- require 'rake/testtask'
3
- require 'rake/rdoctask'
4
- require 'jeweler'
1
+ require "rake"
2
+ require "rake/testtask"
3
+ require "rake/rdoctask"
4
+ require "jeweler"
5
5
 
6
6
 
7
- desc 'Default: run tests.'
7
+ desc "Default: run tests."
8
8
  task :default => [:test]
9
9
 
10
10
 
11
- desc 'Test the plugin.'
11
+ desc "Test the gem."
12
12
  Rake::TestTask.new(:test) do |t|
13
- t.libs << 'lib'
14
- t.pattern = 'test/**/*_test.rb'
15
- t.verbose = true
13
+ t.libs << ["lib", "test"]
14
+ t.pattern = "test/**/*_test.rb"
15
+ t.verbose = true
16
16
  end
17
17
 
18
18
 
19
- desc 'Generate documentation for the plugin.'
19
+ desc 'Generate documentation for the gem.'
20
20
  Rake::RDocTask.new(:rdoc) do |rdoc|
21
- rdoc.rdoc_dir = 'rdoc'
22
- rdoc.title = 'acts_as_list_with_sti_support'
23
- rdoc.options << '--line-numbers --inline-source'
24
- rdoc.rdoc_files.include('README')
25
- rdoc.rdoc_files.include('lib/**/*.rb')
21
+ rdoc.rdoc_dir = "rdoc"
22
+ rdoc.title = "acts_as_list_with_sti_support"
23
+ rdoc.options << "--line-numbers --inline-source"
24
+ rdoc.rdoc_files.include("README")
25
+ rdoc.rdoc_files.include("lib/**/*.rb")
26
26
  end
27
27
 
28
28
 
@@ -30,7 +30,7 @@ begin
30
30
  Jeweler::Tasks.new do |gemspec|
31
31
  gemspec.authors = ["Coroutine", "John Dugan"]
32
32
  gemspec.description = "This acts_as extension does everything acts_as_list does, but it also works in single table inheritance designs and accepts less brain-damaged scope syntax."
33
- gemspec.email = "jdugan@coroutine.com"
33
+ gemspec.email = "gem@coroutine.com"
34
34
  gemspec.homepage = "http://github.com/coroutine/acts_as_list_with_sti_support"
35
35
  gemspec.name = "acts_as_list_with_sti_support"
36
36
  gemspec.summary = "Gem version of acts_as_list_with_sti_support Rails plugin, a smarter version of acts_as_list."
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.1
1
+ 1.0.2
@@ -5,13 +5,13 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{acts_as_list_with_sti_support}
8
- s.version = "1.0.1"
8
+ s.version = "1.0.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Coroutine", "John Dugan"]
12
- s.date = %q{2010-11-05}
12
+ s.date = %q{2010-12-13}
13
13
  s.description = %q{This acts_as extension does everything acts_as_list does, but it also works in single table inheritance designs and accepts less brain-damaged scope syntax.}
14
- s.email = %q{jdugan@coroutine.com}
14
+ s.email = %q{gem@coroutine.com}
15
15
  s.extra_rdoc_files = [
16
16
  "README.rdoc"
17
17
  ]
@@ -69,27 +69,29 @@ module Coroutine #:nodoc:
69
69
  validates_numericality_of column, :only_integer => true, :greater_than => 0, :allow_nil => true
70
70
 
71
71
 
72
- # Add callbacks
73
- begin
74
- before_validation :add_to_list_bottom, :on => :create # rails 3
75
- rescue
76
- before_validation_on_create :add_to_list_bottom # rails 2
77
- end
78
- before_destroy :remove_from_list
79
-
80
-
81
- # if no default scoping, order by position
82
- if self.default_scoping.empty?
83
- default_scope :order => column.to_s
84
- end
85
-
86
-
87
72
  # Include instance methods
88
73
  include Coroutine::ActsAsList::Base::InstanceMethods
89
74
 
75
+
76
+ # rails 3
77
+ if self.respond_to?(:arel_table)
78
+ before_validation :add_to_list_bottom, :if => :position_blank?, :on => :create
79
+ before_destroy :remove_from_list
80
+
81
+ # rails 2
82
+ else
83
+ before_validation_on_create :add_to_list_bottom, :if => :position_blank?
84
+ before_destroy :remove_from_list
85
+
86
+ if self.default_scoping.empty?
87
+ default_scope :order => column.to_s
88
+ end
89
+ end
90
+
90
91
  end
91
92
 
92
93
  end
94
+
93
95
  end
94
96
 
95
97
 
@@ -100,18 +102,21 @@ module Coroutine #:nodoc:
100
102
  #
101
103
  module InstanceMethods
102
104
 
103
- # Return the instance's class object
105
+ # This method returns the instance's class object
106
+ #
104
107
  def acts_as_list_class
105
108
  self.class
106
109
  end
107
110
 
108
- # Returns the column name that holds the position value.
111
+ # This method returns the column name that holds the position value.
112
+ #
109
113
  def position_column
110
114
  acts_as_list_column
111
115
  end
112
116
 
113
- # Returns the scope condition appropriate for the specified definition. (This could probably
114
- # be refactored for brevity.)
117
+ # This method returns the scope condition appropriate for the specified definition. (This
118
+ # could probably be refactored for brevity.)
119
+ #
115
120
  def scope_condition
116
121
  if acts_as_list_scope_condition.nil?
117
122
 
@@ -224,20 +229,21 @@ module Coroutine #:nodoc:
224
229
  def higher_item
225
230
  return nil unless in_list?
226
231
  conditions = "#{scope_condition} AND #{position_column} = #{(send(position_column).to_i - 1).to_s}"
227
- begin
232
+ if self.rails_3?
228
233
  acts_as_list_class.where(conditions).first
229
- rescue
234
+ else
230
235
  acts_as_list_class.find(:first, :conditions => conditions)
231
236
  end
232
237
  end
233
238
 
234
- # Return the next lower item in the list.
239
+ # This method returns the next lower item in the list.
240
+ #
235
241
  def lower_item
236
242
  return nil unless in_list?
237
243
  conditions = "#{scope_condition} AND #{position_column} = #{(send(position_column).to_i + 1).to_s}"
238
- begin
244
+ if self.rails_3?
239
245
  acts_as_list_class.where(conditions).first
240
- rescue
246
+ else
241
247
  acts_as_list_class.find(:first, :conditions => conditions)
242
248
  end
243
249
  end
@@ -247,40 +253,55 @@ module Coroutine #:nodoc:
247
253
  !send(position_column).nil?
248
254
  end
249
255
 
256
+ # This returns whether or not the position column is blank.
257
+ def position_blank?
258
+ return self.send(position_column).blank?
259
+ end
260
+
261
+ # This method indicates whether or not the gem is being used within the
262
+ # rails 3 environment.
263
+ def rails_3?
264
+ return acts_as_list_class.respond_to?(:arel_table)
265
+ end
266
+
267
+
268
+
250
269
  private
270
+
271
+ # This method adds the new item to the top of the list.
251
272
  def add_to_list_top
252
273
  increment_positions_on_all_items
253
274
  end
254
275
 
276
+ # This method adds the new item to the bottom of the list.
255
277
  def add_to_list_bottom
256
278
  self[position_column] = bottom_position_in_list.to_i + 1
257
279
  end
258
280
 
259
- # Returns the bottom position number in the list.
260
- # bottom_position_in_list # => 2
281
+ # This method returns the bottom position number in the list.
261
282
  def bottom_position_in_list(except = nil)
262
283
  item = bottom_item(except)
263
284
  item ? item.send(position_column) : 0
264
285
  end
265
286
 
266
- # Returns the bottom item
287
+ # This method returns the bottom item.
267
288
  def bottom_item(except = nil)
268
289
  conditions = scope_condition
269
- conditions = "#{conditions} AND #{self.class.primary_key} != #{except.id}" if except
290
+ conditions = "#{conditions} AND #{self.class.primary_key} != #{except.id}" unless except.blank?
270
291
  order_by = "#{position_column} DESC"
271
- begin
272
- acts_as_list_class.where(conditions).first.order(order_by)
273
- rescue
292
+ if self.rails_3?
293
+ acts_as_list_class.where(conditions).order(order_by).first
294
+ else
274
295
  acts_as_list_class.find(:first, :conditions => conditions, :order => order_by)
275
296
  end
276
297
  end
277
298
 
278
- # Forces item to assume the bottom position in the list.
299
+ # This method forces item to assume the bottom position in the list.
279
300
  def assume_bottom_position
280
301
  update_attribute(position_column, bottom_position_in_list(self).to_i + 1)
281
302
  end
282
303
 
283
- # Forces item to assume the top position in the list.
304
+ # This method forces item to assume the top position in the list.
284
305
  def assume_top_position
285
306
  update_attribute(position_column, 1)
286
307
  end
@@ -322,6 +343,7 @@ module Coroutine #:nodoc:
322
343
  )
323
344
  end
324
345
 
346
+ # This adds the item at the specified position value.
325
347
  def insert_at_position(position)
326
348
  remove_from_list
327
349
  increment_positions_on_lower_items(position)
@@ -3,7 +3,7 @@
3
3
  #---------------------------------------------------------
4
4
 
5
5
  # all generic requirements are in the helper
6
- require "test/test_helper"
6
+ require "test_helper"
7
7
 
8
8
 
9
9
 
@@ -99,9 +99,9 @@ end
99
99
 
100
100
  # Contacts
101
101
  class Contact < ActiveRecord::Base
102
- has_many :emails
103
- has_many :phones
104
- has_many :websites
102
+ has_many :emails, :order => "pos"
103
+ has_many :phones, :order => "position"
104
+ has_many :websites, :order => "position"
105
105
 
106
106
  def email_ids
107
107
  self.emails(true).map(&:id)
@@ -276,6 +276,39 @@ class ActsAsListTest < ActiveSupport::TestCase
276
276
 
277
277
 
278
278
 
279
+ #---------------------------------------------
280
+ # test default ordering
281
+ #---------------------------------------------
282
+
283
+ def test_default_ordering
284
+
285
+ # standard model
286
+ assert_equal 4, Contact.first.phones.size
287
+
288
+ p3 = Phone.create!({ :contact_id => Contact.last.id, :number => "901.555.7777" })
289
+ assert_equal 3, p3.position
290
+
291
+ p5 = Phone.create!({ :contact_id => Contact.last.id, :number => "901.555.9999", :position => 5 })
292
+ p4 = Phone.create!({ :contact_id => Contact.last.id, :number => "901.555.8888", :position => 4 })
293
+ assert_equal 4, p4.position
294
+ assert_equal 5, p5.position
295
+
296
+
297
+ # sti model
298
+ assert_equal 0, TaxFrequency.count
299
+
300
+ t1 = TaxFrequency.create!({ :label => "Monthly" })
301
+ assert_equal 1, t1.position
302
+
303
+ t3 = TaxFrequency.create!({ :label => "Yearly", :position => 3 })
304
+ t2 = TaxFrequency.create!({ :label => "Quarterly", :position => 2 })
305
+ assert_equal 2, t2.position
306
+ assert_equal 3, t3.position
307
+
308
+ end
309
+
310
+
311
+
279
312
  #---------------------------------------------
280
313
  # test ordering methods
281
314
  #---------------------------------------------
@@ -285,51 +318,51 @@ class ActsAsListTest < ActiveSupport::TestCase
285
318
  # standard model
286
319
  contact = Contact.first
287
320
  assert_equal [1, 2, 3, 4], contact.phone_ids
288
-
321
+
289
322
  Phone.find(2).move_lower
290
323
  assert_equal [1, 3, 2, 4], contact.phone_ids
291
-
324
+
292
325
  Phone.find(2).move_higher
293
326
  assert_equal [1, 2, 3, 4], contact.phone_ids
294
-
327
+
295
328
  Phone.find(1).move_to_bottom
296
329
  assert_equal [2, 3, 4, 1], contact.phone_ids
297
-
330
+
298
331
  Phone.find(1).move_to_top
299
332
  assert_equal [1, 2, 3, 4], contact.phone_ids
300
-
333
+
301
334
  Phone.find(2).move_to_bottom
302
335
  assert_equal [1, 3, 4, 2], contact.phone_ids
303
-
336
+
304
337
  Phone.find(4).move_to_top
305
338
  assert_equal [4, 1, 3, 2], contact.phone_ids
306
339
 
307
340
 
308
341
  # sti model
309
342
  assert_equal [1, 2, 3, 4], BillingFrequency.ids
310
-
343
+
311
344
  BillingFrequency.find(2).move_lower
312
345
  assert_equal [1, 3, 2, 4], BillingFrequency.ids
313
-
346
+
314
347
  BillingFrequency.find(2).move_higher
315
348
  assert_equal [1, 2, 3, 4], BillingFrequency.ids
316
-
349
+
317
350
  BillingFrequency.find(1).move_to_bottom
318
351
  assert_equal [2, 3, 4, 1], BillingFrequency.ids
319
-
352
+
320
353
  BillingFrequency.find(1).move_to_top
321
354
  assert_equal [1, 2, 3, 4], BillingFrequency.ids
322
-
355
+
323
356
  BillingFrequency.find(2).move_to_bottom
324
357
  assert_equal [1, 3, 4, 2], BillingFrequency.ids
325
-
358
+
326
359
  BillingFrequency.find(4).move_to_top
327
360
  assert_equal [4, 1, 3, 2], BillingFrequency.ids
328
361
  end
329
-
330
-
362
+
363
+
331
364
  def test_move_to_bottom_with_next_to_last_item
332
-
365
+
333
366
  # standard model
334
367
  contact = Contact.first
335
368
  assert_equal [1, 2, 3, 4], contact.phone_ids
@@ -360,8 +393,8 @@ class ActsAsListTest < ActiveSupport::TestCase
360
393
  assert_equal BillingFrequency.find(3), BillingFrequency.find(4).higher_item
361
394
  assert_nil BillingFrequency.find(4).lower_item
362
395
  end
363
-
364
-
396
+
397
+
365
398
  def test_insert
366
399
 
367
400
  # standard model
@@ -369,17 +402,17 @@ class ActsAsListTest < ActiveSupport::TestCase
369
402
  assert_equal 1, new.position
370
403
  assert new.first?
371
404
  assert new.last?
372
-
405
+
373
406
  new = Phone.create(:contact_id => 3, :number => "901.555.8888")
374
407
  assert_equal 2, new.position
375
408
  assert !new.first?
376
409
  assert new.last?
377
-
410
+
378
411
  new = Phone.create(:contact_id => 3, :number => "901.555.9999")
379
412
  assert_equal 3, new.position
380
413
  assert !new.first?
381
414
  assert new.last?
382
-
415
+
383
416
  new = Phone.create(:contact_id => 4, :number => "901.555.0000")
384
417
  assert_equal 1, new.position
385
418
  assert new.first?
@@ -391,17 +424,17 @@ class ActsAsListTest < ActiveSupport::TestCase
391
424
  assert_equal 1, new.position
392
425
  assert new.first?
393
426
  assert new.last?
394
-
427
+
395
428
  new = TaxFrequency.create(:label => "Quarterly")
396
429
  assert_equal 2, new.position
397
430
  assert !new.first?
398
431
  assert new.last?
399
-
432
+
400
433
  new = TaxFrequency.create(:label => "Yearly")
401
434
  assert_equal 3, new.position
402
435
  assert !new.first?
403
436
  assert new.last?
404
-
437
+
405
438
  new = PaymentFrequency.create(:label => "Monthly")
406
439
  assert_equal 1, new.position
407
440
  assert new.first?
@@ -414,34 +447,34 @@ class ActsAsListTest < ActiveSupport::TestCase
414
447
  # stadard model
415
448
  new = Phone.create(:contact_id => 3, :number => "615.555.1111")
416
449
  assert_equal 1, new.position
417
-
450
+
418
451
  new = Phone.create(:contact_id => 3, :number => "615.555.2222")
419
452
  assert_equal 2, new.position
420
-
453
+
421
454
  new = Phone.create(:contact_id => 3, :number => "615.555.3333")
422
455
  assert_equal 3, new.position
423
-
456
+
424
457
  new4 = Phone.create(:contact_id => 3, :number => "615.555.4444")
425
458
  assert_equal 4, new4.position
426
-
459
+
427
460
  new4.insert_at(3)
428
461
  assert_equal 3, new4.position
429
-
462
+
430
463
  new.reload
431
464
  assert_equal 4, new.position
432
-
465
+
433
466
  new.insert_at(2)
434
467
  assert_equal 2, new.position
435
-
468
+
436
469
  new4.reload
437
470
  assert_equal 4, new4.position
438
-
471
+
439
472
  new5 = Phone.create(:contact_id => 3, :number => "615.555.5555")
440
473
  assert_equal 5, new5.position
441
-
474
+
442
475
  new5.insert_at(1)
443
476
  assert_equal 1, new5.position
444
-
477
+
445
478
  new4.reload
446
479
  assert_equal 5, new4.position
447
480
 
@@ -449,45 +482,45 @@ class ActsAsListTest < ActiveSupport::TestCase
449
482
  # sti model
450
483
  new = TaxFrequency.create(:label => "Weekly")
451
484
  assert_equal 1, new.position
452
-
485
+
453
486
  new = TaxFrequency.create(:label => "Monthly")
454
487
  assert_equal 2, new.position
455
-
488
+
456
489
  new = TaxFrequency.create(:label => "Quarterly")
457
490
  assert_equal 3, new.position
458
-
491
+
459
492
  new4 = TaxFrequency.create(:label => "Yearly")
460
493
  assert_equal 4, new4.position
461
-
494
+
462
495
  new4.insert_at(3)
463
496
  assert_equal 3, new4.position
464
-
497
+
465
498
  new.reload
466
499
  assert_equal 4, new.position
467
-
500
+
468
501
  new.insert_at(2)
469
502
  assert_equal 2, new.position
470
-
503
+
471
504
  new4.reload
472
505
  assert_equal 4, new4.position
473
-
506
+
474
507
  new5 = TaxFrequency.create(:label => "Daily")
475
508
  assert_equal 5, new5.position
476
-
509
+
477
510
  new5.insert_at(1)
478
511
  assert_equal 1, new5.position
479
-
512
+
480
513
  new4.reload
481
514
  assert_equal 5, new4.position
482
515
  end
483
-
484
-
516
+
517
+
485
518
  def test_delete_middle
486
519
 
487
520
  # standard model
488
521
  contact = Contact.first
489
522
  assert_equal [1, 2, 3, 4], contact.phone_ids
490
-
523
+
491
524
  Phone.find(2).destroy
492
525
  assert_equal [1, 3, 4], contact.phone_ids
493
526
 
@@ -498,8 +531,8 @@ class ActsAsListTest < ActiveSupport::TestCase
498
531
  Phone.find(1).destroy
499
532
  assert_equal [3, 4], contact.phone_ids
500
533
 
501
- # assert_equal 1, Phone.find(3).position
502
- # assert_equal 2, Phone.find(4).position
534
+ assert_equal 1, Phone.find(3).position
535
+ assert_equal 2, Phone.find(4).position
503
536
 
504
537
 
505
538
  # sti model
@@ -518,8 +551,8 @@ class ActsAsListTest < ActiveSupport::TestCase
518
551
  assert_equal 1, BillingFrequency.find(3).position
519
552
  assert_equal 2, BillingFrequency.find(4).position
520
553
  end
521
-
522
-
554
+
555
+
523
556
  def test_remove_from_list_should_then_fail_in_list?
524
557
 
525
558
  # standard model
@@ -535,7 +568,7 @@ class ActsAsListTest < ActiveSupport::TestCase
535
568
  BillingFrequency.find(1).remove_from_list
536
569
  assert_equal false, BillingFrequency.find(1).in_list?
537
570
  end
538
-
571
+
539
572
 
540
573
  def test_remove_from_list_should_set_position_to_nil
541
574
 
@@ -563,8 +596,8 @@ class ActsAsListTest < ActiveSupport::TestCase
563
596
  assert_equal 2, BillingFrequency.find(3).position
564
597
  assert_equal 3, BillingFrequency.find(4).position
565
598
  end
566
-
567
-
599
+
600
+
568
601
  def test_remove_before_destroy_does_not_shift_lower_items_twice
569
602
 
570
603
  # standard model
@@ -13,13 +13,33 @@ require "#{File.dirname(__FILE__)}/../init"
13
13
  # Define global methods
14
14
  #----------------------------------------------------------
15
15
 
16
+ def puts_debug(*args)
17
+ objs = args.flatten
18
+
19
+ puts ""
20
+ puts "======================================"
21
+ objs.each_with_index do |obj, index|
22
+ puts "--------------------------------------" unless index == 0
23
+ puts "DEBUG: #{obj.inspect}"
24
+ end
25
+ puts "======================================"
26
+ puts ""
27
+ end
28
+
29
+
30
+
31
+ #----------------------------------------------------------
32
+ # Extend test class
33
+ #----------------------------------------------------------
34
+
16
35
  class ActiveSupport::TestCase
17
36
 
18
37
  # This method allows us to use a convenient notation for testing
19
38
  # model validations.
39
+ #
20
40
  def assert_not_valid(object, msg="Object is valid when it should be invalid")
21
41
  assert(!object.valid?, msg)
22
42
  end
23
43
  alias :assert_invalid :assert_not_valid
24
-
44
+
25
45
  end
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acts_as_list_with_sti_support
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
5
4
  prerelease: false
6
5
  segments:
7
6
  - 1
8
7
  - 0
9
- - 1
10
- version: 1.0.1
8
+ - 2
9
+ version: 1.0.2
11
10
  platform: ruby
12
11
  authors:
13
12
  - Coroutine
@@ -16,7 +15,7 @@ autorequire:
16
15
  bindir: bin
17
16
  cert_chain: []
18
17
 
19
- date: 2010-11-05 00:00:00 -05:00
18
+ date: 2010-12-13 00:00:00 -06:00
20
19
  default_executable:
21
20
  dependencies:
22
21
  - !ruby/object:Gem::Dependency
@@ -27,7 +26,6 @@ dependencies:
27
26
  requirements:
28
27
  - - ">="
29
28
  - !ruby/object:Gem::Version
30
- hash: 11
31
29
  segments:
32
30
  - 2
33
31
  - 3
@@ -43,7 +41,6 @@ dependencies:
43
41
  requirements:
44
42
  - - ">="
45
43
  - !ruby/object:Gem::Version
46
- hash: 11
47
44
  segments:
48
45
  - 2
49
46
  - 3
@@ -52,7 +49,7 @@ dependencies:
52
49
  type: :development
53
50
  version_requirements: *id002
54
51
  description: This acts_as extension does everything acts_as_list does, but it also works in single table inheritance designs and accepts less brain-damaged scope syntax.
55
- email: jdugan@coroutine.com
52
+ email: gem@coroutine.com
56
53
  executables: []
57
54
 
58
55
  extensions: []
@@ -87,7 +84,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
87
84
  requirements:
88
85
  - - ">="
89
86
  - !ruby/object:Gem::Version
90
- hash: 3
91
87
  segments:
92
88
  - 0
93
89
  version: "0"
@@ -96,7 +92,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
96
92
  requirements:
97
93
  - - ">="
98
94
  - !ruby/object:Gem::Version
99
- hash: 3
100
95
  segments:
101
96
  - 0
102
97
  version: "0"