vignette 0.0.10 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f6e339a4120f9d2aa60652c739eefe130f89bbf1
4
- data.tar.gz: cc3e420a4134dec09e1fe1ce5c91c2b3a5d12d27
3
+ metadata.gz: 196be79b8ba920292a1e9322f8ab84f4ddfa1fd1
4
+ data.tar.gz: c7ec87488bf8c8f5cb57dc192e2c011402d3540f
5
5
  SHA512:
6
- metadata.gz: 7daa2a02433d64a36e53cb0096f071c3d5b232c545af82ece0319390c4956dce75af82367261725050da19939e53fc8c528ec69d731fe81edb367c00b52cfa4d
7
- data.tar.gz: 6c1d9144b845a1807d2e42ecfa3785a710d2cd3c3e582988f970599ad72e26fa754f6aa7e69de71bf064a3e985cc5b9ad68d79daa191a2405fbfec3cf3dbc625
6
+ metadata.gz: e281220e3815bae46954f16b5d0126d1ea601771e51ac69a426449c6351af93b0ff64916636d8f5f092027a462a46a5639e8391cbe9801b4b609f1b0dbaf3300
7
+ data.tar.gz: 9b2d4e372dc309a4e7509d49eeaaa0d43d4ee9c7df82ecaaf729dc1bc31b93bc62bcfef21318baaa3a0989f5d4f7d1f9394549bd023713bb3ac7716078d0b8a2
@@ -16,9 +16,9 @@ if defined?(Haml)
16
16
  # Otherwise, try to use filename and line
17
17
  elsif options[:filename] && options[:line]
18
18
  if options[:filename] == "(haml)"
19
- lines.vignette("(haml:#{options[:line]})")
19
+ lines.vignette("(haml:#{options[:line]})", expect_consistent_name: false)
20
20
  else
21
- lines.vignette("(#{Vignette::strip_path(options[:filename])}:#{options[:line]})")
21
+ lines.vignette("(#{Vignette::strip_path(options[:filename])}:#{options[:line]})", expect_consistent_name: false)
22
22
  end
23
23
  # If not given, raise an error
24
24
  else
@@ -1,5 +1,11 @@
1
1
  module ObjectExtensions
2
2
 
3
+ module Merge
4
+ def merge(store, key, hash)
5
+
6
+ end
7
+ end
8
+
3
9
  # Extensions to the Array object
4
10
  module ArrayExtensions
5
11
 
@@ -8,32 +14,36 @@ module ObjectExtensions
8
14
  end
9
15
 
10
16
  # Test will select a random object from the Array
11
- def vignette(name=nil)
17
+ def vignette(name=nil, expect_consistent_name: true)
12
18
  vignette_crc = self.crc().abs.to_s(16)
13
19
 
14
20
  key = "vignette_#{vignette_crc}"
15
21
  test_name = nil
16
22
 
17
23
  store = Vignette.get_store
24
+ v = store[:v] ? JSON(store[:v]) : {}
18
25
 
19
- test_name = if name.present?
26
+ test_name = if expect_consistent_name && name.present?
27
+ name
28
+ elsif test_hash = v[vignette_crc]
29
+ test_hash['name']
30
+ elsif name.present? # this logic looks weird, but this is if we don't expect consistent names *and* we don't have a name in v[]
20
31
  name
21
- elsif store[:vt] && original_name = JSON(store[:vt])[vignette_crc]
22
- original_name
23
32
  else
24
33
  loc = caller_locations(1,1).first
25
- new_name = "(#{Vignette::strip_path(loc.absolute_path)}:#{loc.lineno})"
26
-
27
- store[:vt] = ( store[:vt].present? ? JSON(store[:vt]) : {} ).merge(vignette_crc => new_name).to_json
28
-
29
- new_name
34
+ "(#{Vignette::strip_path(loc.absolute_path)}:#{loc.lineno})"
30
35
  end
31
36
 
32
- choice = store[key] ||= Kernel.rand(length) # Store key into storage if not available
33
- result = self[choice.to_i]
37
+ result = if v.has_key?(vignette_crc)
38
+ v[vignette_crc]['v']
39
+ else
40
+ # Store key into storage if not available
41
+ new_value = self[Kernel.rand(length)]
34
42
 
