spree_shipping_matrix 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/.gitignore +14 -0
  2. data/.rspec +3 -0
  3. data/.tailor +29 -0
  4. data/.travis.yml +20 -0
  5. data/Gemfile +7 -0
  6. data/LICENSE +22 -0
  7. data/README.md +56 -0
  8. data/Rakefile +28 -0
  9. data/Versionfile +1 -0
  10. data/app/assets/javascripts/spree/backend/spree_shipping_matrix.js +42 -0
  11. data/app/assets/javascripts/spree/frontend/spree_shipping_matrix.js +2 -0
  12. data/app/assets/stylesheets/spree/backend/spree_shipping_matrix.css +3 -0
  13. data/app/assets/stylesheets/spree/frontend/spree_shipping_matrix.css +4 -0
  14. data/app/controllers/spree/admin/shipping_matrices_controller.rb +13 -0
  15. data/app/helpers/spree/admin/base_helper_decorator.rb +9 -0
  16. data/app/helpers/spree/admin/form_builder_decorator.rb +9 -0
  17. data/app/models/spree/shipping_matrix.rb +18 -0
  18. data/app/models/spree/shipping_matrix_calculator.rb +40 -0
  19. data/app/models/spree/shipping_matrix_rule.rb +39 -0
  20. data/app/overrides/spree/admin/shared/_configuration_menu/add_shipping_matrix_link.html.erb.deface +2 -0
  21. data/app/views/spree/admin/shipping_matrices/_form.html.erb +18 -0
  22. data/app/views/spree/admin/shipping_matrices/edit.html.erb +25 -0
  23. data/app/views/spree/admin/shipping_matrices/index.html.erb +63 -0
  24. data/app/views/spree/admin/shipping_matrices/new.html.erb +11 -0
  25. data/app/views/spree/admin/shipping_matrices/new.js.erb +6 -0
  26. data/app/views/spree/admin/shipping_matrix_rules/_form.html.erb +33 -0
  27. data/bin/rails +7 -0
  28. data/config/locales/en.yml +13 -0
  29. data/config/routes.rb +5 -0
  30. data/db/migrate/20140826110342_create_spree_shipping_matrices.rb +8 -0
  31. data/db/migrate/20140826112807_create_spree_shipping_matrix_rules.rb +10 -0
  32. data/lib/generators/spree_shipping_matrix/install/install_generator.rb +27 -0
  33. data/lib/spree_shipping_matrix/engine.rb +25 -0
  34. data/lib/spree_shipping_matrix/version.rb +3 -0
  35. data/lib/spree_shipping_matrix.rb +2 -0
  36. data/spec/factories/shipping_matrix_factory.rb +17 -0
  37. data/spec/factories/shipping_matrix_rule_factory.rb +8 -0
  38. data/spec/features/shipping_matrix_calculator_spec.rb +34 -0
  39. data/spec/features/shipping_matrix_checkout_spec.rb +92 -0
  40. data/spec/features/shipping_matrix_spec.rb +86 -0
  41. data/spec/spec_helper.rb +91 -0
  42. data/spec/support/user_steps.rb +22 -0
  43. data/spec/unit/models/shipping_matrix_calculator_spec.rb +81 -0
  44. data/spec/unit/models/shipping_matrix_rule_spec.rb +35 -0
  45. data/spec/unit/models/shipping_matrix_spec.rb +39 -0
  46. data/spree_shipping_matrix.gemspec +42 -0
  47. metadata +298 -0
