spree_core 5.3.2 → 5.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/app/models/spree/invitation.rb +1 -1
  3. data/app/models/spree/store_product.rb +2 -0
  4. data/lib/generators/spree/dummy/templates/rails/database.yml +6 -6
  5. data/lib/spree/core/controller_helpers/auth.rb +2 -0
  6. data/lib/spree/core/version.rb +1 -1
  7. data/lib/spree/testing_support/common_rake.rb +53 -0
  8. data/lib/spree/testing_support/factories/calculator_factory.rb +4 -4
  9. data/lib/spree/testing_support/factories/custom_domain_factory.rb +1 -1
  10. data/lib/spree/testing_support/factories/customer_group_user_factory.rb +1 -1
  11. data/lib/spree/testing_support/factories/export_factory.rb +2 -2
  12. data/lib/spree/testing_support/factories/google_data_feed_factory.rb +1 -2
  13. data/lib/spree/testing_support/factories/import_factory.rb +1 -1
  14. data/lib/spree/testing_support/factories/invitation_factory.rb +1 -1
  15. data/lib/spree/testing_support/factories/line_item_factory.rb +11 -6
  16. data/lib/spree/testing_support/factories/order_factory.rb +5 -5
  17. data/lib/spree/testing_support/factories/payment_factory.rb +1 -1
  18. data/lib/spree/testing_support/factories/post_factory.rb +3 -3
  19. data/lib/spree/testing_support/factories/product_factory.rb +6 -3
  20. data/lib/spree/testing_support/factories/product_property_factory.rb +1 -1
  21. data/lib/spree/testing_support/factories/prototype_factory.rb +3 -3
  22. data/lib/spree/testing_support/factories/report_factory.rb +4 -4
  23. data/lib/spree/testing_support/factories/store_credit_event_factory.rb +1 -1
  24. data/lib/spree/testing_support/factories/store_credit_factory.rb +3 -3
  25. data/lib/spree/testing_support/factories/user_factory.rb +3 -5
  26. data/lib/spree/testing_support/factories/variant_factory.rb +3 -4
  27. data/lib/spree/testing_support/factories/zone_factory.rb +8 -5
  28. data/lib/spree/testing_support/factories.rb +1 -1
  29. data/lib/spree/testing_support/store.rb +1 -5
  30. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8852343e0b0e126beaff8b5745ca76527a0c436344f670c2cdab2f27eeb1f23f
4
- data.tar.gz: a3378bc532a952c8d72190c5ebfb244c07b103a8f4bb67ec3bcf889278395a45
3
+ metadata.gz: '08d9b1a3cf8bea4f049c9dd444d3f1977e5752adfec8d31dc1fd91d8ee7ccc00'
4
+ data.tar.gz: c3653bae9f794377013d94700bee1eaa9da04485737584af25f103f091e662f5
5
5
  SHA512:
6
- metadata.gz: 893e2c5b7d12b76c599a35ed91df5062fb8849144c4dd34cfc528b59c7c8d993ef523e443d3aba36e949af5814f68105af80fc3caee9295919d53eb5fe3ed137
7
- data.tar.gz: 81cdf22db519e0695e36363a097a0b6703e4bba5a44aff5989bb225d5ea2f16e1ffa087507c2af57254bdd1c3fd0b24b5649b56bca0ee8b38bc46bee59172041
6
+ metadata.gz: 987979ba7a79782bd0412b510a3ecf566b61adfc6af241801a547c5b26bd401e3a16475cfdd3712ab29db5c062a5e8dfadea2d7c21634e773b0dd8fbab8f0423
7
+ data.tar.gz: 73229e1625bafe9ca1c1d8d00d0d1069bdca226aa91ee462abad53e618e4cd546a09cc242d9829a3f7a74ddae11e0ab69f9e4f9bdaf245ae1b4748af95ecb46a
@@ -54,7 +54,7 @@ module Spree
54
54
  #
55
55
  after_initialize :set_defaults, if: :new_record?
56
56
  before_validation :set_invitee_from_email, on: :create
57
- after_create :publish_invitation_created_event, unless: :skip_email
57
+ after_commit :publish_invitation_created_event, on: :create, unless: :skip_email
58
58
 