35
- # Let's store keys where they are (note, this truncates any other tests with the same name)
36
- store[:v] = ( store[:v].present? ? JSON(store[:v]) : {} ).merge(test_name => result).to_json
43
+ store[:v] = v.merge(vignette_crc => { n: test_name, v: new_value, t: Time.now.to_i }).to_json
44
+
45
+ new_value
46
+ end
37
47
 
38
48
  return result
39
49
  end
@@ -1,3 +1,3 @@
1
1
  module Vignette
2
- VERSION = "0.0.10"
2
+ VERSION = "0.0.11"
3
3
  end
data/lib/vignette.rb CHANGED
@@ -63,6 +63,17 @@ module Vignette
63
63
  def self.tests(session=Vignette.session, cookies=Vignette.cookies)
64
64
  store = get_store(session, cookies)
65
65
  store && store[:v].present? ? JSON(store[:v]) : {}
66
+ if store && store[:v].present?
67
+ v = JSON(store[:v])
68
+
69
+ name_values = v.values.map { |v| [ v['n'], [ v['t'], v['v'] ] ] }.group_by { |el| el[0] }
70
+
71
+ arr = name_values.map { |k,v| [ k.to_sym, v.sort { |a,b| b[1][0] <=> a[1][0] }.first[1][1] ] }
72
+
73
+ Hash[arr]
74
+ else
75
+ {}
76
+ end
66
77
  end
67
78
 
68
79
  def self.get_store(session=Vignette.session, cookies=Vignette.cookies)
@@ -20,7 +20,7 @@ describe Haml::Filters::Vignette do
20
20
  html = Haml::Engine.new(template).render
21
21
 
22
22
  expect(html).to match(/\<p\>\s+three\s+\<\/p\>\n/)
23
- expect(Vignette.tests).to eq({"(haml:3)" => "three"})
23
+ expect(Vignette.tests).to eq({:"(haml:3)" => "three"})
24
24
  end
25
25
  end
26
26
  end
@@ -40,7 +40,7 @@ describe Haml::Filters::Vignette do
40
40
  html = Haml::Engine.new(template).render
41
41
 
42
42
  expect(html).to match(/\<p\>\s+three\s+\<\/p\>\n/)
43
- expect(Vignette.tests).to eq({"numbers" => "three"})
43
+ expect(Vignette.tests).to eq({:"numbers" => "three"})
44
44
  end
45
45
  end
46
46
  end
@@ -55,7 +55,7 @@ describe Haml::Filters::Vignette do
55
55
  html = Haml::Engine.new(template, filename: template_file).render
56
56
 
57
57
  expect(html).to match(/\<div\>\s+I like\s+scorpians\s+\<\/div\>/)
58
- expect(Vignette.tests).to eq({"(ex.html.haml:3)" => "scorpians"})
58
+ expect(Vignette.tests).to eq({:"(ex.html.haml:3)" => "scorpians"})
59
59
  end
60
60
  end
61
61
  end
@@ -18,32 +18,61 @@ describe Vignette do
18
18
 
19
19
  it 'should store tests in session' do
20
20
  expect(array.vignette).to eq('b'); line = __LINE__ # for tracking line number
21
- expect(Vignette.tests).to eq({"(vignette_spec.rb:#{line})" => 'b'})
21
+ expect(Vignette.tests).to eq({:"(vignette_spec.rb:#{line})" => 'b'})
22
22
  end
23
23
 
24
24
  it 'should store tests even if we call on different lines' do
25
25
  expect(array.vignette).to eq('b'); line = __LINE__
26
- expect(Vignette.tests).to eq({"(vignette_spec.rb:#{line})" => 'b'})
26
+ expect(Vignette.tests).to eq({:"(vignette_spec.rb:#{line})" => 'b'})
27
27
 
28
28
  expect(array.vignette).to eq('b'); new_line = __LINE__
29
- expect(Vignette.tests).to eq({"(vignette_spec.rb:#{line})" => 'b'})
29
+ expect(Vignette.tests).to eq({:"(vignette_spec.rb:#{line})" => 'b'})
30
30
  end