@@ -0,0 +1,2 @@
1
+ require 'spree_core'
2
+ require 'spree_shipping_matrix/engine'
@@ -0,0 +1,17 @@
1
+ FactoryGirl.define do
2
+ factory :shipping_matrix, class: Spree::ShippingMatrix do
3
+ name 'A shipping matrix'
4
+
5
+ factory :shipping_matrix_with_rules do
6
+ ignore do
7
+ num_of_rules 1
8
+ end
9
+
10
+ after(:create) do |matrix, evaluator|
11
+ evaluator.num_of_rules.times do
12
+ FactoryGirl.create(:shipping_matrix_rule, matrix: matrix)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,8 @@
1
+ FactoryGirl.define do
2
+ factory :shipping_matrix_rule, class: Spree::ShippingMatrixRule do
3
+ association :matrix, factory: :shipping_matrix
4
+ association :role
5
+ min_line_item_total 25
6
+ amount 2.99
7
+ end
8
+ end
@@ -0,0 +1,34 @@
1
+ feature 'Shipping Matrix Calculator' do
2
+ before(:each) do
3
+ given_i_am_logged_into_the_cms
4
+ and_i_have_shipping_category
5
+ and_i_have_shipping_matrices_and_rules
6
+ end
7
+
8
+ scenario 'creating a shipping method using matrix calculator', js: true do
9
+ when_i_create_a_new_shipping_method_using_matrix_calculator
10
+ then_the_num_of_shipping_methods_should_be(1)
11
+ end
12
+ end
13
+
14
+ def and_i_have_shipping_category
15
+ create(:shipping_category)
16
+ end
17
+
18
+ def and_i_have_shipping_matrices_and_rules
19
+ create(:shipping_matrix_with_rules, num_of_rules: 3)
20
+ end
21
+
22
+ def when_i_create_a_new_shipping_method_using_matrix_calculator
23
+ visit spree.new_admin_shipping_method_path
24
+ fill_in :shipping_method_name, with: 'UK Next Day'
25
+ fill_in :shipping_method_admin_name, with: 'UK Next Day'
26
+ all('[type=checkbox]').each { |checkbox| checkbox.set(true) }
27
+ select2 'Shipping Matrix Calculator', from: 'Calculator'
28
+ click_button 'Create'
29
+ end
30
+
31
+ def then_the_num_of_shipping_methods_should_be(expected_num)
32
+ expect(page).to have_content('has been successfully created!')
33
+ expect(Spree::ShippingMethod.count).to be(expected_num)
34
+ end
@@ -0,0 +1,92 @@
1
+ feature 'Shipping Matrix in checkout flow' do
2
+ before(:each) do
3
+ given_there_are_many_spree_roles
4
+ and_there_are_payment_methods_and_zones
5
+ and_there_is_1_shipping_matrix_with_num_of_rules(1)
6
+ and_there_is_1_shipping_method_with_matrix_calculator
7
+ end
8
+
9
+ [['entry', 26, '2.99'],
10
+ ['entry', 52, '0.00'],
11
+ ['vip', 26, '2.99'],
12
+ ['vip', 52, '0.00'],
13
+ ['ultra_vip', 26, '0.00'],
14
+ ['ultra_vip', 52, '0.00'],
15
+ ['press', 26, '0.00'],
16
+ ['press', 52, '0.00']].each do |role, order_value, price|
17
+ scenario "Delivery price as #{role}" do
18
+ given_i_am_logged_in_as_user_with(role)
19
+ when_i_have_reached_the_delivery_stage_of_checkout
20
+ and_my_basket_value_is(order_value)
21
+ then_i_should_see_the_delivery_price_of(price)
22
+ end
23
+
24
+ scenario "Cheapest shipping method for #{role}" do
25
+ given_i_am_logged_in_as_user_with(role)
26
+ when_there_is_more_than_one_shipping_method
27
+ and_my_basket_value_is(order_value)
28
+ then_i_should_see_the_cheapest_delivery_price_of(price)
29
+ end
30
+ end
31
+
32
+ scenario "Free shipping method always wins" do
33
+ given_i_am_logged_in
34
+ when_there_is_a_free_delivery_method
35
+ then_the_delivery_should_be_free
36
+ end
37
+ end
38
+
39
+ def given_there_are_many_spree_roles
40
+ [:entry, :vip, :ultra_vip, :press].each do |role|
41
+ create(:role, name: role)
42
+ end
43
+ end
44
+
45
+ def and_there_are_payment_methods_and_zones
46
+ FactoryGirl.create(:check_payment_method)
47
+ country = FactoryGirl.create(:country)
48
+ Spree::Zone.global.members << Spree::ZoneMember.create(:zoneable => country)
49
+ country.states << FactoryGirl.create(:state, :country => country)
50
+ end
51
+
52
+ def and_there_is_1_shipping_matrix_with_num_of_rules(num_of_rules)
53
+ @matrix = create(:shipping_matrix_with_rules, num_of_rules: num_of_rules)
54
+ end
55
+
56
+ def and_there_is_1_shipping_method_with_matrix_calculator
57
+ calc = Spree::ShippingMatrixCalculator.new(preferred_matrix_id: @matrix.id)
58
+ create(:shipping_method, calculator: calc)
59
+ end
60
+
61
+ def when_i_have_reached_the_delivery_stage_of_checkout
62
+ order = OrderWalkthrough.up_to('delivery')
63
+ order.update(user_id: @user.id)
64
+ Spree::CheckoutController.any_instance.stub(:current_order => order)
65
+ end
66
+
67
+ def and_my_basket_value_is(value)
68
+ Spree::LineItem.first.update(price: value)
69
+ end
70
+
71
+ def when_there_is_more_than_one_shipping_method
72
+ create(:shipping_method)
73
+ when_i_have_reached_the_delivery_stage_of_checkout
74
+ end
75
+
76
+ def when_there_is_a_free_delivery_method
77
+ create(:free_shipping_method)
78
+ when_i_have_reached_the_delivery_stage_of_checkout
79
+ end
80
+
81
+ def then_i_should_see_the_delivery_price_of(expected_delivery)
82
+ visit spree.checkout_state_path(:delivery)
83
+ expect(page).to have_content(expected_delivery)
84
+ end
85
+
86
+ def then_i_should_see_the_cheapest_delivery_price_of(expected_delivery)
87
+ then_i_should_see_the_delivery_price_of(expected_delivery)
88
+ end
89
+
90
+ def then_the_delivery_should_be_free
91
+ then_i_should_see_the_delivery_price_of('0.00')
92
+ end
@@ -0,0 +1,86 @@
1
+ feature 'Shipping Matrix' do
2
+ before(:each) do
3
+ given_i_am_logged_into_the_cms
4
+ end
5
+
6
+ scenario 'creating shipping matrix' do
7
+ when_i_create_a_new_shipping_matrix
8
+ then_the_num_of_matrices_should_be(1)
9
+ and_the_num_of_rules_should_be(1)
10
+ end
11
+
12
+ scenario 'editing shipping matrix' do
13
+ given_i_have_a_shipping_matrix_with(num_of_rules: 1)
14
+ when_i_edit_a_shipping_matrix
15
+ then_i_should_see_changes_to_the_shipping_matrix
16
+ end
17
+
18
+ scenario 'adding rule to shipping matrix', js: true do
19
+ given_i_have_a_shipping_matrix_with(num_of_rules: 1)
20
+ when_i_add_2_rules_to_the_shipping_matrix
21
+ then_the_num_of_rules_should_be(3)
22
+ end
23
+
24
+ scenario 'removing rule from shipping matrix', js: true do
25
+ given_i_have_a_shipping_matrix_with(num_of_rules: 2)
26
+ when_i_remove_1_rule
27
+ then_the_num_of_rules_should_be(1)
28
+ end
29
+ end
30
+
31
+ def given_i_have_a_shipping_matrix_with(with)
32
+ @matrix = create(:shipping_matrix_with_rules, with)
33
+ end
34
+
35
+ def when_i_create_a_new_shipping_matrix
36
+ visit spree.new_admin_shipping_matrix_path
37
+ fill_in :shipping_matrix_name, with: 'UK next day'
38
+ fill_in :shipping_matrix_rules_attributes_0_min_line_item_total, with: '40'
39
+ fill_in :shipping_matrix_rules_attributes_0_amount, with: '2'
40
+ click_button 'Create'
41
+ end
42
+
43
+ def when_i_edit_a_shipping_matrix
44
+ visit spree.edit_admin_shipping_matrix_path(@matrix)
45
+ fill_in :shipping_matrix_name, with: 'UK next day updated'
46
+ fill_in :shipping_matrix_rules_attributes_0_amount, with: '4'
47
+ click_button 'Update'
48
+ end
49
+
50
+ def when_i_add_2_rules_to_the_shipping_matrix
51
+ visit spree.edit_admin_shipping_matrix_path(@matrix)
52
+
53
+ fill_in :shipping_matrix_rules_attributes_1_min_line_item_total, with: '40'
54
+ fill_in :shipping_matrix_rules_attributes_1_amount, with: '4'
55
+
56
+ click_link 'Add rule'
57
+ fill_in :shipping_matrix_rules_attributes_2_min_line_item_total, with: '20'
58
+ fill_in :shipping_matrix_rules_attributes_2_amount, with: '8'
59
+
60
+ click_button 'Update'
61
+ end
62
+
63
+ def when_i_remove_1_rule
64
+ visit spree.edit_admin_shipping_matrix_path(@matrix)
65
+ click_link 'Remove'
66
+ click_button 'Update'
67
+ end
68
+
69
+ def then_the_num_of_matrices_should_be(expected_num)
70
+ expect(Spree::ShippingMatrix.count).to be(expected_num)
71
+ expect(page).to have_content('UK next day')
72
+ end
73
+
74
+ def then_the_num_of_rules_should_be(expected_num)
75
+ expect(Spree::ShippingMatrixRule.count).to be(expected_num)
76
+ end
77
+
78
+ def and_the_num_of_rules_should_be(expected_num)
79
+ then_the_num_of_rules_should_be(expected_num)
80
+ end
81
+
82
+ def then_i_should_see_changes_to_the_shipping_matrix
83
+ then_the_num_of_matrices_should_be(1)
84
+ and_the_num_of_rules_should_be(1)
85
+ expect(page).to have_content('UK next day updated')
86
+ end
@@ -0,0 +1,91 @@
1
+ require 'codeclimate-test-reporter'
2
+ CodeClimate::TestReporter.start
3
+
4
+ # Configure Rails Environment
5
+ ENV['RAILS_ENV'] = 'test'
6
+
7
+ require File.expand_path('../dummy/config/environment.rb', __FILE__)
8
+
9
+ require 'rspec/rails'
10
+ require 'database_cleaner'
11
+ require 'ffaker'
12
+ require 'capybara/poltergeist'
13
+ require 'factory_girl'
14
+
15
+ include(FactoryGirl)
16
+
17
+ # Requires supporting ruby files with custom matchers and macros, etc,
18
+ # in spec/support/ and its subdirectories.
19
+ Dir[File.join(File.dirname(__FILE__), 'support/**/*.rb')].each { |f| require f }
20
+
21
+ # Requires factories and other useful helpers defined in spree_core.
22
+ require 'spree/testing_support/authorization_helpers'
23
+ require 'spree/testing_support/capybara_ext'
24
+ require 'spree/testing_support/controller_requests'
25
+ require 'spree/testing_support/factories'
26
+ require 'spree/testing_support/url_helpers'
27
+ require 'spree/testing_support/order_walkthrough'
28
+
29
+ # Requires factories defined in lib/spree_shipping_matrix/factories.rb
30
+ Dir[File.join(File.dirname(__FILE__), 'factories/**/*_factory.rb')].each { |f| require f }
31
+
32
+ Capybara.default_selector = :css
33
+ Capybara.javascript_driver = :poltergeist
34
+ Capybara.register_driver :poltergeist do |app|
35
+ Capybara::Poltergeist::Driver.new(app, timeout: 45,
36
+ js_errors: false,
37
+ phantomjs_options: ['--load-images=no'])
38
+ end
39
+
40
+ RSpec.configure do |config|
41
+ config.include FactoryGirl::Syntax::Methods
42
+
43
+ # Infer an example group's spec type from the file location.
44
+ config.infer_spec_type_from_file_location!
45
+
46
+ # == URL Helpers
47
+ #
48
+ # Allows access to Spree's routes in specs:
49
+ #
50
+ # visit spree.admin_path
51
+ # current_path.should eql(spree.products_path)
52
+ config.include Spree::TestingSupport::UrlHelpers
53
+
54
+ # == Mock Framework
55
+ #
56
+ # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
57
+ #
58
+ # config.mock_with :mocha
59
+ # config.mock_with :flexmock
60
+ # config.mock_with :rr
61
+ config.mock_with :rspec
62
+ config.color = true
63
+
64
+ # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
65
+ config.fixture_path = "#{::Rails.root}/spec/fixtures"
66
+
67
+ # Capybara javascript drivers require transactional fixtures set to false, and we use DatabaseCleaner
68
+ # to cleanup after each test instead. Without transactional fixtures set to false the records created
69
+ # to setup a test will be unavailable to the browser, which runs under a separate server instance.
70
+ config.use_transactional_fixtures = false
71
+
72
+ # Ensure Suite is set to use transactions for speed.
73
+ config.before :suite do
74
+ DatabaseCleaner.strategy = :transaction
75
+ DatabaseCleaner.clean_with :truncation
76
+ end
77
+
78
+ # Before each spec check if it is a Javascript test and switch between using database transactions or not where necessary.
79
+ config.before :each do
80
+ DatabaseCleaner.strategy = RSpec.current_example.metadata[:js] ? :truncation : :transaction
81
+ DatabaseCleaner.start
82
+ end
83
+
84
+ # After each spec clean the database.
85
+ config.after :each do
86
+ DatabaseCleaner.clean
87
+ end
88
+
89
+ config.fail_fast = ENV['FAIL_FAST'] || false
90
+ config.order = "random"
91
+ end
@@ -0,0 +1,22 @@
1
+ def given_i_am_logged_into_the_cms
2
+ @user = FactoryGirl.create(:admin_user)
3
+ visit spree.admin_path
4
+ fill_in :spree_user_email, with: @user.email
5
+ fill_in :spree_user_password, with: @user.password
6
+ click_button 'Login'
7
+ @user
8
+ end
9
+
10
+ def given_i_am_logged_in
11
+ @user = FactoryGirl.create(:user)
12
+ visit spree.login_path
13
+ fill_in :spree_user_email, with: @user.email
14
+ fill_in :spree_user_password, with: @user.password
15
+ click_button 'Login'
16
+ @user
17
+ end
18
+
19
+ def given_i_am_logged_in_as_user_with(role)
20
+ given_i_am_logged_in
21
+ @user.spree_roles << Spree::Role.find_by(name: role)
22
+ end
@@ -0,0 +1,81 @@
1
+ describe Spree::ShippingMatrixCalculator do
2
+ let(:variant1) { build(:variant, price: 10) }
3
+ let(:variant2) { build(:variant, price: 20) }
4
+
5
+ let(:role) { create(:role) }
6
+ let(:user) { create(:user, spree_roles: [role]) }
7
+
8
+ let (:package) { build(:stock_package, variants_contents: { variant1 => 4, variant2 => 6 }) }
9
+
10
+ before(:each) do
11
+ package.contents.first.inventory_unit.order.update(user: user)
12
+ end
13
+
14
+ context '#compute' do
15
+ subject { described_class.new(preferred_matrix_id: matrix.id).compute(package).to_f }
16
+
17
+ context 'when matrix has no rules' do
18
+ let(:matrix) { create(:shipping_matrix) }
19
+ it { is_expected.to eq(0.0) }
20
+ end
21
+
22
+ context 'when matrix has rules' do
23
+ let(:matrix) { create(:shipping_matrix_with_rules, num_of_rules: 5) }
24
+
25
+ let(:highest_min_line_item_total) do
26
+ create(:shipping_matrix_rule, min_line_item_total: 100, role: role)
27
+ end
28
+
29
+ let(:rule_with_matching_role) { highest_min_line_item_total }
30
+
31
+ before(:each) { matrix.rules << highest_min_line_item_total }
32
+
33
+ context 'and a rule with highest matching min line item total has amount of 4.99' do
34
+ before(:each) { highest_min_line_item_total.update!(amount: 4.99) }
35
+ it { is_expected.to eq(highest_min_line_item_total.amount.to_f) }
36
+ end
37
+
38
+ context 'and two rules with the same highest min line item total match' do
39
+ let(:another_rule) { create(:shipping_matrix_rule, min_line_item_total: 100) }
40
+
41
+ before(:each) { matrix.rules << another_rule }
42
+
43
+ context 'but only one rule#role matches and has amount of 3.99' do
44
+ before(:each) do
45
+ rule_with_matching_role.update!(amount: 3.99)
46
+ another_rule.update!(amount: 4.99)
47
+ end
48
+
49
+ it { is_expected.to eq(rule_with_matching_role.amount.to_f) }
50
+ end
51
+
52
+ context 'and both roles match' do
53
+ let(:matching_roles) { [rule_with_matching_role, another_rule] }
54
+
55
+ before(:each) do
56
+ rule_with_matching_role.update!(amount: 4.99)
57
+ another_rule.update!(role: role, amount: 3.99)
58
+ end
59
+
60
+ it 'should equal #amount from first matching role' do
61
+ is_expected.to eq(matching_roles.first.amount.to_f)
62
+ end
63
+ end
64
+ end
65
+
66
+ context 'and the order is a guest checkout' do
67
+ before(:each) do
68
+ package.contents.first.inventory_unit.order.update(user: nil, email: 'e@e.com')
69
+ end
70
+
71
+ let(:first_entry_rule) do
72
+ create(:shipping_matrix_rule, matrix: matrix, role: create(:role, name: 'entry'))
73
+ end
74
+
75
+ it 'should equal first rule matching #min_line_item_total and #role name is "entry"' do
76
+ is_expected.to eq(first_entry_rule.amount.to_f)
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,35 @@
1
+ describe Spree::ShippingMatrixRule do
2
+ context 'when created' do
3
+ subject { described_class.create(attrs) }
4
+
5
+ let(:attrs) { { role: create(:role),
6
+ min_line_item_total: 50,
7
+ amount: 2.99,
8
+ matrix: create(:shipping_matrix) } }
9
+
10
+ context 'and all required parameters are provided' do
11
+ it { is_expected.to be_valid }
12
+ end
13
+
14
+ [:matrix, :role, :min_line_item_total, :amount].each do |field|
15
+ context "and a ##{field} is not provided" do
16
+ before(:each) { attrs.delete(field) }
17
+ it { is_expected.to be_invalid }
18
+ end
19
+ end
20
+
21
+ [:matrix, :role, :min_line_item_total, :amount].each do |field|
22
+ context "and a ##{field} is not provided" do
23
+ before(:each) { attrs.delete(field) }
24
+ it { is_expected.to be_invalid }
25
+ end
26
+ end
27
+
28
+ [:min_line_item_total, :amount].each do |field|
29
+ context "and text value provided for ##{field}" do
30
+ before(:each) { attrs.merge!(field => 'word') }
31
+ it { is_expected.to be_invalid }
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,39 @@
1
+ describe Spree::ShippingMatrix do
2
+ let(:attrs) { { name: 'UK next day' } }
3
+ subject { described_class.create(attrs) }
4
+
5
+ context 'when created' do
6
+ context 'and all required attributes provided' do
7
+ it { is_expected.to be_valid }
8
+ end
9
+
10
+ context 'and no name provided' do
11
+ before(:each) { attrs.delete(:name) }
12
+ it { is_expected.to be_invalid }
13
+ end
14
+ end
15
+
16
+ context '#rules scope sorting' do
17
+ let(:matrix) { described_class.create(attrs) }
18
+
19
+ subject { matrix.rules }
20
+
21
+ let(:rule_with_lowest_min_line_item_total) do
22
+ create(:shipping_matrix_rule, matrix: matrix,
23
+ min_line_item_total: 50)
24
+ end
25
+
26
+ let(:rule_with_highest_min_line_item_total) do
27
+ create(:shipping_matrix_rule, matrix: matrix,
28
+ min_line_item_total: 100)
29
+ end
30
+
31
+ before(:each) do
32
+ rule_with_lowest_min_line_item_total
33
+ rule_with_highest_min_line_item_total
34
+ end
35
+
36
+ it { is_expected.to start_with(rule_with_highest_min_line_item_total) }
37
+ it { is_expected.to end_with(rule_with_lowest_min_line_item_total) }
38
+ end
39
+ end
@@ -0,0 +1,42 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'spree_shipping_matrix/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'spree_shipping_matrix'
7
+ s.version = SpreeShippingMatrix::VERSION
8
+
9
+ s.summary = 'Advanced shipping calculator based on rules matrix for Spree'
10
+ s.description = ''
11
+
12
+ s.homepage = 'https://github.com/madebymade/spree_shipping_matrix'
13
+
14
+ s.authors = ['Luke Morton']
15
+ s.email = ['luke@madebymade.co.uk']
16
+
17
+ s.license = 'MIT'
18
+
19
+ s.files = `git ls-files`.split("\n")
20
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
21
+
22
+ s.require_path = 'lib'
23
+ s.requirements << 'none'
24
+
25
+ s.platform = Gem::Platform::RUBY
26
+
27
+ s.required_ruby_version = '>= 1.9.3'
28
+
29
+ s.add_dependency 'spree_core', '2.4.0.beta'
30
+
31
+ s.add_development_dependency 'capybara', '~> 2.1'
32
+ s.add_development_dependency 'coffee-rails'
33
+ s.add_development_dependency 'database_cleaner'
34
+ s.add_development_dependency 'factory_girl', '~> 4.4'
35
+ s.add_development_dependency 'ffaker'
36
+ s.add_development_dependency 'rspec-rails', '~> 2.13'
37
+ s.add_development_dependency 'sass-rails', '~> 4.0.2'
38
+ s.add_development_dependency 'poltergeist'
39
+ s.add_development_dependency 'sqlite3'
40
+ s.add_development_dependency 'tailor'
41
+ s.add_development_dependency 'codeclimate-test-reporter'
42
+ end