1
- require 'action_controller'
1
+ require 'split_tester/railtie'
2
+ require 'split_tester/controller'
3
+ require 'split_tester/translation_helper'
4
+ require 'split_tester/caching'
2
5
3
- module ActionController #:nodoc:
6
+ module SplitTester
4
7
class Base
5
-
6
- SPLIT_TESTS = YAML . load_file ( "#{ RAILS_ROOT } /config/split_tests.yml" )
7
-
8
- class << self
9
- def custom_view_path ( name )
10
- name == "views" ? "app/views" : "test/split/#{ name } /views"
11
- end
12
-
13
- def self . random_test_key
14
- split_test_map . sample
8
+ # Doesn't have access to Rails.root here
9
+ SPLIT_TESTS = YAML . load_file ( "config/split_tests.yml" )
10
+
11
+ def self . setup
12
+ # Add the split test language files to the load path
13
+ I18n . load_path += Dir [ Rails . root . join ( 'test' , 'split' , '*' , 'locale.{rb,yml}' ) ]
14
+
15
+ @@preprocessed_pathsets = begin
16
+ SPLIT_TESTS . keys . reject { |k | k == 'BASELINE' } . inject ( { } ) do |pathsets , slug |
17
+ path = custom_view_path ( slug )
18
+ pathsets [ path ] = ActionView ::Base . process_view_paths ( path ) . first
19
+ pathsets
20
+ end
15
21
end
16
- end
17
22
18
- before_filter :setup_split_testing
19
-
20
- # preprocess some pathsets on boot
21
- # doing pathset generation during a request is very costly
22
- @@preprocessed_pathsets = begin
23
- SPLIT_TESTS . keys . reject { |k | k == 'BASELINE' } . inject ( { } ) do |pathsets , slug |
24
- path = ActionController ::Base . custom_view_path ( slug )
25
- pathsets [ path ] = ActionView ::Base . process_view_paths ( path ) . first
26
- pathsets
23
+ @@split_test_map = begin
24
+ tm = { } # test map
25
+ SPLIT_TESTS . each { |k , v | tm [ k ] = v [ 'size' ] . to_i }
26
+ tm . keys . zip ( tm . values ) . collect { |v , d | ( 0 ...d ) . collect { v } } . flatten
27
27
end
28
28
end
29
29
30
- @@split_test_map = begin
31
- tm = { } # test map
32
- SPLIT_TESTS . each { |k , v | tm [ k ] = v [ 'size' ] . to_i }
33
- tm . keys . zip ( tm . values ) . collect { |v , d | ( 0 ...d ) . collect { v } } . flatten
30
+ def self . split_test_map
31
+ @@split_test_map
34
32
end
35
33
36
- cattr_accessor :preprocessed_pathsets , :split_test_map
37
-
38
- # If a split_test_key other than BASELINE exists, add the proper
39
- # view path to the load paths used by ActionView
40
- def setup_split_testing
41
- return unless is_split_test?
42
- split_test_path = preprocessed_pathsets [ ActionController ::Base . custom_view_path ( @split_test_key ) ]
43
- prepend_view_path ( split_test_path ) if split_test_path
44
- end
45
-
46
- # Get the existing split_test_key from the session or the cookie.
47
- # If there isn't one, or if the one isn't a running test anymore
48
- # assign the user a new key and store it.
49
- # Don't assign a key if it is a crawler. (This doesn't feel right)
50
- def get_split_test_key
51
- return params [ :force_test_key ] if params [ :force_test_key ] # just for testing
52
- return session [ :split_test_key ] if session [ :split_test_key ] && SPLIT_TESTS . has_key? ( session [ :split_test_key ] )
53
- return session [ :split_test_key ] = cookies [ :split_test_key ] if cookies [ :split_test_key ] && SPLIT_TESTS . has_key? ( cookies [ :split_test_key ] )
54
- if ( request . user_agent =~ /\b (Baidu|Gigabot|Googlebot|libwww-perl|lwp-trivial|msnbot|SiteUptime|Slurp|WordPress|ZIBB|ZyBorg)\b /i )
55
- session [ :split_test_key ] = nil
56
- else
57
- session [ :split_test_key ] = ActionController ::Base . random_test_key
58
- cookies [ :split_test_key ] = session [ :split_test_key ]
59
- end
60
- return session [ :split_test_key ]
34
+ def self . preprocessed_pathsets
35
+ @@preprocessed_pathsets
61
36
end
62
37
63
- def current_split_test_key
64
- @split_test_key ||= get_split_test_key
38
+ def self . custom_view_path ( name )
39
+ name == "views" ? "app/views" : "test/split/ #{ name } /views"
65
40
end
66
41
67
- def is_split_test?
68
- current_split_test_key && current_split_test_key != 'BASELINE'
42
+ def self . active_test? ( key )
43
+ SPLIT_TESTS . has_key? ( key )
69
44
end
70
45
71
- helper_method :is_split_test? , :current_split_test_key
72
- end
73
- end
74
-
75
- # Change the namespace for caching if the current request
76
- # is a split test so that caches don't get mixed together
77
- module ActionController #:nodoc:
78
- module Caching
79
- module Fragments
80
- def fragment_cache_key ( key )
81
- namespace = is_split_test? ? "views-split-#{ current_split_test_key } " : :views
82
- ActiveSupport ::Cache . expand_cache_key ( key . is_a? ( Hash ) ? url_for ( key ) . split ( "://" ) . last : key , namespace )
83
- end
46
+ def self . view_path ( key )
47
+ preprocessed_pathsets [ custom_view_path ( key ) ]
84
48
end
85
- end
86
- end
87
-
88
- # Overwrite the translate method so that it tries the bucket translation first
89
- # TODO: There is probably a better way to write this
90
- module ActionView
91
- module Helpers
92
- module TranslationHelper
93
- def translate ( key , options = { } )
94
- key = scope_key_by_partial ( key )
95
- if is_split_test?
96
- # normalize the parameters so that we can add in
97
- # the current_split_test_key properly
98
- scope = options . delete ( :scope )
99
- keys = I18n . normalize_keys ( I18n . locale , key , scope )
100
- keys . shift
101
- key = keys . join ( '.' )
102
49
103
- # Set the standard key as a default to fall back on automatically
104
- if options [ :default ]
105
- options [ :default ] = [ options [ :default ] ] unless options [ :default ] . is_a? ( Array )
106
- options [ :default ] . unshift ( key . to_sym )
107
- else
108
- options [ :default ] = [ key . to_sym ]
109
- end
110
-
111
- key = "#{ current_split_test_key } .#{ key } "
112
- end
113
- translation = I18n . translate ( key , options . merge! ( :raise => true ) )
114
- if html_safe_translation_key? ( key ) && translation . respond_to? ( :html_safe )
115
- translation . html_safe
116
- else
117
- translation
118
- end
119
- rescue I18n ::MissingTranslationData => e
120
- keys = I18n . normalize_keys ( e . locale , e . key , e . options [ :scope ] )
121
- content_tag ( 'span' , keys . join ( ', ' ) , :class => 'translation_missing' )
122
- end
123
- alias t translate
50
+ def self . random_test_key
51
+ split_test_map . sample
124
52
end
125
53
end
126
- end
127
-
128
- # Add the split test language files to the load path
129
- I18n . load_path += Dir [ Rails . root . join ( 'test' , 'split' , '*' , 'locale.{rb,yml}' ) ]
54
+ end
0 commit comments