vignette 0.0.8 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|