59
59
  # returns the store for the invitation
60
60
  # if the resource is a store, return the resource
@@ -9,6 +9,8 @@ module Spree
9
9
  validates :store_id, uniqueness: { scope: :product_id }
10
10
 
11
11
  def refresh_metrics!
12
+ return if product.nil?
13
+
12
14
  completed_order_ids = product.completed_orders.where(store_id: store_id).select(:id)
13
15
  variant_ids = product.variants_including_master.ids
14
16
 
@@ -14,7 +14,7 @@ development:
14
14
  database: db/spree_development.sqlite3
15
15
  test:
16
16
  adapter: sqlite3
17
- database: db/spree_test.sqlite3
17
+ database: db/spree_test<%%= ENV['TEST_ENV_NUMBER'] %>.sqlite3
18
18
  timeout: 10000
19
19
  production:
20
20
  adapter: sqlite3
@@ -40,7 +40,7 @@ development:
40
40
  database: <%= database_prefix %><%= lib_name %>_spree_development
41
41
  test:
42
42
  <<: *mysql
43
- database: <%= database_prefix %><%= lib_name %>_spree_test
43
+ database: <%= database_prefix %><%= lib_name %>_spree_test<%%= ENV['TEST_ENV_NUMBER'] %>
44
44
  production:
45
45
  <<: *mysql
46
46
  database: <%= database_prefix %><%= lib_name %>_spree_production
@@ -57,14 +57,14 @@ postgres: &postgres
57
57
  host: <%= db_host %>
58
58
  <% end %>
59
59
  min_messages: warning
60
- pool: <%= ENV["DB_POOL"] || 50 %>
60
+ pool: <%%= ENV.fetch("DB_POOL", 50) %>
61
61
 
62
62
  development:
63
63
  <<: *postgres
64
64
  database: <%= database_prefix %><%= lib_name %>_spree_development
65
65
  test:
66
66
  <<: *postgres
67
- database: <%= database_prefix %><%= lib_name %>_spree_test
67
+ database: <%= database_prefix %><%= lib_name %>_spree_test<%%= ENV['TEST_ENV_NUMBER'] %>
68
68
  production:
69
69
  <<: *postgres
70
70
  database: <%= database_prefix %><%= lib_name %>_spree_production
@@ -74,8 +74,8 @@ development:
74
74
  database: db/spree_development.sqlite3
75
75
  test:
76
76
  adapter: sqlite3
77
- database: db/spree_test.sqlite3
77
+ database: db/spree_test<%%= ENV['TEST_ENV_NUMBER'] %>.sqlite3
78
78
  production:
79
79
  adapter: sqlite3
80
80
  database: db/spree_production.sqlite3
81
- <% end %>
81
+ <% end %>
@@ -21,6 +21,8 @@ module Spree
21
21
  end
22
22
 
23
23
  def current_oauth_token
24
+ Spree::Deprecation.warn('Spree::Current.oauth_token is deprecated and will be removed in Spree 5.5')
25
+
24
26
  get_last_access_token = ->(user) { Spree::OauthAccessToken.active_for(user).where(expires_in: nil).last }
25
27
  create_access_token = ->(user) { Spree::OauthAccessToken.create!(resource_owner: user) }
26
28
  user = try_spree_current_user
@@ -1,5 +1,5 @@
1
1
  module Spree
2
- VERSION = '5.3.2'.freeze
2
+ VERSION = '5.3.3'.freeze
3
3
 
4
4
  def self.version
5
5
  VERSION
@@ -134,3 +134,56 @@ namespace :common do
134
134
  system('bundle exec rake db:seed RAILS_ENV=test > /dev/null 2>&1')
135
135
  end
136
136
  end
