vignette 0.0.8 → 0.0.9
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 +4 -4
- data/.rspec +2 -0
- data/Guardfile +77 -0
- data/README.md +35 -7
- data/lib/vignette/filter.rb +61 -39
- data/lib/vignette/object_extensions.rb +10 -26
- data/lib/vignette/version.rb +1 -1
- data/lib/vignette.rb +32 -3
- data/spec/fixtures/ex.html.haml +6 -0
- data/spec/lib/vignette/filter_spec.rb +63 -0
- data/spec/lib/vignette/object_extensions_spec.rb +7 -0
- data/spec/lib/vignette_spec.rb +64 -0
- data/spec/spec_helper.rb +78 -0
- data/vignette.gemspec +8 -0
- metadata +100 -5
- data/lib/vignette/vignette_errors.rb +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4b05a5bbcbc2c4930ea030d2a739829c1424cd7b
|
4
|
+
data.tar.gz: d875cd3236486b99c4e3f485b32d7f25033a1a56
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 16ff69be2435420d74535ca0bd8a6add17039a477f0b3bb23ffcede3d7dbdd01527a139d171a75ef18b662234b035062a91c59a35be9e1a970f7ed57935504ae
|
7
|
+
data.tar.gz: a23a32a2da1445871d21c0060b246ecf2ca1b8650b52ab502736f7ff816019b4c113a9c6b3e2cad8bb48660a9dd93fd67ffa1dbee624e0319eeec61d576fb14d
|
data/.rspec
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
## Uncomment and set this to only include directories you want to watch
|
5
|
+
# directories %w(app lib config test spec features)
|
6
|
+
|
7
|
+
## Uncomment to clear the screen before every task
|
8
|
+
# clearing :on
|
9
|
+
|
10
|
+
## Guard internally checks for changes in the Guardfile and exits.
|
11
|
+
## If you want Guard to automatically start up again, run guard in a
|
12
|
+
## shell loop, e.g.:
|
13
|
+
##
|
14
|
+
## $ while bundle exec guard; do echo "Restarting Guard..."; done
|
15
|
+
##
|
16
|
+
## Note: if you are using the `directories` clause above and you are not
|
17
|
+
## watching the project directory ('.'), then you will want to move
|
18
|
+
## the Guardfile to a watched dir and symlink it back, e.g.
|
19
|
+
#
|
20
|
+
# $ mkdir config
|
21
|
+
# $ mv Guardfile config/
|
22
|
+
# $ ln -s config/Guardfile .
|
23
|
+
#
|
24
|
+
# and, you'll have to watch "config/Guardfile" instead of "Guardfile"
|
25
|
+
|
26
|
+
# Note: The cmd option is now required due to the increasing number of ways
|
27
|
+
# rspec may be run, below are examples of the most common uses.
|
28
|
+
# * bundler: 'bundle exec rspec'
|
29
|
+
# * bundler binstubs: 'bin/rspec'
|
30
|
+
# * spring: 'bin/rspec' (This will use spring if running and you have
|
31
|
+
# installed the spring binstubs per the docs)
|
32
|
+
# * zeus: 'zeus rspec' (requires the server to be started separately)
|
33
|
+
# * 'just' rspec: 'rspec'
|
34
|
+
|
35
|
+
guard :rspec, cmd: "bundle exec rspec" do
|
36
|
+
require "guard/rspec/dsl"
|
37
|
+
dsl = Guard::RSpec::Dsl.new(self)
|
38
|
+
|
39
|
+
# Feel free to open issues for suggestions and improvements
|
40
|
+
|
41
|
+
# RSpec files
|
42
|
+
rspec = dsl.rspec
|
43
|
+
watch(rspec.spec_helper) { rspec.spec_dir }
|
44
|
+
watch(rspec.spec_support) { rspec.spec_dir }
|
45
|
+
watch(rspec.spec_files)
|
46
|
+
|
47
|
+
# Ruby files
|
48
|
+
ruby = dsl.ruby
|
49
|
+
dsl.watch_spec_files_for(ruby.lib_files)
|
50
|
+
|
51
|
+
# Rails files
|
52
|
+
rails = dsl.rails(view_extensions: %w(erb haml slim))
|
53
|
+
dsl.watch_spec_files_for(rails.app_files)
|
54
|
+
dsl.watch_spec_files_for(rails.views)
|
55
|
+
|
56
|
+
watch(rails.controllers) do |m|
|
57
|
+
[
|
58
|
+
rspec.spec.("routing/#{m[1]}_routing"),
|
59
|
+
rspec.spec.("controllers/#{m[1]}_controller"),
|
60
|
+
rspec.spec.("acceptance/#{m[1]}")
|
61
|
+
]
|
62
|
+
end
|
63
|
+
|
64
|
+
# Rails config changes
|
65
|
+
watch(rails.spec_helper) { rspec.spec_dir }
|
66
|
+
watch(rails.routes) { "#{rspec.spec_dir}/routing" }
|
67
|
+
watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
|
68
|
+
|
69
|
+
# Capybara features specs
|
70
|
+
watch(rails.view_dirs) { |m| rspec.spec.("features/#{m[1]}") }
|
71
|
+
|
72
|
+
# Turnip features and steps
|
73
|
+
watch(%r{^spec/acceptance/(.+)\.feature$})
|
74
|
+
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
|
75
|
+
Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
|
76
|
+
end
|
77
|
+
end
|
data/README.md
CHANGED
@@ -46,7 +46,7 @@ Vignette was crafted to make A/b testing as simple as possible. Simply run the
|
|
46
46
|
# Other options
|
47
47
|
Vignette.init(logging: true) # add debug logging
|
48
48
|
|
49
|
-
Running
|
49
|
+
### Running a Vignette test in your application:
|
50
50
|
|
51
51
|
[ 1,2,3 ].vignette # Chooses an option and stores test as indicated above
|
52
52
|
%w{one two three}.vignette # Same with strings
|
@@ -58,16 +58,44 @@ Running tests:
|
|
58
58
|
Test <strong>two</strong>
|
59
59
|
Test #{three}
|
60
60
|
|
61
|
-
|
61
|
+
The choices for these tests are exposed through the `Vignette.test` method:
|
62
62
|
|
63
|
-
Vignette.test -> { 'views/
|
63
|
+
Vignette.test -> { '(app/views/users/new.html.haml:35)' => 'Test one' } # First choice was select for new.html.haml test line 35
|
64
64
|
|
65
|
-
|
65
|
+
You may store these values as properties in your analytics system.
|
66
|
+
|
67
|
+
## Caveats
|
68
|
+
|
69
|
+
Tests are stored in your store object based on the original input. If you change the input of the test (regardless of the name), a new test will be created. Thus [1,2,3].vignette(:numbers) and [2,3,4].vignette(:numbers) will always be considered unique tests. New tests will overwrite old tests with the same name in `Vignette.tests`. This is by design so that you can update the test, have new results, but keep the same test name in your analytics system.
|
70
|
+
|
71
|
+
Note, you must use arrays that will not change between runs. Thus, `[Date.today, 1.days.ago].vignette` will end up creating separate tests every time this code is run. We use a `Zlib.crc32` check to check for uniqueness of an array. Instead, this should be `[0,1].vignette.days.ago`.
|
72
|
+
|
73
|
+
If you choose to store your `tests` in `cookies`, then the chosen result will be stored in a cookie sent to the user's browser. Thus, be careful not to store any secret information in a test.
|
74
|
+
|
75
|
+
## Naming Tests
|
76
|
+
|
77
|
+
Vignette tests can also be specifically named, e.g:
|
78
|
+
|
79
|
+
@cat_name = ["Chairman Meow", "Katy Purry"].vignette(:cat_names)
|
80
|
+
|
81
|
+
|
82
|
+
or from HAML:
|
83
|
+
|
84
|
+
%div
|
85
|
+
:vignette
|
86
|
+
[dog_names]
|
87
|
+
Wooferson
|
88
|
+
T-Bone
|
89
|
+
|
90
|
+
This will lead to `Vignette.tests` to include: `{ "cat_names" => "Chairman Meow" }`
|
91
|
+
|
92
|
+
Without a name, Vignettes will try to name themselves based on the name of the falling calling them, e.g. `(app/models/user.rb:25)` or `(app/views/users/new.html.haml:22)`
|
66
93
|
|
67
94
|
## Contributing
|
68
95
|
|
69
96
|
1. Fork it
|
70
97
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
71
|
-
3.
|
72
|
-
4.
|
73
|
-
5.
|
98
|
+
3. Ensure test cases are passing (`bundle exec rspec`)
|
99
|
+
4. Commit your changes (`git commit -am 'Add some feature'`)
|
100
|
+
5. Push to the branch (`git push origin my-new-feature`)
|
101
|
+
6. Create new Pull Request
|
data/lib/vignette/filter.rb
CHANGED
@@ -1,45 +1,67 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
1
|
+
if defined?(Haml)
|
2
|
+
module Haml::Filters::Vignette
|
3
|
+
include Haml::Filters::Base
|
4
|
+
|
5
|
+
|
6
|
+
# TODO: We need to find a way to disable caching
|
7
|
+
def render_with_options(text, options)
|
8
|
+
splitter = "\n"
|
9
|
+
splitter = '->' if text.include?('->')
|
10
|
+
lines = text.split splitter
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
"
|
12
|
+
# Allow first line to be name of test, if desired
|
13
|
+
if lines.first.strip =~ /^\[(\w+)\]$/
|
14
|
+
lines[1..-1].vignette($1)
|
15
|
+
|
16
|
+
# Otherwise, try to use filename and line
|
17
|
+
elsif options[:filename] && options[:line]
|
18
|
+
if options[:filename] == "(haml)"
|
19
|
+
lines.vignette("(haml:#{options[:line]})")
|
20
|
+
else
|
21
|
+
lines.vignette("(#{Vignette::strip_path(options[:filename])}:#{options[:line]})")
|
22
|
+
end
|
23
|
+
# If not given, raise an error
|
24
|
+
else
|
25
|
+
Vignette::Errors::TemplateRequiresNameError.new("Missing filename or [test_name] in Vignette test")
|
26
26
|
end
|
27
|
-
# We need to add a newline at the beginning to get the
|
28
|
-
# filter lines to line up (since the Haml filter contains
|
29
|
-
# a line that doesn't show up in the source, namely the
|
30
|
-
# filter name). Then we need to escape the trailing
|
31
|
-
# newline so that the whole filter block doesn't take up
|
32
|
-
# too many.
|
33
|
-
text = %[\n#{text.sub(/\n"\Z/, "\\n\"")}]
|
34
|
-
push_script <<RUBY.rstrip, :escape_html => false
|
35
|
-
find_and_preserve(#{filter.inspect}.render_with_options(#{text}, _hamlout.options))
|
36
|
-
RUBY
|
37
|
-
return
|
38
27
|
end
|
39
28
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
29
|
+
# Note, this is copied from haml/filter.rb
|
30
|
+
# Unless the text contained interpolation, haml seems
|
31
|
+
# to naturally cache the result. This was impossible,
|
32
|
+
# then to run a test based on session, etc.
|
33
|
+
# I removed that check from below.
|
34
|
+
def compile(compiler, text)
|
35
|
+
filter = self
|
36
|
+
filename = compiler.options[:filename]
|
37
|
+
line = compiler.instance_variable_get('@node').line
|
38
|
+
|
39
|
+
compiler.instance_eval do
|
40
|
+
return if options[:suppress_eval]
|
41
|
+
|
42
|
+
text = unescape_interpolation(text).gsub(/(\\+)n/) do |s|
|
43
|
+
escapes = $1.size
|
44
|
+
next s if escapes % 2 == 0
|
45
|
+
"#{'\\' * (escapes - 1)}\n"
|
46
|
+
end
|
47
|
+
# We need to add a newline at the beginning to get the
|
48
|
+
# filter lines to line up (since the Haml filter contains
|
49
|
+
# a line that doesn't show up in the source, namely the
|
50
|
+
# filter name). Then we need to escape the trailing
|
51
|
+
# newline so that the whole filter block doesn't take up
|
52
|
+
# too many.
|
53
|
+
text = %[\n#{text.sub(/\n"\Z/, "\\n\"")}]
|
54
|
+
push_script <<RUBY.rstrip, :escape_html => false
|
55
|
+
find_and_preserve(#{filter.inspect}.render_with_options(#{text}, _hamlout.options.merge(filename: "#{filename}", line: #{line})))
|
56
|
+
RUBY
|
57
|
+
return
|
58
|
+
end
|
59
|
+
|
60
|
+
rendered = Haml::Helpers::find_and_preserve(filter.render_with_options(text, compiler.options, filename, line), compiler.options[:preserve])
|
61
|
+
rendered.rstrip!
|
62
|
+
rendered.gsub!("\n", "\n#{' ' * @output_tabs}") unless options[:ugly]
|
63
|
+
push_text(rendered)
|
64
|
+
end
|
44
65
|
end
|
66
|
+
|
45
67
|
end
|
@@ -9,42 +9,26 @@ module ObjectExtensions
|
|
9
9
|
|
10
10
|
# Test will select a random object from the Array
|
11
11
|
def vignette(name=nil)
|
12
|
-
|
12
|
+
vignette_crc = self.crc().abs.to_s(16)
|
13
|
+
|
14
|
+
key = "vignette_#{vignette_crc}"
|
13
15
|
test_name = nil
|
14
16
|
|
15
|
-
if name.blank?
|
16
|
-
|
17
|
-
|
18
|
-
# -> app/views/landing/family.html.haml:313c7f3a472883ba
|
19
|
-
filename = caller[1].split(':')[0].gsub(Rails.root.to_s+'/','') # Take the view name
|
20
|
-
test_name = "#{filename}:#{crc.abs.to_s(16)}"
|
21
|
-
else
|
22
|
-
# E.g /Users/hayesgm/animals/shadow/app/controllers/home_controller.rb:27:in `home'
|
23
|
-
# -> app/controllers/home_controller:home:313c7f3a472883ba
|
24
|
-
line = caller[0].gsub(Rails.root.to_s+'/','') # Take everything but the Rails root portion
|
25
|
-
|
26
|
-
m = /(?<filename>[\w.\/]+):(?<line>\d+):in `(?<function>\w+)'/.match(line)
|
27
|
-
|
28
|
-
if m && !m[:filename].blank? && !m[:function].blank?
|
29
|
-
test_name = "#{m[:filename]}:#{m[:function]}:#{crc.abs.to_s(16)}"
|
30
|
-
else # Fallback
|
31
|
-
test_name = key
|
32
|
-
end
|
33
|
-
end
|
17
|
+
test_name = if name.blank?
|
18
|
+
loc = caller_locations(1,1).first
|
19
|
+
"(#{Vignette::strip_path(loc.absolute_path)}:#{loc.lineno})"
|
34
20
|
else
|
35
|
-
name
|
21
|
+
name
|
36
22
|
end
|
37
23
|
|
38
|
-
# p ['Test name',test_name]
|
39
|
-
|
40
24
|
store = Vignette.get_store
|
41
25
|
|
42
26
|
choice = store[key] ||= Kernel.rand(length) # Store key into storage if not available
|
43
27
|
result = self[choice.to_i]
|
44
|
-
|
45
|
-
# Let's store keys where they are
|
28
|
+
|
29
|
+
# Let's store keys where they are (note, this truncates any other tests with the same name)
|
46
30
|
store[:v] = ( store[:v].present? ? JSON(store[:v]) : {} ).merge(test_name => result).to_json
|
47
|
-
|
31
|
+
|
48
32
|
return result
|
49
33
|
end
|
50
34
|
|
data/lib/vignette/version.rb
CHANGED
data/lib/vignette.rb
CHANGED
@@ -1,9 +1,18 @@
|
|
1
|
+
require "active_support/core_ext/module/attribute_accessors"
|
2
|
+
require "action_controller"
|
3
|
+
|
1
4
|
require "vignette/version"
|
2
5
|
require "vignette/object_extensions"
|
3
6
|
require "vignette/filter"
|
4
|
-
require "vignette/vignette_errors"
|
5
7
|
|
6
8
|
module Vignette
|
9
|
+
|
10
|
+
module Errors
|
11
|
+
class VignetteStandardError < StandardError; end
|
12
|
+
class ConfigError < VignetteStandardError; end
|
13
|
+
class TemplateRequiresNameError < VignetteStandardError; end
|
14
|
+
end
|
15
|
+
|
7
16
|
# Your code goes here...
|
8
17
|
mattr_accessor :logging
|
9
18
|
mattr_accessor :store
|
@@ -36,6 +45,16 @@ module Vignette
|
|
36
45
|
Vignette.session = session
|
37
46
|
Vignette.cookies = cookies
|
38
47
|
end
|
48
|
+
|
49
|
+
def self.with_settings(request, session, cookies)
|
50
|
+
begin
|
51
|
+
Vignette.request_config(request, session, cookies)
|
52
|
+
|
53
|
+
yield
|
54
|
+
ensure
|
55
|
+
Vignette.clear_request
|
56
|
+
end
|
57
|
+
end
|
39
58
|
|
40
59
|
def self.clear_request
|
41
60
|
Vignette.request = Vignette.session = Vignette.cookies = nil # clear items
|
@@ -49,11 +68,11 @@ module Vignette
|
|
49
68
|
def self.get_store(session=Vignette.session, cookies=Vignette.cookies)
|
50
69
|
case Vignette.store
|
51
70
|
when :cookies
|
52
|
-
raise
|
71
|
+
raise Errors::ConfigError, "Missing cookies configuration in Vignette. Must access Vignette in controller within around_filter." if cookies.nil?
|
53
72
|
Rails.logger.debug [ 'Vignette::vignette', 'Cookies Sampling', cookies ] if Vignette.logging
|
54
73
|
cookies.signed
|
55
74
|
when :session
|
56
|
-
raise
|
75
|
+
raise Errors::ConfigError, "Missing session configuration in Vignette. Must access Vignette in controller within around_filter." if session.nil?
|
57
76
|
Rails.logger.debug [ 'Vignette::vignette', 'Session Sampling', session ] if Vignette.logging
|
58
77
|
session
|
59
78
|
else
|
@@ -61,5 +80,15 @@ module Vignette
|
|
61
80
|
{} # This is an empty storage
|
62
81
|
end
|
63
82
|
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def self.strip_path(filename)
|
87
|
+
if defined?(Rails) && Rails
|
88
|
+
filename.gsub(Regexp.new("#{Rails.root}[/]?"), '')
|
89
|
+
else
|
90
|
+
filename.split('/')[-1]
|
91
|
+
end
|
92
|
+
end
|
64
93
|
|
65
94
|
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Haml::Filters::Vignette do
|
4
|
+
|
5
|
+
context "when parsing a haml template" do
|
6
|
+
let!(:session) { Hash.new }
|
7
|
+
before(:each) { expect(Kernel).to receive(:rand).and_return(2) }
|
8
|
+
|
9
|
+
context "with a rendered template and no file name" do
|
10
|
+
let(:template) { "
|
11
|
+
%p
|
12
|
+
:vignette
|
13
|
+
one
|
14
|
+
two
|
15
|
+
three
|
16
|
+
" }
|
17
|
+
|
18
|
+
it "should raise error" do
|
19
|
+
Vignette.with_settings(nil, session, nil) do
|
20
|
+
html = Haml::Engine.new(template).render
|
21
|
+
|
22
|
+
expect(html).to match(/\<p\>\s+three\s+\<\/p\>\n/)
|
23
|
+
expect(Vignette.tests).to eq({"(haml:3)" => "three"})
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "with a rendered template" do
|
29
|
+
let(:template) { "
|
30
|
+
%p
|
31
|
+
:vignette
|
32
|
+
[numbers]
|
33
|
+
one
|
34
|
+
two
|
35
|
+
three
|
36
|
+
" }
|
37
|
+
|
38
|
+
it "should correctly call vignette from render" do
|
39
|
+
Vignette.with_settings(nil, session, nil) do
|
40
|
+
html = Haml::Engine.new(template).render
|
41
|
+
|
42
|
+
expect(html).to match(/\<p\>\s+three\s+\<\/p\>\n/)
|
43
|
+
expect(Vignette.tests).to eq({"numbers" => "three"})
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "with a template file" do
|
49
|
+
let(:template_file) { File.join(File.dirname(__FILE__), '../../fixtures/ex.html.haml') }
|
50
|
+
|
51
|
+
it "should correctly call vignette from render" do
|
52
|
+
Vignette.with_settings(nil, session, nil) do
|
53
|
+
template = File.read(template_file)
|
54
|
+
|
55
|
+
html = Haml::Engine.new(template, filename: template_file).render
|
56
|
+
|
57
|
+
expect(html).to match(/\<div\>\s+I like\s+scorpians\s+\<\/div\>/)
|
58
|
+
expect(Vignette.tests).to eq({"(ex.html.haml:3)" => "scorpians"})
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Vignette do
|
4
|
+
|
5
|
+
context 'with simple session store' do
|
6
|
+
let!(:session) { Hash.new }
|
7
|
+
let(:array) { %w{a b c} }
|
8
|
+
before { Vignette.session = session }
|
9
|
+
|
10
|
+
it 'should have correct crc' do
|
11
|
+
expect(array.crc).to eq(891568578)
|
12
|
+
expect(array.crc.abs.to_s(16)).to eq('352441c2')
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'when calling vignette' do
|
16
|
+
context "for a single run" do
|
17
|
+
before(:each) { expect(Kernel).to receive(:rand).and_return(1) }
|
18
|
+
|
19
|
+
it 'should store tests in session' do
|
20
|
+
expect(array.vignette).to eq('b'); line = __LINE__ # for tracking line number
|
21
|
+
expect(Vignette.tests).to eq({"(vignette_spec.rb:#{line})" => 'b'})
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "for multiple runs" do
|
26
|
+
before(:each) { expect(Kernel).to receive(:rand).and_return(1, 2) }
|
27
|
+
|
28
|
+
it 'should store tests in session by name' do
|
29
|
+
expect(array.vignette('cat')).to eq('b')
|
30
|
+
|
31
|
+
expect(Vignette.tests).to eq({'cat' => 'b'})
|
32
|
+
expect(session).to eq( {'vignette_352441c2' => 1, v: {'cat' => 'b'}.to_json} )
|
33
|
+
|
34
|
+
expect(array.vignette('cat')).to eq('b') # same value
|
35
|
+
expect(session).to eq( {'vignette_352441c2' => 1, v: {'cat' => 'b'}.to_json} )
|
36
|
+
|
37
|
+
expect([11,22,33].vignette('cat')).to eq(33) # new value
|
38
|
+
expect(session).to eq( {'vignette_352441c2' => 1, 'vignette_d4d3e16f' => 2, v: {'cat' => 33}.to_json} )
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'when stripping paths' do
|
45
|
+
let(:path) { '/a/b/c/d.ex' }
|
46
|
+
|
47
|
+
context 'with rails defined' do
|
48
|
+
before { stub_const('Rails', double('rails', root: '/a/b')) }
|
49
|
+
|
50
|
+
it 'should properly gsub out rails root' do
|
51
|
+
expect(Vignette.strip_path(path)).to eq('c/d.ex')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'with rails undefined' do
|
56
|
+
before { stub_const('Rails', nil) }
|
57
|
+
|
58
|
+
it 'should just have final path' do
|
59
|
+
expect(Vignette.strip_path(path)).to eq('d.ex')
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
|
2
|
+
require 'pry'
|
3
|
+
require 'haml'
|
4
|
+
require 'vignette'
|
5
|
+
|
6
|
+
RSpec.configure do |config|
|
7
|
+
# rspec-expectations config goes here. You can use an alternate
|
8
|
+
# assertion/expectation library such as wrong or the stdlib/minitest
|
9
|
+
# assertions if you prefer.
|
10
|
+
config.expect_with :rspec do |expectations|
|
11
|
+
# This option will default to `true` in RSpec 4. It makes the `description`
|
12
|
+
# and `failure_message` of custom matchers include text for helper methods
|
13
|
+
# defined using `chain`, e.g.:
|
14
|
+
# be_bigger_than(2).and_smaller_than(4).description
|
15
|
+
# # => "be bigger than 2 and smaller than 4"
|
16
|
+
# ...rather than:
|
17
|
+
# # => "be bigger than 2"
|
18
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
19
|
+
end
|
20
|
+
|
21
|
+
# rspec-mocks config goes here. You can use an alternate test double
|
22
|
+
# library (such as bogus or mocha) by changing the `mock_with` option here.
|
23
|
+
config.mock_with :rspec do |mocks|
|
24
|
+
# Prevents you from mocking or stubbing a method that does not exist on
|
25
|
+
# a real object. This is generally recommended, and will default to
|
26
|
+
# `true` in RSpec 4.
|
27
|
+
mocks.verify_partial_doubles = true
|
28
|
+
end
|
29
|
+
|
30
|
+
# The settings below are suggested to provide a good initial experience
|
31
|
+
# with RSpec, but feel free to customize to your heart's content.
|
32
|
+
=begin
|
33
|
+
# These two settings work together to allow you to limit a spec run
|
34
|
+
# to individual examples or groups you care about by tagging them with
|
35
|
+
# `:focus` metadata. When nothing is tagged with `:focus`, all examples
|
36
|
+
# get run.
|
37
|
+
config.filter_run :focus
|
38
|
+
config.run_all_when_everything_filtered = true
|
39
|
+
|
40
|
+
# Limits the available syntax to the non-monkey patched syntax that is
|
41
|
+
# recommended. For more details, see:
|
42
|
+
# - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
|
43
|
+
# - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
44
|
+
# - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
|
45
|
+
config.disable_monkey_patching!
|
46
|
+
|
47
|
+
# This setting enables warnings. It's recommended, but in some cases may
|
48
|
+
# be too noisy due to issues in dependencies.
|
49
|
+
config.warnings = true
|
50
|
+
|
51
|
+
# Many RSpec users commonly either run the entire suite or an individual
|
52
|
+
# file, and it's useful to allow more verbose output when running an
|
53
|
+
# individual spec file.
|
54
|
+
if config.files_to_run.one?
|
55
|
+
# Use the documentation formatter for detailed output,
|
56
|
+
# unless a formatter has already been configured
|
57
|
+
# (e.g. via a command-line flag).
|
58
|
+
config.default_formatter = 'doc'
|
59
|
+
end
|
60
|
+
|
61
|
+
# Print the 10 slowest examples and example groups at the
|
62
|
+
# end of the spec run, to help surface which specs are running
|
63
|
+
# particularly slow.
|
64
|
+
config.profile_examples = 10
|
65
|
+
|
66
|
+
# Run specs in random order to surface order dependencies. If you find an
|
67
|
+
# order dependency and want to debug it, you can fix the order by providing
|
68
|
+
# the seed, which is printed after each run.
|
69
|
+
# --seed 1234
|
70
|
+
config.order = :random
|
71
|
+
|
72
|
+
# Seed global randomization in this process using the `--seed` CLI option.
|
73
|
+
# Setting this allows you to use `--seed` to deterministically reproduce
|
74
|
+
# test failures related to randomization by passing the same `--seed` value
|
75
|
+
# as the one that triggered the failure.
|
76
|
+
Kernel.srand config.seed
|
77
|
+
=end
|
78
|
+
end
|
data/vignette.gemspec
CHANGED
@@ -16,4 +16,12 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
17
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
18
|
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_dependency "activesupport", ">= 3.0"
|
21
|
+
gem.add_dependency "actionpack", ">= 3.0"
|
22
|
+
|
23
|
+
gem.add_development_dependency "rspec", ">= 3.2.0"
|
24
|
+
gem.add_development_dependency "guard-rspec", ">= 4.5.0"
|
25
|
+
gem.add_development_dependency "haml", ">= 4.0.6"
|
26
|
+
gem.add_development_dependency "pry-byebug", ">= 0"
|
19
27
|
end
|
metadata
CHANGED
@@ -1,15 +1,99 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vignette
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Geoff Hayes
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-02-
|
12
|
-
dependencies:
|
11
|
+
date: 2015-02-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: actionpack
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 3.2.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 3.2.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: guard-rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 4.5.0
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 4.5.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: haml
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 4.0.6
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 4.0.6
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pry-byebug
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
13
97
|
description: Simple, effective A/b testing made easy.
|
14
98
|
email:
|
15
99
|
- geoff@safeshepherd.com
|
@@ -18,7 +102,9 @@ extensions: []
|
|
18
102
|
extra_rdoc_files: []
|
19
103
|
files:
|
20
104
|
- ".gitignore"
|
105
|
+
- ".rspec"
|
21
106
|
- Gemfile
|
107
|
+
- Guardfile
|
22
108
|
- LICENSE.txt
|
23
109
|
- README.md
|
24
110
|
- Rakefile
|
@@ -26,7 +112,11 @@ files:
|
|
26
112
|
- lib/vignette/filter.rb
|
27
113
|
- lib/vignette/object_extensions.rb
|
28
114
|
- lib/vignette/version.rb
|
29
|
-
-
|
115
|
+
- spec/fixtures/ex.html.haml
|
116
|
+
- spec/lib/vignette/filter_spec.rb
|
117
|
+
- spec/lib/vignette/object_extensions_spec.rb
|
118
|
+
- spec/lib/vignette_spec.rb
|
119
|
+
- spec/spec_helper.rb
|
30
120
|
- vignette.gemspec
|
31
121
|
homepage: https://github.com/hayesgm/vignette
|
32
122
|
licenses: []
|
@@ -51,5 +141,10 @@ rubygems_version: 2.2.2
|
|
51
141
|
signing_key:
|
52
142
|
specification_version: 4
|
53
143
|
summary: With a few simple features, get A/b testing up in your application.
|
54
|
-
test_files:
|
144
|
+
test_files:
|
145
|
+
- spec/fixtures/ex.html.haml
|
146
|
+
- spec/lib/vignette/filter_spec.rb
|
147
|
+
- spec/lib/vignette/object_extensions_spec.rb
|
148
|
+
- spec/lib/vignette_spec.rb
|
149
|
+
- spec/spec_helper.rb
|
55
150
|
has_rdoc:
|