moviepilot-gwo 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Made by Many
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,120 @@
1
+ This is a Ruby on Rails plugin (gem) which simplifies Server-Side Dynamic Section Variations with
2
+ [Google Website Optimizer](http://www.google.com/websiteoptimizer) as described in the article
3
+ [Server-Side Dynamic Section Variations on gwotricks.com](http://www.gwotricks.com/2009/05/server-side-dynamic-section-variations.html)
4
+
5
+ == Features:
6
+ ------------
7
+
8
+ * very good Ruby on Rails integration
9
+ * very simple to use
10
+ * support for several sections that should have different variants
11
+ * support for named and numbered sections
12
+ * include part of a page in more than one variant
13
+ * support for google analytics tracking
14
+ * kill-switch
15
+ * well tested
16
+
17
+
18
+ The 'Usage' may look long - but it's fairly straightforward and shouldn't take 5 mins.
19
+
20
+ Daniel Bornkessel gwo@bornkessel.com & Alex MacCaw - alex@madebymany.co.uk (original author)
21
+
22
+ == Usage
23
+ --------
24
+
25
+ To use GWO, you need two pages:
26
+ * A test page containing the multi variant sections
27
+ * A page that signifies conversion (i.e. account creation page)
28
+
29
+ [Signup for Google Website Optimizer and](http://www.google.com/websiteoptimizer):
30
+ 1. Click create another experiment
31
+ 2. Click multivariate experiment
32
+ 3. Name it and enter the test/conversion urls
33
+ 4. Select 'You will install and validate the JavaScript tags'
34
+ 5. Ignore the scripts that are offered, but strip out your account id (uacct) and test id (both to be found in the Tracking Script).
35
+ They look like as follows:
36
+ var pageTracker=_gat._getTracker("UI-6882082-1");
37
+ pageTracker._trackPageview("/1662461989/test");
38
+ So, in this example the uacct is 'UA-6882082-1' and the test id is 1662461989.
39
+ 6. Leave google and prepare your source code
40
+ 7. Add the gwo_experiment tag around the code that is supposed to contain the variants (see the gwo_experiment documentation for
41
+ possible options)
42
+ 8. in the gwo_experiment you can specify one or more sections your side can contain. Each section can have several
43
+ variants. So if you have for example 2 sections with each having 3 variants you would have 6 different possible
44
+ combinations on your page.
45
+ 9. Create your gwo_sections, as in the example. The first parameter is the name of the section,
46
+ the second the name of the variant(s) in which the following code should be shown (see example code).
47
+ You can mix variants by just passing in more than one identifier. The
48
+ original variant has the reserved identifier :original (or 0 if you use numbers)
49
+ 10. The variants can either be identified by numbers (starting at 0 for the original variant) or be named (see below how to
50
+ assign the names in the google web interface).
51
+ 11. Add a gwo_conversion helper tag on your conversion page passing in your uacct and test id.
52
+ 12. In order to validate the pages in the goole web interface, start rails, surf to the pages (variant and conversion page) you
53
+ just created and save each one locally.
54
+ 13. back in the google web interface, validate your pages by using the 'offline validation' link and upload the two
55
+ pages you just saved
56
+ 14. as a next step, define the sections. If you used named identifiers in you rails source code, put the the identifiers
57
+ name as the content of the variations in the web interface (i.e. the example below would have two variants (+ the original
58
+ variant); one variation would have the CONTENT (subject & name of the variants are not important) 'minimalistic' and the other
59
+ 'with_sidebar_and_top_signup_box' (without the quotes)). If you use numbered identifiers, just create new variations and leave the
60
+ content empty.
61
+ 15. finish up and start the experiment
62
+ 16. lean back and let google collect data for you for the next few days ... go back an be shocked about the little number of
63
+ conversions you will probably get ;)
64
+
65
+
66
+ == Example
67
+ ----------
68
+ ... in haml:
69
+
70
+ = gwo_experiment("1662461989", "UA-6882082-1", :signup_box_test, :conditions => (signed_up? && country == "de")) do
71
+ = gwo_section(:signup_box_test, [:with_sidebar_and_top_signup_box, :minimalistic], :ga_tracking => true, :conditions => (signed_up? && country == "de")) do
72
+ = render :partial => 'gossib/signup'
73
+ %span I am only visible in the variants :with_sidebar_and_top_signup_box and :minimalistic
74
+
75
+ = gwo_section(:signup_box_test, [:original, :with_sidebar_and_top_signup_box], :conditions => (signed_up? && country == "de")) do
76
+ = render :partial => 'gossib/bookmark_menu'
77
+ = render :partial => 'gossip/pics', :locals => {:images => @article.images}
78
+ .box#
79
+ %span Hi hi ... I am not visible in :minimalistic
80
+
81
+ %span I am visible in every variation
82
+
83
+ = gwo_section(:signup_box_test, :original, :conditions => (signed_up? && country == "de")) do
84
+ %span I am only in the original page
85
+
86
+ ... or in erb:
87
+
88
+ <% gwo_experiment("1662461989", "UA-6882082-1", :signup_box_test, :conditions => (signed_up? && country == "de")) do %>
89
+ <% render :partial => 'gossip/article.html.haml', :object => @article %>
90
+
91
+ <% gwo_section(:signup_box_test, [:with_sidebar_and_top_signup_box, :minimalistic], :conditions => (signed_up? && country == "de")) do %>
92
+ <%= render :partial => 'gossib/signup' %>
93
+ <span> I am only visible in the variants :with_sidebar_and_top_signup_box and :minimalistic</span>
94
+ <% end %>
95
+
96
+ <% gwo_section(:signup_box_test, [:original, :with_sidebar_and_top_signup_box], :conditions => (signed_up? && country == "de")) do %>
97
+ <%= render :partial => 'gossib/bookmark_menu' %>
98
+ <%= render :partial => 'gossip/pics', :locals => {:images => @article.images} %>
99
+ <div class="box">
100
+ <span> Hi hi ... I am not visible in :minimalistic</span>
101
+ <% end %>
102
+
103
+ <span> I am visible in every variation</span>
104
+
105
+ <% gwo_section(:signup_box_test, :original, :conditions => (signed_up? && country == "de")) do %>
106
+ <span> I am only in the original page</span>
107
+ <% end %>
108
+ <% end %>
109
+
110
+
111
+ == Conversion page:
112
+ ------------------
113
+ ... haml:
114
+ = gwo_conversion('UA-23902382-1', '1909920434')
115
+
116
+ ... erb:
117
+ <%= gwo_conversion('UA-23902382-1', '1909920434') %>
118
+
119
+
120
+ Copyright (c) 2009 Made by Many, released under the MIT license
data/lib/gwo.rb ADDED
@@ -0,0 +1,203 @@
1
+ # Author:: Alex MacCaw - alex AT madebymany DOT co DOT uk (original), Daniel Bornkessel - daniel AT bornkessel DOT com
2
+ # License:: MIT
3
+ # :include:README.markdown
4
+ #
5
+ #
6
+
7
+ require 'action_view/helpers/capture_helper'
8
+ module GWO
9
+ module Helper
10
+
11
+ include ::ActionView::Helpers::CaptureHelper
12
+
13
+ # start a gwo_experiment
14
+ #
15
+ # Params:
16
+ # * <b>id</b> the id of the experiment (in the google Tracking Script look for something like <tt>pageTracker._trackPageview("/<ID>/test");</tt> )
17
+ # * <b>uacct</b> account number (in the google Tracking Script look for something like <tt>var pageTracker=_gat._getTracker("<UACCT>");</tt> )
18
+ # * <b>sections</b> name of the section(s) your page will include; pass in one symbol/string or an array of symbols/strings here
19
+ # * <b>options</b> hash of possible options:
20
+ # * <b>:conditions</b> if set to false, the experiment won't be executed -- only the source code of the :original (or 0) variants would be shown. No JavaScript code will be produced. It serves as a kill switch for the gwo experiment. If, for example, you only want to execute an experiment for users that are not logged in, you could pass <tt>:conditions => !logged_in?</tt> here.
21
+ # * <b>:ga_tracking</b> executes a <tt>trackPageView(...)</tt> for google analytics tracking. It adds parameters to the URL, so you can identify which variant (or combination) the user saw (handy if you want to check on the exit rate with GA)
22
+ # * <b>:ga_base_url</b> set a static base URL for google analytics: Say your variant is in a 'show' view, GA would track a lot of different URLs (as the show view url contains the ID). If you are just interested about the variants in GA, set a static URL here (i.e. hbp://<your domain>/ab-testing ) and GA tracking will always be that static domain + parameters with information about the variant the user saw.
23
+ def gwo_experiment(id, uacct, sections = [], options = {}, &block)
24
+ options = {
25
+ :conditions => true,
26
+ :ga_tracking => false,
27
+ :ga_base_url => nil
28
+ }.update(options)
29
+
30
+ src = gwo_start(id, sections, options)
31
+ src += capture(&block)
32
+ src += gwo_end(id, uacct, options)
33
+ src
34
+ end
35
+
36
+
37
+ # to be included on the conversion page.
38
+ #
39
+ # Params:
40
+ # * <b>id</b> & <b>uacct</b> see gwo_experiment
41
+ # * <b>options</b>
42
+ # * :conditions as in gwo_experiment
43
+ def gwo_conversion(id, uacct, options = {})
44
+ options = {
45
+ :conditions => true
46
+ }.update(options)
47
+
48
+ return js_logger("skipping conversion snippet: a/b variation test switched off", true) if options[:conditions] == false
49
+
50
+ %{
51
+ <script type="text/javascript">
52
+ #{ js_logger("'conversion for test with id #{id} and uacct #{uacct}'") }
53
+ if(typeof(_gat)!='object')document.write('<sc'+'ript src="http'+
54
+ (document.location.protocol=='https:'?'s://ssl':'://www')+
55
+ '.google-analytics.com/ga.js"></sc'+'ript>')</script>
56
+ <script type="text/javascript">
57
+ try {
58
+ var pageTracker=_gat._getTracker("#{uacct}");
59
+ pageTracker._trackPageview("/#{id}/goal");
60
+ }catch(err){}</script>
61
+ }
62
+
63
+ end
64
+
65
+
66
+ # identify a section which is only visible in certain variants
67
+ #
68
+ # Params:
69
+ # * <b>section</b> name of the section
70
+ # * <b>variation_ids</b> identifiers of the variants in which this content is to be shown. Can be either a name of the variant (== the <b><i>content</i></b> of a variant in the GWO web interface) or a number. The original content has the reserved name <tt>:original</tt> or the number <tt>0</tt> respectivly. If the content should be shown in more than one variant, pass in an array of identifiers. Mixing numbered and named variant ids will result in an exception.
71
+ # * <b>options</b>
72
+ # * :conditions as in gwo_experiment
73
+ def gwo_section(section = "gwo_section", variation_ids = nil, options = {}, &block)
74
+ options = {
75
+ :conditions => true
76
+ }.update(options)
77
+
78
+ variation_ids = [*variation_ids].compact
79
+ src = ""
80
+ if is_default_section?(variation_ids)
81
+ if options[:conditions] == false
82
+ src += capture(&block)
83
+ else
84
+ conditions = (named_variations?(variation_ids) ? variation_ids.map{|x| "GWO_#{section}_name != \"#{x}\""} : variation_ids.map{|x| "GWO_#{section}_number != #{x}"}).join(" && ")
85
+
86
+ src += %{ <script>
87
+ if ( #{ conditions } ) document.write('<no' + 'script>');
88
+ </script>
89
+ #{capture(&block) if block_given?}
90
+ </noscript>
91
+ }
92
+ end
93
+ elsif options[:conditions] == true
94
+ if !variation_ids.empty?
95
+ conditions = (named_variations?(variation_ids) ? variation_ids.map{|x| "GWO_#{section}_name == \"#{x}\""} : variation_ids.map{|x| "GWO_#{section}_number == #{x}"}).join(" || ")
96
+
97
+ src += %{<script>
98
+ if ( #{ conditions } ) document.write('</noscript a="');
99
+ </script><!--">
100
+ #{capture(&block) if block_given?}
101
+ <script>document.write('<'+'!'+'-'+'-')</script>-->
102
+ }
103
+ end
104
+ else
105
+ src = js_logger("skipping snippet for #{variation_ids.join(", ")} variations: a/b variation test switched off", true)
106
+ end
107
+ src
108
+ end
109
+
110
+ private
111
+ def js_logger(text, with_js_tag = false)
112
+ return "if(typeof(console.log) == 'function') console.log(#{text});" if RAILS_ENV != "test" && RAILS_ENV != "production" && !with_js_tag
113
+ return "<script type='text/javascript'>if(typeof(console.log) == 'function') console.log(\"#{text}\");</script>" if RAILS_ENV != "test" && RAILS_ENV != "production" && with_js_tag
114
+ return ""
115
+ end
116
+
117
+ def gwo_start(id, sections = [], options = {})
118
+
119
+ return js_logger("skipping start snippet: a/b variation test switched off", true) if options[:conditions] == false
120
+
121
+
122
+ sections = [*sections].compact.empty? ? ["gwo_section"] : [*sections]
123
+ src = %{
124
+ <script type='text/javascript'>
125
+ function utmx_section(){}function utmx(){}
126
+ (function(){var k='#{id}',d=document,l=d.location,c=d.cookie;function f(n){
127
+ if(c){var i=c.indexOf(n+'=');if(i>-1){var j=c.indexOf(';',i);return c.substring(i+n.
128
+ length+1,j<0?c.length:j)}}}var x=f('__utmx'),xx=f('__utmxx'),h=l.hash;
129
+ d.write('<sc'+'ript src="'+
130
+ 'http'+(l.protocol=='https:'?'s://ssl':'://www')+'.google-analytics.com'
131
+ +'/siteopt.js?v=1&utmxkey='+k+'&utmx='+(x?x:'')+'&utmxx='+(xx?xx:'')+'&utmxtime='
132
+ +new Date().valueOf()+(h?'&utmxhash='+escape(h.substr(1)):'')+
133
+ '" type="text/javascript" charset="utf-8"></sc'+'ript>')})();
134
+ </script>
135
+ }
136
+
137
+ google_analytics_info = "";
138
+ section_definitions = "";
139
+ variable_assignments = "";
140
+
141
+ sections.each do |section|
142
+ section_definitions += "<!-- utmx section name='#{section}' -->\n"
143
+
144
+ variable_assignments += %{\
145
+ var GWO_#{section}_name = utmx("variation_content", "#{section}");\
146
+ if( GWO_#{section}_name == undefined) GWO_#{section}_name = 'original';\
147
+ \
148
+ var GWO_#{section}_number = utmx("variation_number", "#{section}");\
149
+ if( GWO_#{section}_number == undefined) GWO_#{section}_number = 0;\
150
+ \
151
+ #{ js_logger("'variant: ' + GWO_#{section}_name") }\
152
+ }
153
+ google_analytics_info += "google_analytics_info += \"&GWO_#{section}_name=\" + GWO_#{section}_name;" if options[:ga_tracking]
154
+ end
155
+
156
+ if options[:ga_tracking]
157
+ base_url = options[:ga_base_url] ? "\"#{options[:ga_base_url]}\"" : "document.location"
158
+ variable_assignments += %{\
159
+ window.onload = function(){ \
160
+ var google_analytics_info = ''; #{google_analytics_info}; if(typeof(trackPageView) == 'function') {\
161
+ trackPageView(#{base_url} + "?ab_test=true" + google_analytics_info);\
162
+ #{js_logger("#{base_url} + \"?ab_test=true\" + google_analytics_info")}\
163
+ }\
164
+ }\
165
+ }
166
+ end
167
+
168
+ variable_assignments = "<script type='text/javascript'>#{variable_assignments}</script>";
169
+
170
+ "#{src}#{section_definitions}#{variable_assignments}"
171
+ end
172
+
173
+ def gwo_end(id, uacct, options)
174
+ return js_logger("skipping end snippet: a/b variation test switched off", true) if options[:conditions] == false
175
+
176
+ %{<script type="text/javascript">
177
+ if(typeof(_gat)!='object')document.write('<sc'+'ript src="http'+
178
+ (document.location.protocol=='https:'?'s://ssl':'://www')+
179
+ '.google-analytics.com/ga.js"></sc'+'ript>')</script>
180
+ <script type="text/javascript">
181
+ try {
182
+ var pageTracker=_gat._getTracker("#{uacct}");
183
+ pageTracker._trackPageview("/#{id}/test");
184
+ }catch(err){}</script>
185
+ }
186
+
187
+ end
188
+
189
+ def is_default_section?(variation_ids)
190
+ variation_ids.include?(:original) || variation_ids.include?(0)
191
+ end
192
+
193
+ def named_variations?(variation_ids)
194
+ raise RuntimeError.new("variation ids can only be either string, symbols or numbers") if [*variation_ids].compact.empty? # catch empty hashes and nil
195
+
196
+ return false if [1, *variation_ids].map(&:class).uniq.length == 1 # all variation_ids are FixNums
197
+ return true if ["string", :symbol, *variation_ids].map(&:class).uniq.length == 2 # all variation_ids are either string or symbol
198
+
199
+ raise RuntimeError.new("variation ids can only be either string, symbols or numbers")
200
+ end
201
+ end
202
+
203
+ end
data/rails/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ # Include hook code here
2
+ ActionView::Base.send(:include, GWO::Helper)
@@ -0,0 +1,203 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require 'lib/gwo'
3
+
4
+ describe GWO do
5
+ include GWO::Helper
6
+
7
+ describe "google analytics stuff" do
8
+ it "should not create any google analytics stuff by default" do
9
+ gwo_start("gwo_id", "section_name").should_not =~ /google_analytics_info \+= \"&GWO_section_name_name=\" \+ GWO_section_name_name;/
10
+ gwo_start("gwo_id", "section_name").should_not =~ /trackPageView\(document.location \+ \"\?ab_test=true\" \+ google_analytics_info\)/
11
+ end
12
+ it "should not create google analytics stuff if option is disabled" do
13
+ gwo_start("gwo_id", "section_name", :ga_tracking => false).should_not =~ /google_analytics_info \+= \"&GWO_section_name_name=\" \+ GWO_section_name_name;/
14
+ gwo_start("gwo_id", "section_name", :ga_tracking => false).should_not =~ /trackPageView\(document.location \+ \"\?ab_test=true\" \+ google_analytics_info\)/
15
+ end
16
+
17
+ it "should create correct google analytics stuff for default urls" do
18
+ gwo_start("gwo_id", "section_name", :ga_tracking => true).should =~ /google_analytics_info \+= \"&GWO_section_name_name=\" \+ GWO_section_name_name;/
19
+ gwo_start("gwo_id", "section_name", :ga_tracking => true).should =~ /trackPageView\(document.location \+ \"\?ab_test=true\" \+ google_analytics_info\)/
20
+ end
21
+
22
+ it "should create correct google analytics stuff for static urls" do
23
+ gwo_start("gwo_id", "section_name", :ga_tracking => true, :ga_base_url => "http://example.com").should =~ /google_analytics_info \+= \"&GWO_section_name_name=\" \+ GWO_section_name_name;/
24
+ gwo_start("gwo_id", "section_name", :ga_tracking => true, :ga_base_url => "http://example.com").should =~ /trackPageView\(\"http:\/\/example\.com\" \+ \"\?ab_test=true\" \+ google_analytics_info\)/
25
+ end
26
+
27
+ it "should create correct google analytics stuff for several sections" do
28
+ gwo_start("gwo_id", ["section_name1", "section_name2", "section_name3"], :ga_tracking => true).should =~ /google_analytics_info \+= \"&GWO_section_name1_name=\" \+ GWO_section_name1_name;/
29
+ gwo_start("gwo_id", ["section_name1", "section_name2", "section_name3"], :ga_tracking => true).should =~ /google_analytics_info \+= \"&GWO_section_name2_name=\" \+ GWO_section_name2_name;/
30
+ gwo_start("gwo_id", ["section_name1", "section_name2", "section_name3"], :ga_tracking => true).should =~ /google_analytics_info \+= \"&GWO_section_name3_name=\" \+ GWO_section_name3_name;/
31
+ gwo_start("gwo_id", ["section_name1", "section_name2", "section_name3"], :ga_tracking => true).should =~ /trackPageView\(document.location \+ \"\?ab_test=true\" \+ google_analytics_info\)/
32
+ end
33
+
34
+ end
35
+
36
+ describe "named_variations? method" do
37
+ it "should return false if one numbered variation is passed in" do
38
+ named_variations?(1).should == false
39
+ end
40
+ it "should return false if variations are numbered" do
41
+ named_variations?([1,2,3]).should == false
42
+ end
43
+
44
+ it "should return true if one string is passed in" do
45
+ named_variations?("string").should == true
46
+ end
47
+ it "should return true if one symbol is passed in" do
48
+ named_variations?(:symbol).should == true
49
+ end
50
+ it "should return true if symbols and strings are mixed" do
51
+ named_variations?([:symbol, "string", :symbol2]).should == true
52
+ end
53
+ it "should throw an exception if numbers and strings are mixed" do
54
+ lambda {named_variations?([1, :symbol])}.should raise_error(RuntimeError)
55
+ lambda {named_variations?([1, "string"])}.should raise_error(RuntimeError)
56
+ lambda {named_variations?([1, "string", :symbol])}.should raise_error(RuntimeError)
57
+ end
58
+ it "should throw an exception if one obscure object is passed in" do
59
+ lambda {named_variations?(Hash.new)}.should raise_error(RuntimeError)
60
+ lambda {named_variations?(RuntimeError.new)}.should raise_error(RuntimeError)
61
+ end
62
+ it "should throw an exception if an array of obscure object is passed in" do
63
+ lambda {named_variations?([{}, {}])}.should raise_error(RuntimeError)
64
+ end
65
+ end
66
+
67
+ describe "gwo_start method" do
68
+ it "should produce correct output" do
69
+ gwo_start("gwo_id", "section_name").should =~ /utmx section name='section_name'/
70
+ gwo_start("gwo_id", "section_name").should =~ /utmx\(\"variation_content\", \"section_name\"\)/
71
+ gwo_start("gwo_id", "section_name").should =~ /utmx\(\"variation_number\", \"section_name\"\)/
72
+ gwo_start("gwo_id", "section_name").should =~ /k='gwo_id'/
73
+ end
74
+
75
+ it "should work with just the id parameter set" do
76
+ gwo_start("gwo_id").should =~ /k='gwo_id'/
77
+ gwo_start("gwo_id").should =~ /utmx section name='gwo_section'/
78
+ gwo_start("gwo_id").should =~ /utmx\(\"variation_content\", \"gwo_section\"\)/
79
+ gwo_start("gwo_id").should =~ /utmx\(\"variation_number\", \"gwo_section\"\)/
80
+ gwo_start("gwo_id", nil).should =~ /utmx section name='gwo_section'/
81
+ end
82
+
83
+ it "should work with one single section ... section is a symbol" do
84
+ gwo_start("gwo_id", :section_name).should =~ /utmx section name='section_name'/
85
+ gwo_start("gwo_id", :section_name).should =~ /utmx\(\"variation_content\", \"section_name\"\)/
86
+ gwo_start("gwo_id", :section_name).should =~ /utmx\(\"variation_number\", \"section_name\"\)/
87
+ gwo_start("gwo_id", :section_name).should =~ /k='gwo_id'/
88
+ end
89
+
90
+ it "should work with an array of section" do
91
+ gwo_start("gwo_id", ["body",:content,"footer"]).should =~ /utmx section name='body'/
92
+ gwo_start("gwo_id", ["body",:content,"footer"]).should =~ /utmx section name='content'/
93
+ gwo_start("gwo_id", ["body",:content,"footer"]).should =~ /utmx section name='footer'/
94
+
95
+ gwo_start("gwo_id", ["body",:content,"footer"]).should =~ /utmx\(\"variation_content\", \"body\"\)/
96
+ gwo_start("gwo_id", ["body",:content,"footer"]).should =~ /utmx\(\"variation_content\", \"content\"\)/
97
+ gwo_start("gwo_id", ["body",:content,"footer"]).should =~ /utmx\(\"variation_content\", \"footer\"\)/
98
+
99
+ gwo_start("gwo_id", ["body",:content,"footer"]).should =~ /utmx\(\"variation_number\", \"body\"\)/
100
+ gwo_start("gwo_id", ["body",:content,"footer"]).should =~ /utmx\(\"variation_number\", \"content\"\)/
101
+ gwo_start("gwo_id", ["body",:content,"footer"]).should =~ /utmx\(\"variation_number\", \"footer\"\)/
102
+ end
103
+
104
+ it "should return nothing when conditions return false" do
105
+ gwo_start("id", [], {:conditions => false}).should == ""
106
+ gwo_start("gwo_id", ["body",:content,"footer"], :conditions => false).should == ""
107
+
108
+ gwo_start("gwo_id", ["body",:content,"footer"], {:conditions => false}).should_not =~ /utmx\(\"variation_content\", \"body\"\)/
109
+ gwo_start("gwo_id", ["body",:content,"footer"], {:conditions => false}).should_not =~ /utmx\(\"variation_content\", \"content\"\)/
110
+ gwo_start("gwo_id", ["body",:content,"footer"], {:conditions => false}).should_not =~ /utmx\(\"variation_content\", \"footer\"\)/
111
+
112
+ gwo_start("gwo_id", ["body",:content,"footer"], :conditions => false).should_not =~ /utmx\(\"variation_number\", \"body\"\)/
113
+ gwo_start("gwo_id", ["body",:content,"footer"], :conditions => false).should_not =~ /utmx\(\"variation_number\", \"content\"\)/
114
+ gwo_start("gwo_id", ["body",:content,"footer"], :conditions => false).should_not =~ /utmx\(\"variation_number\", \"footer\"\)/
115
+ end
116
+ end
117
+
118
+ describe "gwo_end method" do
119
+ it "should produce correct output" do
120
+ gwo_end("gwo_id", "gwo_uacct", :conditions => true).should =~ /getTracker\(\"gwo_uacct\"\)/
121
+ gwo_end("gwo_id", "gwo_uacct", :conditions => true).should =~ /trackPageview\(\"\/gwo_id\/test\"\)/
122
+ end
123
+
124
+ it "should return nothing if conditions are not met" do
125
+ gwo_end("gwo_id", "gwo_uacct", {:conditions => false}).should_not =~ /getTracker\(\"gwo_uacct\"\)/
126
+ gwo_end("gwo_id", "gwo_uacct", :conditions => false).should == ""
127
+ end
128
+ end
129
+
130
+ describe "gw_conversion method" do
131
+ it "should produce correct output" do
132
+ gwo_conversion("gwo_id", "gwo_uacct").should =~ /getTracker\(\"gwo_uacct\"\)/
133
+ gwo_conversion("gwo_id", "gwo_uacct").should =~ /trackPageview\(\"\/gwo_id\/goal\"\)/
134
+ end
135
+
136
+ it "should return nothing when conditions are not met" do
137
+ gwo_conversion("gwo_id", "gwo_uacct", {:conditions => false}).should == ""
138
+ end
139
+ end
140
+
141
+ describe "gwo_section method with named sections" do
142
+
143
+ it "should return nothing when conditions are not met and the variation is not the original" do
144
+ gwo_section("gwo_section", ["foo","bar"], {:conditions => false}).should == ""
145
+ end
146
+
147
+ it "should return original output without javascript if conditions are not met and original is the variation " do
148
+ gwo_section("gwo_section", :original, {:conditions => false}) { "this is the content" }.should == "this is the content"
149
+ end
150
+
151
+ it "should return original output with javascript if ignore is unset and original is the variation " do
152
+ gwo_section("gwo_section", :original) { "this is the content" }.should =~ /this is the content/
153
+ gwo_section("gwo_section", :original) { "this is the content" }.should =~ /( GWO_gwo_section_name != \"original\" )/
154
+ end
155
+
156
+ it "should only write one javascript block if the section is used for original and variations" do
157
+ gwo_section("section", [:original, :variation1, :variation2]) { "this is the content" }.should =~ /this is the content/
158
+ gwo_section("section", [:original, :variation1, :variation2]) { "this is the content" }.should =~ /( GWO_section_name != \"original\" && GWO_section_name != \"variation1\" && GWO_section_name != \"variation2\" )/
159
+ end
160
+
161
+ it "should write block for one variant" do
162
+ gwo_section("section",:testing) { "this is the content" }.should =~ /this is the content/
163
+ gwo_section("section",:testing) { "this is the content" }.should =~ /( GWO_section_name == \"testing\" )/
164
+ end
165
+
166
+ it "should write one block but enabled for all given variants " do
167
+ gwo_section("section",[:testing, :still_testing]) { "this is the content" }.should =~ /this is the content/
168
+ gwo_section("section",[:testing, :still_testing]) { "this is the content" }.should =~ /( GWO_section_name == \"testing\" || GWO_section_name == \"still_testing\" )/
169
+ end
170
+ end
171
+
172
+ describe "gwo_section method with numbered sections" do
173
+
174
+ it "should return nothing when conditions are not met and the variation is not the original" do
175
+ gwo_section("gwo_section", [1, 2], {:conditions => false}).should == ""
176
+ end
177
+
178
+ it "should return original output without javascript if conditions are not met and original is the variation " do
179
+ gwo_section("gwo_section", 0, {:conditions => false}) { "this is the content" }.should == "this is the content"
180
+ end
181
+
182
+ it "should return original output with javascript if ignore is unset and original is the variation " do
183
+ gwo_section("gwo_section", 0) { "this is the content" }.should =~ /this is the content/
184
+ gwo_section("gwo_section", 0) { "this is the content" }.should =~ /( GWO_gwo_section_number != 0 )/
185
+ end
186
+
187
+ it "should only write one javascript block if the section is used for original and variations" do
188
+ gwo_section("section", [0, 1, 2]) { "this is the content" }.should =~ /this is the content/
189
+ gwo_section("section", [0, 1, 2]) { "this is the content" }.should =~ /( GWO_section_number != 0 && GWO_section_number != 1 && GWO_section_number != 2 )/
190
+ end
191
+
192
+ it "should write block for one variant" do
193
+ gwo_section("section",1) { "this is the content" }.should =~ /this is the content/
194
+ gwo_section("section",1) { "this is the content" }.should =~ /( GWO_section_number == 1 )/
195
+ end
196
+
197
+ it "should write one block but enabled for all given variants " do
198
+ gwo_section("section",[1, 2]) { "this is the content" }.should =~ /this is the content/
199
+ gwo_section("section",[1, 2]) { "this is the content" }.should =~ /( GWO_section_number == 1 || GWO_section_number == 2 )/
200
+ end
201
+ end
202
+
203
+ end
@@ -0,0 +1,4 @@
1
+ # This file is copied to ~/spec when you run 'ruby script/generate rspec'
2
+ # from the project root directory.
3
+ require 'spec'
4
+ RAILS_ENV="test"
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: moviepilot-gwo
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.1"
5
+ platform: ruby
6
+ authors:
7
+ - Alex MacCaw
8
+ - Daniel Bornkessel
9
+ - Johannes Mentz
10
+ - Yan Minagawa
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+
15
+ date: 2009-09-11 00:00:00 -07:00
16
+ default_executable:
17
+ dependencies: []
18
+
19
+ description:
20
+ email: daniel@bornkessel.com
21
+ executables: []
22
+
23
+ extensions: []
24
+
25
+ extra_rdoc_files:
26
+ - README.markdown
27
+ files:
28
+ - lib/gwo.rb
29
+ - MIT-LICENSE
30
+ - README.markdown
31
+ - spec/lib/gwo_spec.rb
32
+ - spec/spec_helper.rb
33
+ - rails/init.rb
34
+ has_rdoc: true
35
+ homepage: http://github.com/kesselborn/gwo
36
+ licenses:
37
+ post_install_message:
38
+ rdoc_options:
39
+ - --line-numbers
40
+ - --inline-source
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: "0"
48
+ version:
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ requirements: []
56
+
57
+ rubyforge_project:
58
+ rubygems_version: 1.3.5
59
+ signing_key:
60
+ specification_version: 2
61
+ summary: Plugin to easily make use of Server-Side Dynamic Section Variations with Google Web Optimizer
62
+ test_files: []
63
+