137
+
138
+ # Custom parallel setup task instead of parallel_tests' native parallel:create/parallel:prepare
139
+ # because Spree gems are not Rails apps — the Rails app lives in spec/dummy/ and db: rake tasks
140
+ # are not available from the gem directory. For SQLite, we copy the primary .sqlite3 file which
141
+ # is faster than creating + migrating N databases through Rails.
142
+ desc 'Create and prepare databases for parallel test workers'
143
+ task :parallel_setup, [:count] do |_t, args|
144
+ require 'parallel'
145
+
146
+ count = (args[:count] || ENV.fetch('PARALLEL_TEST_PROCESSORS', Parallel.processor_count)).to_i
147
+ dummy_path = ENV['DUMMY_PATH'] || 'spec/dummy'
148
+ db_config_path = File.join(dummy_path, 'config', 'database.yml')
149
+
150
+ raise "Database config not found at #{db_config_path}. Run 'rake test_app' first." unless File.exist?(db_config_path)
151
+
152
+ require 'erb'
153
+ require 'yaml'
154
+
155
+ db_config = YAML.safe_load(ERB.new(File.read(db_config_path)).result, permitted_classes: [Symbol])
156
+ adapter = db_config.dig('test', 'adapter')
157
+
158
+ if adapter == 'sqlite3'
159
+ # For SQLite, copy the primary test database for each worker
160
+ primary_db = File.join(dummy_path, db_config.dig('test', 'database'))
161
+
162
+ raise "Primary test database not found at #{primary_db}. Run 'rake test_app' first." unless File.exist?(primary_db)
163
+
164
+ 2.upto(count) do |i|
165
+ worker_db = primary_db.sub(/\.sqlite3$/, "#{i}.sqlite3")
166
+ FileUtils.cp(primary_db, worker_db)
167
+ puts "Created parallel database: #{worker_db}"
168
+ end
169
+ else
170
+ # For PostgreSQL/MySQL, create and migrate each worker's database
171
+ 2.upto(count) do |i|
172
+ env_vars = "TEST_ENV_NUMBER=#{i} RAILS_ENV=test"
173
+ puts "Setting up database for worker #{i}..."
174
+ Dir.chdir(dummy_path) do
175
+ system("#{env_vars} bundle exec rake db:create db:migrate") || raise("Failed to setup database for worker #{i}")
176
+ end
177
+ end
178
+ end
179
+
180
+ puts "Parallel databases setup complete (#{count} workers)"
181
+ end
182
+
183
+ desc 'Run specs in parallel'
184
+ task :parallel_spec, [:count] do |_t, args|
185
+ count = args[:count] || ENV.fetch('PARALLEL_TEST_PROCESSORS', nil)
186
+ count_arg = count ? "-n #{count}" : ''
187
+ success = system("bundle exec parallel_rspec #{count_arg} spec")
188
+ exit(success ? 0 : 1)
189
+ end
@@ -1,10 +1,10 @@
1
1
  FactoryBot.define do
2
2
  factory :calculator, class: Spree::Calculator::FlatRate do
3
- after(:create) { |c| c.set_preference(:amount, 10.0) }
3
+ preferred_amount { 10.0 }
4
4
  end
5
5
 
6
6
  factory :no_amount_calculator, class: Spree::Calculator::FlatRate do
7
- after(:create) { |c| c.set_preference(:amount, 0) }
7
+ preferred_amount { 0 }
8
8
  end
9
9
 
10
10
  factory :default_tax_calculator, class: Spree::Calculator::DefaultTax do
@@ -27,10 +27,10 @@ FactoryBot.define do
27
27
  end
28
28
 
29
29
  factory :non_free_shipping_calculator, class: Spree::Calculator::Shipping::FlatRate do
30
- after(:create) { |c| c.set_preference(:amount, 20.0) }
30
+ preferred_amount { 20.0 }
31
31
  end
32
32
 
33
33
  factory :digital_shipping_calculator, class: Spree::Calculator::Shipping::DigitalDelivery do
34
- after(:create) { |c| c.set_preference(:amount, 0) }
34
+ preferred_amount { 0 }
35
35
  end
36
36
  end
@@ -1,7 +1,7 @@
1
1
  FactoryBot.define do
2
2
  factory :custom_domain, class: Spree::CustomDomain do
3
3
  url { FFaker::Internet.domain_name }
4
- store { create(:store) }
4
+ association :store, factory: :store
5
5
  default { true }
6
6
  end
7
7
  end
@@ -1,6 +1,6 @@
1
1
  FactoryBot.define do
2
2
  factory :customer_group_user, class: Spree::CustomerGroupUser do
3
3
  customer_group
4
- user { create(:user) }
4
+ user
5
5
  end
