Skip to content
This repository has been archived by the owner on Feb 2, 2022. It is now read-only.

Commit

Permalink
Merge pull request #7 from simplybusiness/keep_it_fresh
Browse files Browse the repository at this point in the history
Keep it fresh
  • Loading branch information
Joshua Fleck authored Jan 4, 2017
2 parents 5333fda + f2c864c commit cd1a947
Show file tree
Hide file tree
Showing 18 changed files with 40 additions and 50 deletions.
8 changes: 8 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Metrics/LineLength:
Max: 116

Style/Documentation:
Enabled: false

Style/ModuleFunction:
EnforcedStyle: 'extend_self'
9 changes: 0 additions & 9 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
8 changes: 6 additions & 2 deletions divisio.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@ 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'

spec.files = `git ls-files -z`.split("\x0")
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
1 change: 0 additions & 1 deletion lib/divisio.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
require 'divisio/mongoid_adapter' if defined? Mongoid

class Divisio

@default_adapter = Divisio::NoPersistenceAdapter
class << self
attr_accessor :default_adapter
Expand Down
4 changes: 2 additions & 2 deletions lib/divisio/base_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 0 additions & 1 deletion lib/divisio/modulo_algorithm.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
class Divisio
class ModuloAlgorithm

attr_reader :key, :variants
private :key, :variants

Expand Down
2 changes: 1 addition & 1 deletion lib/divisio/mongoid_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 1 addition & 3 deletions lib/divisio/mongoid_adapter/experiment.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
class Divisio
module MongoidAdapter
class Experiment

include Mongoid::Document
include Mongoid::Timestamps

Expand All @@ -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
2 changes: 1 addition & 1 deletion lib/divisio/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
class Divisio
VERSION = '0.1.0'
VERSION = '0.2.0'.freeze
end
4 changes: 1 addition & 3 deletions mongoid.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
test:
sessions:
clients:
default:
database: divisio_test
hosts:
- localhost:27017
options:
<%= "safe: true" if Mongoid::VERSION =~ /^3/%>
1 change: 0 additions & 1 deletion spec/divisio/base_adapter_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
describe Divisio::BaseAdapter do

it_behaves_like 'a base adapter'
end
8 changes: 4 additions & 4 deletions spec/divisio/modulo_algorithm_spec.rb
Original file line number Diff line number Diff line change
@@ -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 }
Expand All @@ -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
Expand All @@ -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
Expand Down
18 changes: 8 additions & 10 deletions spec/divisio/mongoid_adapter/experiment_spec.rb
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand Down
8 changes: 3 additions & 5 deletions spec/divisio/mongoid_adapter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -21,7 +20,6 @@
end

context 'old record' do

before do
Divisio::MongoidAdapter::Experiment.create(name: experiment, identifier: identity, variant: 'random')
end
Expand All @@ -38,15 +36,15 @@
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
Divisio::MongoidAdapter::Experiment.create(name: experiment, identifier: identity, variant: 'random')
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
Expand Down
1 change: 0 additions & 1 deletion spec/divisio/no_persistence_adapter_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
describe Divisio::NoPersistenceAdapter do

it_behaves_like 'a base adapter'
end
4 changes: 2 additions & 2 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -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'
Expand All @@ -9,6 +9,6 @@

RSpec.configure do |config|
config.before(:each) do
Mongoid::Sessions.default.collections.each(&:drop)
Mongoid.purge!
end
end
5 changes: 2 additions & 3 deletions spec/support/shared_examples_for_base_adapter.rb
Original file line number Diff line number Diff line change
@@ -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')
Expand Down

0 comments on commit cd1a947

Please sign in to comment.