diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..4f3c2c0 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,8 @@ +Metrics/LineLength: + Max: 116 + +Style/Documentation: + Enabled: false + +Style/ModuleFunction: + EnforcedStyle: 'extend_self' diff --git a/Gemfile b/Gemfile index 26d6125..35292ff 100644 --- a/Gemfile +++ b/Gemfile @@ -2,12 +2,3 @@ source 'https://rubygems.org' # Specify your gem's dependencies in divisio.gemspec gemspec - -group :development, :test do - gem 'pry-plus' - gem 'mongoid' -end - -group :test do - gem 'rspec' -end diff --git a/README.md b/README.md index 387dae5..ae7c794 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ Divisio.new.split(experiment_name, variants, identity) # ==>> 1 ### Mongoid adaper -_Requires mongoid v4.0.0 or greater_ +_Requires mongoid v5.0.0 or greater_ This adapter will persist the experiment name, identifier, and variant information in a MongoDb collection called `experiments`. Note: The variant returned will be cast to a string. diff --git a/divisio.gemspec b/divisio.gemspec index 52bc1eb..34f945b 100644 --- a/divisio.gemspec +++ b/divisio.gemspec @@ -8,8 +8,8 @@ Gem::Specification.new do |spec| spec.version = Divisio::VERSION spec.authors = ['Dragos Miron'] spec.email = ['tech@simplybusiness.co.uk'] - spec.summary = %q{Provides a splitting framework similar to AB testing} - spec.description = %q{Provides a splitting framework similar to AB testing} + spec.summary = 'Provides a splitting framework similar to AB testing' + spec.description = 'Provides a splitting framework similar to AB testing' spec.homepage = 'http://www.simplybusiness.co.uk' spec.license = 'MIT' @@ -17,4 +17,8 @@ Gem::Specification.new do |spec| spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) spec.require_paths = ['lib'] + + spec.add_development_dependency 'mongoid', '~> 6.0' + spec.add_development_dependency 'rspec', '~> 3.5' + spec.add_development_dependency 'rubocop', '~> 0.46' end diff --git a/lib/divisio.rb b/lib/divisio.rb index 9679976..8b02b92 100644 --- a/lib/divisio.rb +++ b/lib/divisio.rb @@ -4,7 +4,6 @@ require 'divisio/mongoid_adapter' if defined? Mongoid class Divisio - @default_adapter = Divisio::NoPersistenceAdapter class << self attr_accessor :default_adapter diff --git a/lib/divisio/base_adapter.rb b/lib/divisio/base_adapter.rb index b44fcdd..2169161 100644 --- a/lib/divisio/base_adapter.rb +++ b/lib/divisio/base_adapter.rb @@ -3,10 +3,10 @@ module BaseAdapter extend self def split(experiment_name, variants, identity) - ModuloAlgorithm.new(experiment_name.to_s+identity.to_s, variants).calc + ModuloAlgorithm.new(experiment_name.to_s + identity.to_s, variants).calc end - def delete_experiment_for_identity(identity, experiment_name) + def delete_experiment_for_identity(_identity, _experiment_name) raise NotImplementedError end end diff --git a/lib/divisio/modulo_algorithm.rb b/lib/divisio/modulo_algorithm.rb index 3d95cf5..417b508 100644 --- a/lib/divisio/modulo_algorithm.rb +++ b/lib/divisio/modulo_algorithm.rb @@ -1,6 +1,5 @@ class Divisio class ModuloAlgorithm - attr_reader :key, :variants private :key, :variants diff --git a/lib/divisio/mongoid_adapter.rb b/lib/divisio/mongoid_adapter.rb index 999db4b..0c5b954 100644 --- a/lib/divisio/mongoid_adapter.rb +++ b/lib/divisio/mongoid_adapter.rb @@ -23,7 +23,7 @@ def delete_experiment_for_identity(identity, experiment_name) experiment_object = Experiment.where(identifier: identity, name: experiment_name).first return experiment_object.destroy if experiment_object - return false + false end end end diff --git a/lib/divisio/mongoid_adapter/experiment.rb b/lib/divisio/mongoid_adapter/experiment.rb index b9fccee..0f23537 100644 --- a/lib/divisio/mongoid_adapter/experiment.rb +++ b/lib/divisio/mongoid_adapter/experiment.rb @@ -1,7 +1,6 @@ class Divisio module MongoidAdapter class Experiment - include Mongoid::Document include Mongoid::Timestamps @@ -12,8 +11,7 @@ class Experiment field :identifier, type: String field :variant, type: String - index({ name: 1, identifier: 1}, { unique: true}) - + index({ name: 1, identifier: 1 }, unique: true) end end end diff --git a/lib/divisio/version.rb b/lib/divisio/version.rb index 0742630..134ff08 100644 --- a/lib/divisio/version.rb +++ b/lib/divisio/version.rb @@ -1,3 +1,3 @@ class Divisio - VERSION = '0.1.0' + VERSION = '0.2.0'.freeze end diff --git a/mongoid.yml b/mongoid.yml index d17aca0..07f6fa3 100644 --- a/mongoid.yml +++ b/mongoid.yml @@ -1,8 +1,6 @@ test: - sessions: + clients: default: database: divisio_test hosts: - localhost:27017 - options: - <%= "safe: true" if Mongoid::VERSION =~ /^3/%> diff --git a/spec/divisio/base_adapter_spec.rb b/spec/divisio/base_adapter_spec.rb index 36152e5..602b8c3 100644 --- a/spec/divisio/base_adapter_spec.rb +++ b/spec/divisio/base_adapter_spec.rb @@ -1,4 +1,3 @@ describe Divisio::BaseAdapter do - it_behaves_like 'a base adapter' end diff --git a/spec/divisio/modulo_algorithm_spec.rb b/spec/divisio/modulo_algorithm_spec.rb index ff07cb8..82b8b2d 100644 --- a/spec/divisio/modulo_algorithm_spec.rb +++ b/spec/divisio/modulo_algorithm_spec.rb @@ -1,6 +1,6 @@ describe Divisio::ModuloAlgorithm do describe '#calc' do - let(:variants) { } + let(:variants) {} context 'when there is one variant provided' do let(:variants) { 1 } @@ -11,9 +11,9 @@ end context 'when there are multiple variants provided' do - let(:variants) { ['1', '2', '3'] } + let(:variants) { %w(1 2 3) } - { blah8: '1', blah4: '2', blah0: '3'}.each_pair do |key, expected_variant| + { blah8: '1', blah4: '2', blah0: '3' }.each_pair do |key, expected_variant| it "returns the variant based on the key provided: #{key}" do expect(Divisio::ModuloAlgorithm.new(key, variants).calc).to eq(expected_variant) end @@ -23,7 +23,7 @@ context 'when there are multiple weighted variants provided' do let(:variants) { { a: 1, b: 2, c: 3 } } - { blah8: :a, blah4: :b, blah0: :c}.each_pair do |key, expected_variant| + { blah8: :a, blah4: :b, blah0: :c }.each_pair do |key, expected_variant| it "returns the variant based on the key provided and weight: #{key}" do expect(Divisio::ModuloAlgorithm.new(key, variants).calc).to eq(expected_variant) end diff --git a/spec/divisio/mongoid_adapter/experiment_spec.rb b/spec/divisio/mongoid_adapter/experiment_spec.rb index e793682..4db07e4 100644 --- a/spec/divisio/mongoid_adapter/experiment_spec.rb +++ b/spec/divisio/mongoid_adapter/experiment_spec.rb @@ -1,36 +1,34 @@ describe Divisio::MongoidAdapter::Experiment do describe '#save' do - - let(:required_fields) { {:name => 'experiment', :identifier => 'hash', :variant => '2'} } + let(:required_fields) { { name: 'experiment', identifier: 'hash', variant: '2' } } subject { Divisio::MongoidAdapter::Experiment.new } context 'all fields are present' do it 'gets saved to the database' do subject.attributes = required_fields - expect{ subject.save }.to change{ described_class.count }.from(0).to(1) + expect { subject.save }.to change { described_class.count }.from(0).to(1) end end context 'missing fields' do it 'does not get saved if identifier is missing' do - subject.attributes = required_fields.tap{ |h| h.delete(:identifier) } + subject.attributes = required_fields.tap { |h| h.delete(:identifier) } expect(subject.save).to be_falsey end it 'does not get saved if name is missing' do - subject.attributes = required_fields.tap{ |h| h.delete(:name) } + subject.attributes = required_fields.tap { |h| h.delete(:name) } expect(subject.save).to be_falsey end it 'does not get saved if variant is missing' do - subject.attributes = required_fields.tap{ |h| h.delete(:variant) } + subject.attributes = required_fields.tap { |h| h.delete(:variant) } expect(subject.save).to be_falsey end end context 'uniqueness' do - it 'does not save second object with the same name and identifier' do subject.attributes = required_fields subject.save @@ -39,16 +37,16 @@ required_fields[:variant] = '3' new_object = described_class.new(required_fields) - expect{ new_object.save }.to_not change(described_class, :count) + expect { new_object.save }.to_not change(described_class, :count) end it 'does not save second object in case of race condition because of mongo index' do described_class.create_indexes - Mongoid.default_session[:divisio_mongoid_adapter_experiments].insert(required_fields) + Mongoid::Clients.default[:divisio_mongoid_adapter_experiments].insert_one(required_fields) expect(described_class.count).to eq(1) collection = described_class.collection - expect{collection.insert(required_fields)}.to raise_exception(Moped::Errors::OperationFailure) + expect { collection.insert_one(required_fields) }.to raise_exception(Mongo::Error::OperationFailure) end end end diff --git a/spec/divisio/mongoid_adapter_spec.rb b/spec/divisio/mongoid_adapter_spec.rb index 148240e..be7d0ac 100644 --- a/spec/divisio/mongoid_adapter_spec.rb +++ b/spec/divisio/mongoid_adapter_spec.rb @@ -4,12 +4,11 @@ let(:identity) { 'identity' } describe '::split' do - subject{ described_class.split(experiment, variants, identity) } + subject { described_class.split(experiment, variants, identity) } it_behaves_like 'a base adapter' context 'new record' do - it 'saves the experiment to the database' do expect_any_instance_of(Divisio::MongoidAdapter::Experiment).to receive(:save) subject @@ -21,7 +20,6 @@ end context 'old record' do - before do Divisio::MongoidAdapter::Experiment.create(name: experiment, identifier: identity, variant: 'random') end @@ -38,7 +36,7 @@ end describe '::delete_experiment_for_identity' do - subject{ described_class.delete_experiment_for_identity(identity, experiment) } + subject { described_class.delete_experiment_for_identity(identity, experiment) } context 'record exists in the database' do before do @@ -46,7 +44,7 @@ end it 'deletes the record' do - expect{subject}.to change { Divisio::MongoidAdapter::Experiment.count }.from(1).to(0) + expect { subject }.to change { Divisio::MongoidAdapter::Experiment.count }.from(1).to(0) end it 'returns true' do diff --git a/spec/divisio/no_persistence_adapter_spec.rb b/spec/divisio/no_persistence_adapter_spec.rb index 66f1d0f..1c45aea 100644 --- a/spec/divisio/no_persistence_adapter_spec.rb +++ b/spec/divisio/no_persistence_adapter_spec.rb @@ -1,4 +1,3 @@ describe Divisio::NoPersistenceAdapter do - it_behaves_like 'a base adapter' end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 1b92253..66ec413 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,6 +1,6 @@ ENV['RACK_ENV'] = 'test' -Dir['./spec/support/**/*.rb'].sort.each { |f| require f} +Dir['./spec/support/**/*.rb'].sort.each { |f| require f } require 'mongoid' require 'divisio' @@ -9,6 +9,6 @@ RSpec.configure do |config| config.before(:each) do - Mongoid::Sessions.default.collections.each(&:drop) + Mongoid.purge! end end diff --git a/spec/support/shared_examples_for_base_adapter.rb b/spec/support/shared_examples_for_base_adapter.rb index 79d9540..58e539b 100644 --- a/spec/support/shared_examples_for_base_adapter.rb +++ b/spec/support/shared_examples_for_base_adapter.rb @@ -1,10 +1,9 @@ shared_examples_for 'a base adapter' do - describe '::split' do let(:experiment) { 'experiment' } - let(:variants) { ['1', '2', '3'] } + let(:variants) { %w(1 2 3) } let(:identity) { 'identity' } - subject{ described_class.split(experiment, variants, identity) } + subject { described_class.split(experiment, variants, identity) } it 'returns a variant for the given experiment and identity' do expect(subject).to eq('3')