6
6
  end
@@ -1,7 +1,7 @@
1
1
  FactoryBot.define do
2
2
  factory :export, class: 'Spree::Export' do
3
- store { create(:store) }
4
- user { create(:admin_user) }
3
+ association :store, factory: :store
4
+ association :user, factory: :admin_user
5
5
  type { 'Spree::Exports::Products' }
6
6
  format { 'csv' }
7
7
 
@@ -1,8 +1,7 @@
1
1
  FactoryBot.define do
2
2
  factory :google_data_feed, class: Spree::DataFeed::Google do
3
- id { 1 }
4
3
  active { true }
5
- store { create(:store) }
4
+ association :store, factory: :store
6
5
  name { 'test' }
7
6
  end
8
7
  end
@@ -1,7 +1,7 @@
1
1
  FactoryBot.define do
2
2
  factory :import, class: 'Spree::Import' do
3
3
  owner { Spree::Store.default || create(:store) }
4
- user { create(:admin_user) }
4
+ association :user, factory: :admin_user
5
5
  type { 'Spree::Imports::Products' }
6
6
 
7
7
  factory :product_import, class: 'Spree::Imports::Products', parent: :import do
@@ -1,6 +1,6 @@
1
1
  FactoryBot.define do
2
2
  factory :invitation, class: Spree::Invitation do
3
3
  email { FFaker::Internet.email }
4
- inviter { create(:admin_user) }
4
+ association :inviter, factory: :admin_user
5
5
  end
6
6
  end
@@ -4,13 +4,18 @@ FactoryBot.define do
4
4
  quantity { 1 }
5
5
  price { BigDecimal('10.00') }
6
6
  currency { order.currency }
7
- product do
8
- if order&.store&.present?
9
- create(:product, stores: [order.store])
10
- else
11
- create(:product)
7
+ transient do
8
+ product { nil }
9
+ end
10
+ variant do
11
+ resolved_product = product || begin
12
+ if order&.store&.present?
13
+ create(:product, stores: [order.store])
14
+ else
15
+ create(:product)
16
+ end
12
17
  end
18
+ resolved_product.master
13
19
  end
14
- variant { product.master }
15
20
  end
16
21
  end
@@ -13,10 +13,11 @@ FactoryBot.define do
13
13
 
14
14
  before(:create) do |order|
15
15
  unless order.store.present?
16
- default_store = Spree::Store.default.persisted? ? Spree::Store.default : nil
17
- store = default_store || create(:store)
18
-
19
- order.store = store
16
+ store = begin
17
+ default = Spree::Store.default
18
+ default&.persisted? ? default : nil
19
+ end
20
+ order.store = store || create(:store)
20
21
  end
21
22
  end
22
23
 
@@ -42,7 +43,6 @@ FactoryBot.define do
42
43
  end
43
44
 
44
45
  factory :order_with_line_items do
45
- bill_address
46
46
  ship_address
47
47
 
48
48
  transient do
@@ -23,7 +23,7 @@ FactoryBot.define do
23
23
 
24
24
  factory :check_payment, class: Spree::Payment do
25
25
  amount { 45.75 }
26
- order { create(:order, total: 45.75) }
26
+ order { create(:order, total: amount) }
27
27
 
28
28
  association(:payment_method, factory: :check_payment_method)
29
29
  end
@@ -1,11 +1,11 @@
1
1
  FactoryBot.define do
2
2
  factory :post, class: Spree::Post do
3
- post_category { create(:post_category, store: Spree::Store.default || create(:store)) }
3
+ store { Spree::Store.default || create(:store) }
4
+ post_category { association(:post_category, store: store) }
4
5
  title { FFaker::Lorem.sentence }
5
6
  content { FFaker::Lorem.paragraph }
6
7
  published_at { Time.current }
7
- author { create(:admin_user) }
8
- store { Spree::Store.default || create(:store) }
8
+ association :author, factory: :admin_user
9
9
 
10
10
  trait :with_image do
11
11
  image { Rack::Test::UploadedFile.new(Spree::Core::Engine.root.join('spec/fixtures/thinking-cat.jpg'), 'image/jpeg') }
