rack-track 0.1.0

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.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source "http://rubygems.org"
2
+ gem "rack"
3
+
4
+ group :development do
5
+ gem "bundler", "~> 1.0.0"
6
+ gem "jeweler", "~> 1.6.4"
7
+ gem "rcov", ">= 0"
8
+ gem "rack-test"
9
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,23 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ git (1.2.5)
5
+ jeweler (1.6.4)
6
+ bundler (~> 1.0)
7
+ git (>= 1.2.5)
8
+ rake
9
+ rack (1.3.2)
10
+ rack-test (0.5.7)
11
+ rack (>= 1.0)
12
+ rake (0.9.2)
13
+ rcov (0.9.9)
14
+
15
+ PLATFORMS
16
+ ruby
17
+
18
+ DEPENDENCIES
19
+ bundler (~> 1.0.0)
20
+ jeweler (~> 1.6.4)
21
+ rack
22
+ rack-test
23
+ rcov
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Michael Baldry
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,33 @@
1
+ # Rack::Track
2
+
3
+ On too many projects I've worked on, nobody actually know every tracking pixel we have, what areas/pages they appear on (or should appear on) and it
4
+ becomes a massive headache when you need to do work around them. This is where Rack::Track comes in to play, providing a DSL to define tracking pixels
5
+ and the areas they should appear on. It's all in one place, instead of across layouts and pages and it's self documenting.
6
+
7
+ ```ruby
8
+ MyApp::Application.config.middleware.use(Rack::Track) do
9
+ area :confirmation_pages, "/checkout/order_confirmation", "/basket/complete"
10
+
11
+ pixel "Generic GA", :on => :all_pages do
12
+ %Q{
13
+ <!-- GOOGLE ANALYTICS -->
14
+ blah
15
+ <!-- END GOOGLE ANALYTICS -->
16
+ }
17
+ end
18
+
19
+ pixel "Goal GA", :on => :confirmation_pages do
20
+ %Q{
21
+ <!-- GOOGLE ANALYTICS -->
22
+ blah
23
+ <!-- END GOOGLE ANALYTICS -->
24
+ }
25
+ end
26
+ end
27
+ ```
28
+ These tracking pixels will be inserted in to the page before the body tag closes. This is what most tracking pixels expect. If you require a pixel
29
+ to be placed in the head tag, or anywhere else, let me know and I'll extend it (or you could clone and submit a pull request with your changes!)
30
+
31
+ $ gem install rack-track
32
+
33
+ require "rack-track" # or "rack/track", whatever floats your boat.
data/Rakefile ADDED
@@ -0,0 +1,54 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "rack-track"
18
+ gem.version = "0.1.0"
19
+ gem.homepage = "http://github.com/michaelbaldry/rack-track"
20
+ gem.license = "MIT"
21
+ gem.summary = %Q{Taking all the pain away from managing Tracking Pixels}
22
+ gem.description = %Q{A rack middleware that allows you to define and document tracking pixels in one location}
23
+ gem.email = "clockwize@gmail.com"
24
+ gem.authors = ["Michael Baldry"]
25
+ # dependencies defined in Gemfile
26
+ end
27
+ Jeweler::RubygemsDotOrgTasks.new
28
+
29
+ require 'rake/testtask'
30
+ Rake::TestTask.new(:test) do |test|
31
+ test.libs << 'lib' << 'test'
32
+ test.pattern = 'test/**/test_*.rb'
33
+ test.verbose = true
34
+ end
35
+
36
+ require 'rcov/rcovtask'
37
+ Rcov::RcovTask.new do |test|
38
+ test.libs << 'test'
39
+ test.pattern = 'test/**/test_*.rb'
40
+ test.verbose = true
41
+ test.rcov_opts << '--exclude "gems/*"'
42
+ end
43
+
44
+ task :default => :test
45
+
46
+ require 'rake/rdoctask'
47
+ Rake::RDocTask.new do |rdoc|
48
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
49
+
50
+ rdoc.rdoc_dir = 'rdoc'
51
+ rdoc.title = "rack-track #{version}"
52
+ rdoc.rdoc_files.include('README*')
53
+ rdoc.rdoc_files.include('lib/**/*.rb')
54
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/lib/rack/track.rb ADDED
@@ -0,0 +1,54 @@
1
+ module Rack
2
+ class Track
3
+ def initialize(app, &block)
4
+ @app = app
5
+ @rules = Rack::Track::PixelSet.new &block
6
+ end
7
+
8
+ def call(env)
9
+ request = Rack::Request.new(env)
10
+ status, headers, response = @app.call(env)
11
+
12
+ if /^text\/html/ =~ headers["Content-Type"]
13
+ response_body = ""
14
+ response.each { |p| response_body += p }
15
+ response = [@rules.apply(request, response_body)] if response_body.include? "</body>"
16
+ end
17
+
18
+ [status, headers, response]
19
+ end
20
+
21
+ def each(&block)
22
+ end
23
+
24
+ private
25
+
26
+ class PixelSet
27
+ Pixel = Struct.new(:name, :area, :content)
28
+
29
+ def initialize(&block)
30
+ @pixels = []
31
+ @areas = {}
32
+ self.instance_eval(&block) if block_given?
33
+ end
34
+
35
+ def area(id, *paths)
36
+ @areas[id] = [] unless @areas[id]
37
+ paths.each { |path| @areas[id] << path.downcase }
38
+ end
39
+
40
+ def pixel(name, opts = {}, &block)
41
+ @pixels << Pixel.new(name, opts[:on], block[])
42
+ end
43
+
44
+ def apply(request, response)
45
+ url = URI::parse(request.url)
46
+ @pixels.each do |p|
47
+ paths = @areas[p.area]
48
+ response.insert(response.rindex("</body>"), p.content) if p.area == :all || paths.include?(url.path.downcase)
49
+ end
50
+ response
51
+ end
52
+ end
53
+ end
54
+ end
data/lib/rack-track.rb ADDED
@@ -0,0 +1 @@
1
+ require "rack/track"
@@ -0,0 +1,63 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{rack-track}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = [%q{Michael Baldry}]
12
+ s.date = %q{2011-08-03}
13
+ s.description = %q{A rack middleware that allows you to define and document tracking pixels in one location}
14
+ s.email = %q{clockwize@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.markdown"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ "Gemfile",
22
+ "Gemfile.lock",
23
+ "LICENSE.txt",
24
+ "README.markdown",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "lib/rack-track.rb",
28
+ "lib/rack/track.rb",
29
+ "rack-track.gemspec",
30
+ "test/helper.rb",
31
+ "test/test_rack-track.rb"
32
+ ]
33
+ s.homepage = %q{http://github.com/michaelbaldry/rack-track}
34
+ s.licenses = [%q{MIT}]
35
+ s.require_paths = [%q{lib}]
36
+ s.rubygems_version = %q{1.8.6}
37
+ s.summary = %q{Taking all the pain away from managing Tracking Pixels}
38
+
39
+ if s.respond_to? :specification_version then
40
+ s.specification_version = 3
41
+
42
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
43
+ s.add_runtime_dependency(%q<rack>, [">= 0"])
44
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
45
+ s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
46
+ s.add_development_dependency(%q<rcov>, [">= 0"])
47
+ s.add_development_dependency(%q<rack-test>, [">= 0"])
48
+ else
49
+ s.add_dependency(%q<rack>, [">= 0"])
50
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
51
+ s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
52
+ s.add_dependency(%q<rcov>, [">= 0"])
53
+ s.add_dependency(%q<rack-test>, [">= 0"])
54
+ end
55
+ else
56
+ s.add_dependency(%q<rack>, [">= 0"])
57
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
58
+ s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
59
+ s.add_dependency(%q<rcov>, [">= 0"])
60
+ s.add_dependency(%q<rack-test>, [">= 0"])
61
+ end
62
+ end
63
+
data/test/helper.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+ require 'rack/test'
12
+
13
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
15
+ require 'rack-track'
16
+
17
+ class Test::Unit::TestCase
18
+ end
@@ -0,0 +1,107 @@
1
+ require 'helper'
2
+
3
+ class TestRackTrack < Test::Unit::TestCase
4
+ include Rack::Test::Methods
5
+
6
+ def initialize(x)
7
+ super(x)
8
+ @rules = lambda {}
9
+ @app_class = SimpleApp
10
+ end
11
+
12
+ FAIL_RULE = Proc.new do
13
+ pixel "Test pixel", :on => :all do
14
+ "FAIL"
15
+ end
16
+ end
17
+
18
+ class SimpleApp
19
+ def call(env)
20
+ [200, {'Content-Type' => "text/html"}, ["<html><head><title></title></head><body>hello this is the body</body></html>"]]
21
+ end
22
+ end
23
+
24
+ def app
25
+ Rack::Track.new(@app_class.new, &@rules)
26
+ end
27
+
28
+ def test_defining_pixels_and_areas_with_dsl
29
+ tp = Rack::Track::PixelSet.new do
30
+ area :confirmation, "business-energy/confirmation", "business-communications/confirmation"
31
+
32
+ pixel "Confirmation (GA)", :on => :confirmation do
33
+ "THIS IS A GA CONFIRMATION TEST"
34
+ end
35
+ end
36
+
37
+ assert tp.instance_variable_get(:@areas) == {:confirmation => ["business-energy/confirmation", "business-communications/confirmation"]}
38
+ assert tp.instance_variable_get(:@pixels) == [Rack::Track::PixelSet::Pixel.new("Confirmation (GA)", :confirmation, "THIS IS A GA CONFIRMATION TEST")]
39
+ end
40
+
41
+ def test_psudo_area_all
42
+ @rules = Proc.new do
43
+ pixel "Test pixel", :on => :all do
44
+ "THIS-IS-A-TEST"
45
+ end
46
+ end
47
+ get '/'
48
+ assert last_response.body.include? "THIS-IS-A-TEST</body>"
49
+ get '/poatoes'
50
+ assert last_response.body.include? "THIS-IS-A-TEST</body>"
51
+ end
52
+
53
+ def test_area_inclusion
54
+ @rules = Proc.new do
55
+ area :an_area, "/blah", "/blah/test"
56
+
57
+ pixel "Test pixel", :on => :an_area do
58
+ "THIS-IS-A-TEST"
59
+ end
60
+ end
61
+ get '/'
62
+ assert !last_response.body.include?("THIS-IS-A-TEST</body>")
63
+ get '/blah'
64
+ assert last_response.body.include? "THIS-IS-A-TEST</body>"
65
+ get '/blah/test'
66
+ assert last_response.body.include? "THIS-IS-A-TEST</body>"
67
+ end
68
+
69
+ def test_only_works_on_html_pages
70
+ @app_class = Class.new do
71
+ def call(env)
72
+ [200, {'Content-Type' => "text/css"}, ["<html><head><title></title></head><body>hello this is the body</body></html>"]]
73
+ end
74
+ end
75
+
76
+ @rules = FAIL_RULE
77
+
78
+ get '/'
79
+ assert last_response.body != "<html><head><title></title></head><body>hello this is the bodyFAIL</body></html>"
80
+ end
81
+
82
+ def test_only_works_on_html_pages_with_charset
83
+ @app_class = Class.new do
84
+ def call(env)
85
+ [200, {'Content-Type' => "text/html; charset=utf-8"}, ["<html><head><title></title></head><body>hello this is the body</body></html>"]]
86
+ end
87
+ end
88
+
89
+ @rules = FAIL_RULE
90
+
91
+ get '/'
92
+ assert last_response.body == "<html><head><title></title></head><body>hello this is the bodyFAIL</body></html>"
93
+ end
94
+
95
+ def test_only_works_on_pages_with_closing_body
96
+ @app_class = Class.new do
97
+ def call(env)
98
+ [200, {'Content-Type' => "text/html; charset=utf-8"}, ["<html><head><title></title></head><body>hello this is the body</html>"]]
99
+ end
100
+ end
101
+
102
+ @rules = FAIL_RULE
103
+
104
+ get '/'
105
+ assert last_response.body == "<html><head><title></title></head><body>hello this is the body</html>"
106
+ end
107
+ end
metadata ADDED
@@ -0,0 +1,123 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rack-track
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.0
6
+ platform: ruby
7
+ authors:
8
+ - Michael Baldry
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-08-03 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rack
17
+ requirement: &id001 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "0"
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: bundler
28
+ requirement: &id002 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 1.0.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: jeweler
39
+ requirement: &id003 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ version: 1.6.4
45
+ type: :development
46
+ prerelease: false
47
+ version_requirements: *id003
48
+ - !ruby/object:Gem::Dependency
49
+ name: rcov
50
+ requirement: &id004 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: *id004
59
+ - !ruby/object:Gem::Dependency
60
+ name: rack-test
61
+ requirement: &id005 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: "0"
67
+ type: :development
68
+ prerelease: false
69
+ version_requirements: *id005
70
+ description: A rack middleware that allows you to define and document tracking pixels in one location
71
+ email: clockwize@gmail.com
72
+ executables: []
73
+
74
+ extensions: []
75
+
76
+ extra_rdoc_files:
77
+ - LICENSE.txt
78
+ - README.markdown
79
+ files:
80
+ - .document
81
+ - Gemfile
82
+ - Gemfile.lock
83
+ - LICENSE.txt
84
+ - README.markdown
85
+ - Rakefile
86
+ - VERSION
87
+ - lib/rack-track.rb
88
+ - lib/rack/track.rb
89
+ - rack-track.gemspec
90
+ - test/helper.rb
91
+ - test/test_rack-track.rb
92
+ homepage: http://github.com/michaelbaldry/rack-track
93
+ licenses:
94
+ - MIT
95
+ post_install_message:
96
+ rdoc_options: []
97
+
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ none: false
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ hash: 3420878610649270305
106
+ segments:
107
+ - 0
108
+ version: "0"
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ none: false
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: "0"
115
+ requirements: []
116
+
117
+ rubyforge_project:
118
+ rubygems_version: 1.8.6
119
+ signing_key:
120
+ specification_version: 3
121
+ summary: Taking all the pain away from managing Tracking Pixels
122
+ test_files: []
123
+