31
31
  end
32
32
 
33
33
  context "for multiple runs" do
34
- before(:each) { expect(Kernel).to receive(:rand).and_return(1, 2) }
34
+ before(:each) { expect(Kernel).to receive(:rand).and_return(1, 2, 0) }
35
35
 
36
36
  it 'should store tests in session by name' do
37
- expect(array.vignette('cat')).to eq('b')
37
+ expect(array.vignette(:cat)).to eq('b')
38
38
 
39
- expect(Vignette.tests).to eq({'cat' => 'b'})
40
- expect(session).to eq( {'vignette_352441c2' => 1, v: {'cat' => 'b'}.to_json} )
41
-
42
- expect(array.vignette('cat')).to eq('b') # same value
43
- expect(session).to eq( {'vignette_352441c2' => 1, v: {'cat' => 'b'}.to_json} )
44
-
45
- expect([11,22,33].vignette('cat')).to eq(33) # new value
46
- expect(session).to eq( {'vignette_352441c2' => 1, 'vignette_d4d3e16f' => 2, v: {'cat' => 33}.to_json} )
39
+ original_time = Time.now
40
+ second_time = original_time + 1
41
+ third_time = original_time + 2
42
+ fourth_time = original_time + 3
43
+
44
+ Timecop.freeze(original_time) do
45
+ expect(Vignette.tests).to eq(cat: 'b') # original choice
46
+ expect(JSON(session[:v])).to eq( { '352441c2' => { 'n' => 'cat', 'v' => 'b', 't' => original_time.to_i } } )
47
+ end
48
+
49
+ Timecop.freeze(second_time) do
50
+ expect(Vignette.tests).to eq(cat: 'b') # same value
51
+ expect(JSON(session[:v])).to eq( { '352441c2' => { 'n' => 'cat', 'v' => 'b', 't' => original_time.to_i } } )
52
+ end
53
+
54
+ Timecop.freeze(third_time) do
55
+ expect([11,22,33].vignette(:cat)).to eq(33) # new value
56
+ expect(JSON(session[:v])).to eq(
57
+ {
58
+ '352441c2' => { 'n' => 'cat', 'v' => 'b', 't' => original_time.to_i },
59
+ 'd4d3e16f' => { 'n' => 'cat', 'v' => 33, 't' => third_time.to_i }
60
+ }
61
+ )
62
+ expect(Vignette.tests).to eq(cat: 33)
63
+ end
64
+
65
+ Timecop.freeze(fourth_time) do
66
+ expect(['mice', 'mooise'].vignette(:cat)).to eq('mice') # new value
67
+ expect(JSON(session[:v])).to eq(
68
+ {
69
+ '2384053' => { 'n' => 'cat', 'v' => 'mice', 't' => fourth_time.to_i },
70
+ '352441c2' => { 'n' => 'cat', 'v' => 'b', 't' => original_time.to_i },
71
+ 'd4d3e16f' => { 'n' => 'cat', 'v' => 33, 't' => third_time.to_i }
72
+ }
73
+ )
74
+ expect(Vignette.tests).to eq(cat: 'mice')
75
+ end
47
76
  end
48
77
  end
49
78
  end
data/spec/spec_helper.rb CHANGED
@@ -2,6 +2,7 @@
2
2
  require 'pry'
3
3
  require 'haml'
4
4
  require 'vignette'
5
+ require 'timecop'
5
6
 
6
7
  RSpec.configure do |config|
7
8
  # rspec-expectations config goes here. You can use an alternate
data/vignette.gemspec CHANGED
@@ -24,4 +24,5 @@ Gem::Specification.new do |gem|
24
24
  gem.add_development_dependency "guard-rspec", ">= 4.5.0"
25
25
  gem.add_development_dependency "haml", ">= 4.0.6"
26
26
  gem.add_development_dependency "pry-byebug", ">= 0"
27
+ gem.add_development_dependency "timecop", ">= 0"
27
28
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vignette
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Geoff Hayes
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: timecop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
97
111
  description: Simple, effective A/b testing made easy.
98
112
  email:
99
113
  - geoff@safeshepherd.com