@@ -19,7 +19,10 @@ FactoryBot.define do
19
19
  create(:store, default: true) unless Spree::Store.any?
20
20
  end
21
21
  after(:create) do |product|
22
- Spree::StockLocation.all.each { |stock_location| stock_location.propagate_variant(product.master) unless stock_location.stock_items.exists?(variant: product.master) }
22
+ existing_location_ids = product.master.stock_items.pluck(:stock_location_id)
23
+ Spree::StockLocation.where.not(id: existing_location_ids).find_each do |stock_location|
24
+ stock_location.propagate_variant(product.master)
25
+ end
23
26
  end
24
27
 
25
28
  factory :custom_product do
@@ -49,8 +52,8 @@ FactoryBot.define do
49
52
  end
50
53
  factory :product_with_properties do
51
54
  after(:create) do |product|
52
- create(:property, :brand, id: 10)
53
- create(:product_property, product: product, property_id: 10, value: 'Epsilon')
55
+ property = create(:property, :brand)
56
+ create(:product_property, product: product, property: property, value: 'Epsilon')
54
57
  end
55
58
  end
56
59
 
@@ -1,6 +1,6 @@
1
1
  FactoryBot.define do
2
2
  factory :product_property, class: Spree::ProductProperty do
3
- product { create(:product, stores: [Spree::Store.default]) }
3
+ product
4
4
  value { "val-#{rand(50)}" }
5
5
  property
6
6
  end
@@ -1,11 +1,11 @@
1
1
  FactoryBot.define do
2
2
  factory :prototype, class: Spree::Prototype do
3
3
  name { 'Baseball Cap' }
4
- properties { [create(:property)] }
4
+ properties { [build(:property)] }
5
5
  end
6
6
  factory :prototype_with_option_types, class: Spree::Prototype do
7
7
  name { 'Baseball Cap' }
8
- properties { [create(:property)] }
9
- option_types { [create(:option_type)] }
8
+ properties { [build(:property)] }
9
+ option_types { [build(:option_type)] }
10
10
  end
11
11
  end
@@ -14,8 +14,8 @@
14
14
  #
15
15
  FactoryBot.define do
16
16
  factory :report, class: 'Spree::Reports::SalesTotal' do
17
- store { create(:store) }
18
- user { create(:admin_user) }
17
+ association :store, factory: :store
18
+ association :user, factory: :admin_user
19
19
  type { 'Spree::Reports::SalesTotal' }
20
20
  currency { 'USD' }
21
21
  date_from { 1.month.ago }
@@ -23,8 +23,8 @@ FactoryBot.define do
23
23
  end
24
24
 
25
25
  factory :products_performance_report, class: 'Spree::Reports::ProductsPerformance' do
26
- store { create(:store) }
27
- user { create(:admin_user) }
26
+ association :store, factory: :store
27
+ association :user, factory: :admin_user
28
28
  type { 'Spree::Reports::ProductsPerformance' }
29
29
  currency { 'USD' }
30
30
  date_from { 1.month.ago }
@@ -1,6 +1,6 @@
1
1
  FactoryBot.define do
2
2
  factory :store_credit_auth_event, class: Spree::StoreCreditEvent do
3
- store_credit { create(:store_credit) }
3
+ association :store_credit, factory: :store_credit
4
4
  action { Spree::StoreCredit::AUTHORIZE_ACTION }
5
5
  amount { 100.00 }
6
6
  authorization_code { "#{store_credit.id}-SC-20140602164814476128" }
@@ -3,11 +3,11 @@ FactoryBot.define do
3
3
 
4
4
  factory :store_credit, class: Spree::StoreCredit do
5
5
  user
6
- created_by { create(:admin_user) }
7
- category { create(:store_credit_category) }
6
+ association :created_by, factory: :admin_user
7
+ association :category, factory: :store_credit_category
8
8
  amount { 150.00 }
9
9
  currency { 'USD' }
10
- credit_type { create(:primary_credit_type) }
10
+ association :credit_type, factory: :primary_credit_type
11
11
  store { Spree::Store.default || create(:store) }
12
12
  end
13
13
 
@@ -13,11 +13,9 @@ FactoryBot.define do
13
13
 
14
14
  factory :user_with_addresses, aliases: [:user_with_addreses] do
