mongoid-casino 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/.gitignore +20 -0
  2. data/.ruby-gemset +1 -0
  3. data/.ruby-version +1 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +93 -0
  7. data/Rakefile +9 -0
  8. data/casino.gemspec +30 -0
  9. data/lib/casino.rb +13 -0
  10. data/lib/casino/collection.rb +195 -0
  11. data/lib/casino/dimension.rb +11 -0
  12. data/lib/casino/focus.rb +26 -0
  13. data/lib/casino/intersection.rb +30 -0
  14. data/lib/casino/intersection/match/all.rb +29 -0
  15. data/lib/casino/intersection/match/base.rb +49 -0
  16. data/lib/casino/intersection/match/equivalence.rb +25 -0
  17. data/lib/casino/intersection/match/expression.rb +15 -0
  18. data/lib/casino/intersection/match/greater.rb +43 -0
  19. data/lib/casino/intersection/match/include.rb +15 -0
  20. data/lib/casino/intersection/match/lesser.rb +31 -0
  21. data/lib/casino/intersection/match/recurse.rb +19 -0
  22. data/lib/casino/lobby.rb +21 -0
  23. data/lib/casino/projection.rb +76 -0
  24. data/lib/casino/query.rb +23 -0
  25. data/lib/casino/question.rb +9 -0
  26. data/lib/casino/store.rb +49 -0
  27. data/lib/casino/version.rb +3 -0
  28. data/spec/fabricators/model_fabricator.rb +12 -0
  29. data/spec/fabricators/note_fabricator.rb +3 -0
  30. data/spec/fixtures/collections/collection.rb +3 -0
  31. data/spec/fixtures/collections/emails_by_day.rb +28 -0
  32. data/spec/fixtures/models/model.rb +8 -0
  33. data/spec/fixtures/models/note.rb +7 -0
  34. data/spec/lib/casino/collection_spec.rb +146 -0
  35. data/spec/lib/casino/dimension_spec.rb +27 -0
  36. data/spec/lib/casino/focus_spec.rb +53 -0
  37. data/spec/lib/casino/intersection/match/all_spec.rb +24 -0
  38. data/spec/lib/casino/intersection/match/base_spec.rb +159 -0
  39. data/spec/lib/casino/intersection/match/equivalence_spec.rb +26 -0
  40. data/spec/lib/casino/intersection/match/expression_spec.rb +26 -0
  41. data/spec/lib/casino/intersection/match/greater_spec.rb +72 -0
  42. data/spec/lib/casino/intersection/match/include_spec.rb +27 -0
  43. data/spec/lib/casino/intersection/match/lesser_spec.rb +74 -0
  44. data/spec/lib/casino/intersection/match/recurse_spec.rb +24 -0
  45. data/spec/lib/casino/intersection_spec.rb +33 -0
  46. data/spec/lib/casino/lobby_spec.rb +20 -0
  47. data/spec/lib/casino/projection_spec.rb +81 -0
  48. data/spec/lib/casino/query_spec.rb +42 -0
  49. data/spec/lib/casino/question_spec.rb +10 -0
  50. data/spec/lib/casino/store_spec.rb +60 -0
  51. data/spec/spec_helper.rb +26 -0
  52. data/spec/support/mongoid.yml +6 -0
  53. metadata +234 -0
