vignette 0.0.10 → 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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