15
15
  after(:create) do |user|
16
- user.ship_address = create(:address, user: user)
17
- user.bill_address = create(:address, user: user)
18
- user.addresses << user.ship_address
19
- user.addresses << user.bill_address
20
- user.save
16
+ ship_address = create(:address, user: user)
17
+ bill_address = create(:address, user: user)
18
+ user.update_columns(ship_address_id: ship_address.id, bill_address_id: bill_address.id)
21
19
  end
22
20
  end
23
21
  end
@@ -13,7 +13,7 @@ FactoryBot.define do
13
13
  track_inventory { true }
14
14
 
15
15
  product { |p| p.association(:base_product, stores: [Spree::Store.default]) }
16
- option_values { [create(:option_value)] }
16
+ option_values { [build(:option_value)] }
17
17
 
18
18
  transient do
19
19
  create_stock { true }
@@ -26,9 +26,8 @@ FactoryBot.define do
26
26
 
27
27
  after(:create) do |variant, evaluator|
28
28
  if evaluator.create_stock
29
- Spree::StockLocation.all.each do |stock_location|
30
- next if stock_location.stock_item(variant).present?
31
-
29
+ existing_location_ids = variant.stock_items.pluck(:stock_location_id)
30
+ Spree::StockLocation.where.not(id: existing_location_ids).find_each do |stock_location|
32
31
  stock_location.propagate_variant(variant)
33
32
  end
34
33
  end
@@ -13,13 +13,16 @@ FactoryBot.define do
13
13
  end
14
14
 
15
15
  factory :global_zone, class: Spree::Zone do
16
- sequence(:name) { |n| "GlobalZone_#{n}" }
16
+ name { 'GlobalZone' }
17
17
 
18
- zone_members do |proxy|
19
- zone = proxy.instance_eval { @instance }
18
+ after(:create) do |zone|
19
+ country_ids = Spree::Country.pluck(:id)
20
+ existing_ids = zone.zone_members.where(zoneable_type: 'Spree::Country').pluck(:zoneable_id)
21
+ new_ids = country_ids - existing_ids
20
22
 
21
- Spree::Country.all.map do |country|
22
- Spree::ZoneMember.where(zoneable: country, zone: zone).first_or_create
23
+ if new_ids.any?
24
+ records = new_ids.map { |id| { zoneable_type: 'Spree::Country', zoneable_id: id, zone_id: zone.id, created_at: Time.current, updated_at: Time.current } }
25
+ Spree::ZoneMember.insert_all(records)
23
26
  end
24
27
  end
25
28
  end
@@ -2,7 +2,7 @@ require 'factory_bot'
2
2
 
3
3
  Spree::Zone.class_eval do
4
4
  def self.global
5
- find_by(name: 'GlobalZone') || FactoryBot.create(:global_zone)
5
+ find_by(name: 'GlobalZone') || FactoryBot.create(:global_zone, name: 'GlobalZone')
6
6
  end
7
7
  end
8
8
 
@@ -34,10 +34,6 @@ RSpec.configure do |config|
34
34
  end
35
35
 
36
36
  config.after(:all) do
37
- unless self.class.metadata[:without_global_store]
38
- DatabaseCleaner.strategy = :transaction
39
- DatabaseCleaner.clean_with(:truncation)
40
- clear_enqueued_jobs
41
- end
37
+ clear_enqueued_jobs
42
38
  end
43
39
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spree_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.3.2
4
+ version: 5.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Schofield
@@ -1717,9 +1717,9 @@ licenses:
1717
1717
  - BSD-3-Clause
1718
1718
  metadata:
1719
1719
  bug_tracker_uri: https://github.com/spree/spree/issues
1720
- changelog_uri: https://github.com/spree/spree/releases/tag/v5.3.2
1720
+ changelog_uri: https://github.com/spree/spree/releases/tag/v5.3.3
1721
1721
  documentation_uri: https://docs.spreecommerce.org/
1722
- source_code_uri: https://github.com/spree/spree/tree/v5.3.2
1722
+ source_code_uri: https://github.com/spree/spree/tree/v5.3.3
1723
1723
  rdoc_options: []
1724
1724
  require_paths:
1725
1725
  - lib