@@ -0,0 +1,26 @@
1
+ describe Casino::Intersection::Match::Equivalence do
2
+
3
+ let(:klass) { Casino::Intersection::Match::Equivalence }
4
+ let(:source) { "Facebook" }
5
+ let(:document) { Model.new(source: source) }
6
+ let(:criteria) { Model.where(source: source) }
7
+ let(:selector) { criteria.selector }
8
+ let(:key) { 'source' }
9
+ let(:field) { selector[key] }
10
+ let(:value) { document.send(key) }
11
+ let(:equivalence) { klass.new(key, field, document, source) }
12
+
13
+ describe '#evaluate' do
14
+ describe 'when values match' do
15
+ subject { equivalence.evaluate }
16
+ it { subject.must_equal true }
17
+ end
18
+
19
+ describe 'when values do not match' do
20
+ let(:inequivalence) { klass.new(key, field, document, "Google") }
21
+ subject { inequivalence.evaluate }
22
+ it { subject.must_equal false }
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,26 @@
1
+ describe Casino::Intersection::Match::Expression do
2
+
3
+ let(:klass) { Casino::Intersection::Match::Expression }
4
+ let(:source) { "Facebook" }
5
+ let(:document) { Model.new(source: source) }
6
+ let(:criteria) { Model.where(source: /facebook/i) }
7
+ let(:selector) { criteria.selector }
8
+ let(:key) { 'source' }
9
+ let(:field) { selector[key] }
10
+ let(:value) { document.send(key) }
11
+ let(:equivalence) { klass.new(key, field, document, source) }
12
+
13
+ describe '#evaluate' do
14
+ describe 'when values match' do
15
+ subject { equivalence.evaluate }
16
+ it { subject.must_equal true }
17
+ end
18
+
19
+ describe 'when values do not match' do
20
+ let(:inequivalence) { klass.new(key, field, document, "Google") }
21
+ subject { inequivalence.evaluate }
22
+ it { subject.must_equal false }
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,72 @@
1
+ describe Casino::Intersection::Match::Greater do
2
+
3
+ let(:system) { Casino::Intersection::Match::Greater }
4
+
5
+ describe 'greater than' do
6
+
7
+ describe '#eligible?' do
8
+ describe "when the key is $gt" do
9
+ let(:matcher) { system.new '$gt', '', '', '' }
10
+ subject { matcher.eligible? }
11
+ end
12
+ end
13
+
14
+ describe '#evaluate' do
15
+
16
+ describe 'when the value is greater than the field' do
17
+ it "returns true" do
18
+ matcher = system.new '$gt', Date.today, '', Date.yesterday
19
+ matcher.evaluate.must_equal true
20
+ end
21
+ end
22
+
23
+ describe 'when the value is less than the field' do
24
+ it "returns false" do
25
+ matcher = system.new '$gt', Date.yesterday, '', Date.today
26
+ matcher.evaluate.must_equal false
27
+ end
28
+ end
29
+
30
+ end
31
+
32
+ end
33
+
34
+ describe 'greater than or equal to' do
35
+
36
+ describe '#eligible?' do
37
+ describe "when the key is $gt" do
38
+ it "returns true" do
39
+ matcher = system.new '$gte', '', '', ''
40
+ matcher.eligible?.must_equal true
41
+ end
42
+ end
43
+ end
44
+
45
+ describe '#evaluate' do
46
+
47
+ describe 'when the value is greater than the field' do
48
+ it "returns true" do
49
+ matcher = system.new '$gte', Date.today, '', Date.yesterday
50
+ matcher.evaluate.must_equal true
51
+ end
52
+ end
53
+
54
+ describe 'when the value is equal to the field' do
55
+ it "returns true" do
56
+ matcher = system.new '$gte', Date.yesterday, '', Date.yesterday
57
+ matcher.evaluate.must_equal true
58
+ end
59
+ end
60
+
61
+ describe 'when the value is less than the field' do
62
+ it "returns false" do
63
+ matcher = system.new '$gte', Date.yesterday, '', Date.today
64
+ matcher.evaluate.must_equal false
65
+ end
66
+ end
67
+
68
+ end
69
+
70
+ end
71
+
72
+ end
@@ -0,0 +1,27 @@
1
+ describe Casino::Intersection::Match::Include do
2
+
3
+ let(:system) { Casino::Intersection::Match::Include }
4
+
5
+ describe '#eligible?' do
6
+ describe 'when the key is $in' do
7
+ let(:matcher) { system.new('$in', '', '', '') }
8
+ subject { matcher.eligible? }
9
+ it { subject.must_equal true }
10
+ end
11
+ end
12
+
13
+ describe '#evaluate' do
14
+ describe 'when the value is within the field' do
15
+ let(:matcher) { system.new('$in', 1, '', [1, 2, 3, 4]) }
16
+ subject { matcher.evaluate }
17
+ it { subject.must_equal true }
18
+ end
19
+
20
+ describe 'when the value is not within the field' do
21
+ let(:matcher) { system.new('$in', 1, '', [2, 3, 4]) }
22
+ subject { matcher.evaluate }
23
+ it { subject.must_equal false }
24
+ end
25
+ end
26
+
27
+ end
@@ -0,0 +1,74 @@
1
+ describe Casino::Intersection::Match::Lesser do
2
+
3
+ let(:system) { Casino::Intersection::Match::Lesser }
4
+
5
+ describe 'lesser than' do
6
+
7
+ describe '#eligible?' do
8
+ describe "when the key is $lt" do
9
+ it "returns true" do
10
+ matcher = system.new '$lt', '', '', ''
11
+ matcher.eligible?.must_equal true
12
+ end
13
+ end
14
+ end
15
+
16
+ describe '#evaluate' do
17
+
18
+ describe 'when the value is less than the field' do
19
+ it "returns true" do
20
+ matcher = system.new '$lt', Date.yesterday, '', Date.today
21
+ matcher.evaluate.must_equal true
22
+ end
23
+ end
24
+
25
+ describe 'when the value is greater than the field' do
26
+ it "returns false" do
27
+ matcher = system.new '$lt', Date.today, '', Date.yesterday
28
+ matcher.evaluate.must_equal false
29
+ end
30
+ end
31
+
32
+ end
33
+
34
+ end
35
+
36
+ describe 'lesser than or equal to' do
37
+
38
+ describe '#eligible?' do
39
+ describe "when the key is $lte" do
40
+ it "returns true" do
41
+ matcher = system.new '$lte', '', '', ''
42
+ matcher.eligible?.must_equal true
43
+ end
44
+ end
45
+ end
46
+
47
+ describe '#evaluate' do
48
+
49
+ describe 'when the value is less than the field' do
50
+ it "returns true" do
51
+ matcher = system.new '$lte', Date.yesterday, '', Date.today
52
+ matcher.evaluate.must_equal true
53
+ end
54
+ end
55
+
56
+ describe 'when the value is equal to the field' do
57
+ it "returns true" do
58
+ matcher = system.new '$lte', Date.today, '', Date.today
59
+ matcher.evaluate.must_equal true
60
+ end
61
+ end
62
+
63
+ describe 'when the value is greater than the field' do
64
+ it "returns false" do
65
+ matcher = system.new '$lte', Date.today, '', Date.yesterday
66
+ matcher.evaluate.must_equal false
67
+ end
68
+ end
69
+
70
+ end
71
+
72
+ end
73
+
74
+ end
@@ -0,0 +1,24 @@
1
+ describe Casino::Intersection::Match::Recurse do
2
+
3
+ let(:system) { Casino::Intersection::Match::Recurse }
4
+
5
+ describe '#eligible?' do
6
+ let(:matcher) { system.new('', '', '', {}) }
7
+ subject { matcher.eligible? }
8
+ it { subject.must_equal true }
9
+ end
10
+
11
+ describe '#evaluate' do
12
+
13
+ let(:matcher) { system.new('', '', '', { '$gt' => 4 }) }
14
+ let(:base) { Casino::Intersection::Match::Base }
15
+ subject { matcher.evaluate }
16
+ it 'builds base matchers to evaluate' do
17
+ base.stub(:new, OpenStruct.new(evaluate: true)) do
18
+ subject.must_equal true
19
+ end
20
+ end
21
+
22
+ end
23
+
24
+ end
@@ -0,0 +1,33 @@
1
+ describe Casino::Intersection do
2
+
3
+ let(:label) { [ Date.today.strftime("%m/%d/%Y"), "Facebook" ] }
4
+ let(:criteria) { Model.scoped }
5
+ let(:intersection) { Casino::Intersection.new(label, criteria) }
6
+
7
+ subject { intersection }
8
+
9
+ it { subject.label.must_equal label }
10
+ it { subject.criteria.must_equal criteria }
11
+ it { subject.must_respond_to :selector }
12
+
13
+ describe '#match?' do
14
+
15
+ let(:model) { Model.new }
16
+ let(:criteria) { Model.where(created_at: Date.today) }
17
+ let(:intersection) { Casino::Intersection.new(label, criteria) }
18
+ let(:value) { model.created_at }
19
+ let(:base_class) { Casino::Intersection::Match::Base }
20
+ let(:base_mock) { MiniTest::Mock.new }
21
+ let(:base_instance) { base_class.new(*base_arguments) }
22
+ let(:base_arguments) { [model, 'created_at', intersection.selector, value] }
23
+
24
+ it "invokes a Casino::Intersection::Match::Base instance" do
25
+ base_mock.expect(:evaluate, base_instance)
26
+ base_class.stub(:new, base_mock) do
27
+ intersection.match?(model)
28
+ end
29
+ base_mock.verify
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe Casino::Lobby do
4
+
5
+ let(:collection) { Collection }
6
+ let(:object_class) { Model }
7
+ let(:object_instance) { object_class.new }
8
+ let(:object_key) { object_class.name.downcase.split("::").last.to_sym }
9
+ let(:lobby) { Casino::Lobby.new(collection) }
10
+
11
+ subject { lobby }
12
+
13
+ it { subject.collection.must_equal collection }
14
+
15
+ it "stores objects instances in a registry" do
16
+ subject.add_registry(object_instance)
17
+ subject.registry[object_key].must_include object_instance
18
+ end
19
+
20
+ end
@@ -0,0 +1,81 @@
1
+ describe Casino::Projection do
2
+
3
+ let(:projection) { Casino::Projection.new(Model) }
4
+
5
+ describe '#results' do
6
+ it "sends the pipeline to the collection's aggregate method" do
7
+ Model.collection.stub(:aggregate, []) do
8
+ projection.results.must_equal []
9
+ end
10
+ end
11
+ end
12
+
13
+ describe '#mongoize' do
14
+ let(:hash) do
15
+ { group: { '_id' => :email, 'count' => { sum: 1 } } }
16
+ end
17
+ let(:mongoized_hash) do
18
+ { '$group' => { '_id' => '$email', 'count' => { '$sum' => 1 } } }
19
+ end
20
+ subject { projection.mongoize(hash) }
21
+ it { subject.must_equal mongoized_hash }
22
+ end
23
+
24
+ describe '#group' do
25
+ let(:group_hash) do
26
+ { '$group' => { '_id' => '$author' } }
27
+ end
28
+ subject { projection.group('_id' => :author) }
29
+ it { subject.pipeline.must_include group_hash }
30
+ end
31
+
32
+ describe '#project' do
33
+ let(:project_hash) do
34
+ { '$project' => { 'person' => '$human' } }
35
+ end
36
+ subject { projection.project('person' => :human) }
37
+ it { subject.pipeline.must_include project_hash }
38
+ end
39
+
40
+ describe '#unwind' do
41
+ let(:unwind_hash) do
42
+ { '$unwind' => '$notes' }
43
+ end
44
+ subject { projection.unwind(:notes) }
45
+ it { subject.pipeline.must_include unwind_hash }
46
+ end
47
+
48
+ describe '#match' do
49
+ let(:today) { Date.today }
50
+ let(:match_hash) do
51
+ { '$match' => { '$created_at' => { '$gte' => today } } }
52
+ end
53
+ subject { projection.match(created_at: { gte: today }) }
54
+ it { subject.pipeline.must_include match_hash }
55
+ end
56
+
57
+ describe '#sort' do
58
+ let(:sort_hash) do
59
+ { '$sort' => { 'count' => -1 } }
60
+ end
61
+ subject { projection.sort('count' => -1) }
62
+ it { subject.pipeline.must_include sort_hash }
63
+ end
64
+
65
+ describe '#skip' do
66
+ let(:skip_hash) do
67
+ { '$skip' => 10 }
68
+ end
69
+ subject { projection.skip(10) }
70
+ it { subject.pipeline.must_include skip_hash }
71
+ end
72
+
73
+ describe '#limit' do
74
+ let(:limit_hash) do
75
+ { '$limit' => 10 }
76
+ end
77
+ subject { projection.limit(10) }
78
+ it { subject.pipeline.must_include limit_hash }
79
+ end
80
+
81
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ describe Casino::Query do
4
+
5
+ let(:label) { "women's boots" }
6
+ let(:criteria) { [ /page_gender=f/i, /offer_cohort=boots/i ] }
7
+ let(:query) { Casino::Query.new(label, [], *criteria) }
8
+
9
+ subject { query }
10
+
11
+ it { subject.label.must_equal label }
12
+ it { subject.criteria.must_equal criteria }
13
+ it { subject.conditions.must_equal [] }
14
+
15
+ describe '#merge' do
16
+
17
+ let(:field) { :created_at }
18
+ let(:queries) { :method_name }
19
+ let(:and_approach) { { operator: :and } }
20
+
21
+ let(:dimension) do
22
+ Casino::Dimension.new("Date", field, queries, and_approach)
23
+ end
24
+
25
+ let(:conditions) do
26
+ query.criteria.map do |condition|
27
+ [ :and, { dimension.field => condition } ]
28
+ end
29
+ end
30
+
31
+ subject { query.merge(dimension) }
32
+
33
+ it "merges the dimension data in" do
34
+ subject.conditions.must_equal conditions
35
+ end
36
+
37
+ it "produces a different object" do
38
+ subject.wont_equal query
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ describe Casino::Question do
4
+ let(:name) { :emails }
5
+ let(:answer) { :distinct_emails }
6
+ let(:question) { Casino::Question.new(name, answer) }
7
+ subject { question }
8
+ it { subject.name.must_equal name }
9
+ it { subject.answer.must_equal answer }
10
+ end