remarkable 3.1.8 → 3.1.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.
- data/CHANGELOG +58 -58
- data/LICENSE +20 -20
- data/README +197 -197
- data/lib/remarkable.rb +18 -18
- data/lib/remarkable/base.rb +55 -56
- data/lib/remarkable/core_ext/array.rb +19 -19
- data/lib/remarkable/dsl.rb +35 -35
- data/lib/remarkable/dsl/assertions.rb +384 -384
- data/lib/remarkable/dsl/callbacks.rb +52 -52
- data/lib/remarkable/dsl/optionals.rb +122 -122
- data/lib/remarkable/i18n.rb +53 -53
- data/lib/remarkable/macros.rb +48 -48
- data/lib/remarkable/matchers.rb +17 -17
- data/lib/remarkable/messages.rb +103 -103
- data/lib/remarkable/pending.rb +66 -66
- data/lib/remarkable/rspec.rb +24 -24
- data/lib/remarkable/version.rb +3 -3
- data/locale/en.yml +14 -14
- data/spec/base_spec.rb +41 -41
- data/spec/dsl/assertions_spec.rb +54 -54
- data/spec/dsl/optionals_spec.rb +237 -237
- data/spec/i18n_spec.rb +41 -41
- data/spec/locale/en.yml +20 -20
- data/spec/locale/pt-BR.yml +21 -21
- data/spec/macros_spec.rb +26 -26
- data/spec/matchers/be_a_person_matcher.rb +25 -25
- data/spec/matchers/collection_contain_matcher.rb +32 -32
- data/spec/matchers/contain_matcher.rb +31 -31
- data/spec/matchers/single_contain_matcher.rb +49 -49
- data/spec/matchers_spec.rb +5 -5
- data/spec/messages_spec.rb +66 -66
- data/spec/pending_spec.rb +7 -7
- data/spec/spec.opts +4 -4
- data/spec/spec_helper.rb +15 -15
- metadata +3 -3
@@ -1,13 +1,13 @@
|
|
1
|
-
module Remarkable
|
2
|
-
module DSL
|
3
|
-
module Callbacks
|
4
|
-
|
5
|
-
def self.included(base) #:nodoc:
|
6
|
-
base.extend ClassMethods
|
7
|
-
end
|
8
|
-
|
9
|
-
module ClassMethods
|
10
|
-
protected
|
1
|
+
module Remarkable
|
2
|
+
module DSL
|
3
|
+
module Callbacks
|
4
|
+
|
5
|
+
def self.included(base) #:nodoc:
|
6
|
+
base.extend ClassMethods
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
protected
|
11
11
|
# Class method that accepts a block or a symbol which is called after
|
12
12
|
# initialization.
|
13
13
|
#
|
@@ -18,15 +18,15 @@ module Remarkable
|
|
18
18
|
# after_initialize do
|
19
19
|
# # code
|
20
20
|
# end
|
21
|
-
#
|
22
|
-
def after_initialize(*symbols, &block)
|
23
|
-
if block_given?
|
24
|
-
@after_initialize_callbacks << block
|
25
|
-
else
|
26
|
-
@after_initialize_callbacks += symbols
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
21
|
+
#
|
22
|
+
def after_initialize(*symbols, &block)
|
23
|
+
if block_given?
|
24
|
+
@after_initialize_callbacks << block
|
25
|
+
else
|
26
|
+
@after_initialize_callbacks += symbols
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
30
|
# Class method that accepts a block or a symbol which is called before
|
31
31
|
# running assertions.
|
32
32
|
#
|
@@ -37,36 +37,36 @@ module Remarkable
|
|
37
37
|
# before_assert do
|
38
38
|
# # code
|
39
39
|
# end
|
40
|
-
#
|
41
|
-
def before_assert(*symbols, &block)
|
42
|
-
if block_given?
|
43
|
-
@before_assert_callbacks << block
|
44
|
-
else
|
45
|
-
@before_assert_callbacks += symbols
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def run_after_initialize_callbacks #:nodoc:
|
51
|
-
self.class.after_initialize_callbacks.each do |method|
|
52
|
-
if method.is_a?(Proc)
|
53
|
-
instance_eval &method
|
54
|
-
elsif method.is_a?(Symbol)
|
55
|
-
send(method)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def run_before_assert_callbacks #:nodoc:
|
61
|
-
self.class.before_assert_callbacks.each do |method|
|
62
|
-
if method.is_a?(Proc)
|
63
|
-
instance_eval &method
|
64
|
-
elsif method.is_a?(Symbol)
|
65
|
-
send(method)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
40
|
+
#
|
41
|
+
def before_assert(*symbols, &block)
|
42
|
+
if block_given?
|
43
|
+
@before_assert_callbacks << block
|
44
|
+
else
|
45
|
+
@before_assert_callbacks += symbols
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def run_after_initialize_callbacks #:nodoc:
|
51
|
+
self.class.after_initialize_callbacks.each do |method|
|
52
|
+
if method.is_a?(Proc)
|
53
|
+
instance_eval &method
|
54
|
+
elsif method.is_a?(Symbol)
|
55
|
+
send(method)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def run_before_assert_callbacks #:nodoc:
|
61
|
+
self.class.before_assert_callbacks.each do |method|
|
62
|
+
if method.is_a?(Proc)
|
63
|
+
instance_eval &method
|
64
|
+
elsif method.is_a?(Symbol)
|
65
|
+
send(method)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -1,13 +1,13 @@
|
|
1
|
-
module Remarkable
|
1
|
+
module Remarkable
|
2
2
|
module DSL
|
3
3
|
# This module is responsable for create optional handlers and providing macro
|
4
4
|
# configration blocks. Consider the matcher below:
|
5
5
|
#
|
6
|
-
# class AllowValuesForMatcher < Remarkable::ActiveRecord::Base
|
7
|
-
# arguments :collection => :attributes, :as => :attribute
|
8
|
-
#
|
6
|
+
# class AllowValuesForMatcher < Remarkable::ActiveRecord::Base
|
7
|
+
# arguments :collection => :attributes, :as => :attribute
|
8
|
+
#
|
9
9
|
# optional :message
|
10
|
-
# optional :in, :splat => true
|
10
|
+
# optional :in, :splat => true
|
11
11
|
# optional :allow_nil, :allow_blank, :default => true
|
12
12
|
# end
|
13
13
|
#
|
@@ -44,31 +44,31 @@ module Remarkable
|
|
44
44
|
#
|
45
45
|
# == I18n
|
46
46
|
#
|
47
|
-
# Optionals will be included in description messages if you assign them
|
48
|
-
# properly on your locale file. If you have a validate_uniqueness_of
|
49
|
-
# matcher with the following on your locale file:
|
50
|
-
#
|
51
|
-
# description: validate uniqueness of {{attributes}}
|
52
|
-
# optionals:
|
53
|
-
# scope:
|
54
|
-
# positive: scoped to {{inspect}}
|
55
|
-
# case_sensitive:
|
56
|
-
# positive: case sensitive
|
57
|
-
# negative: case insensitive
|
58
|
-
#
|
59
|
-
# When invoked like below will generate the following messages:
|
60
|
-
#
|
61
|
-
# validate_uniqueness_of :project_id, :scope => :company_id
|
62
|
-
# #=> "validate uniqueness of project_id scoped to :company_id"
|
63
|
-
#
|
64
|
-
# validate_uniqueness_of :project_id, :scope => :company_id, :case_sensitive => true
|
65
|
-
# #=> "validate uniqueness of project_id scoped to :company_id and case sensitive"
|
66
|
-
#
|
67
|
-
# validate_uniqueness_of :project_id, :scope => :company_id, :case_sensitive => false
|
68
|
-
# #=> "validate uniqueness of project_id scoped to :company_id and case insensitive"
|
47
|
+
# Optionals will be included in description messages if you assign them
|
48
|
+
# properly on your locale file. If you have a validate_uniqueness_of
|
49
|
+
# matcher with the following on your locale file:
|
50
|
+
#
|
51
|
+
# description: validate uniqueness of {{attributes}}
|
52
|
+
# optionals:
|
53
|
+
# scope:
|
54
|
+
# positive: scoped to {{inspect}}
|
55
|
+
# case_sensitive:
|
56
|
+
# positive: case sensitive
|
57
|
+
# negative: case insensitive
|
58
|
+
#
|
59
|
+
# When invoked like below will generate the following messages:
|
60
|
+
#
|
61
|
+
# validate_uniqueness_of :project_id, :scope => :company_id
|
62
|
+
# #=> "validate uniqueness of project_id scoped to :company_id"
|
63
|
+
#
|
64
|
+
# validate_uniqueness_of :project_id, :scope => :company_id, :case_sensitive => true
|
65
|
+
# #=> "validate uniqueness of project_id scoped to :company_id and case sensitive"
|
66
|
+
#
|
67
|
+
# validate_uniqueness_of :project_id, :scope => :company_id, :case_sensitive => false
|
68
|
+
# #=> "validate uniqueness of project_id scoped to :company_id and case insensitive"
|
69
69
|
#
|
70
70
|
# == Interpolation options
|
71
|
-
#
|
71
|
+
#
|
72
72
|
# The default interpolation options available are "inspect" and "value". Whenever
|
73
73
|
# you use :splat => true, it also adds a new interpolation option called {{sentence}}.
|
74
74
|
#
|
@@ -87,50 +87,50 @@ module Remarkable
|
|
87
87
|
#
|
88
88
|
# positive: scoped to {{value}}
|
89
89
|
# # Outputs: "validate uniqueness of project_id scoped to company_id and project_id"
|
90
|
-
#
|
91
|
-
# == Interpolation keys
|
90
|
+
#
|
91
|
+
# == Interpolation keys
|
92
92
|
#
|
93
93
|
# Three keys are available to be used in I18n files and control how optionals
|
94
|
-
# are appended to your description:
|
95
|
-
#
|
96
|
-
# * <tt>positive</tt> - When the optional is given and it evaluates to true (everything but false and nil).
|
97
|
-
# * <tt>negative</tt> - When the optional is given and it evaluates to false (false or nil).
|
98
|
-
# * <tt>not_given</tt> - When the optional is not given.
|
99
|
-
#
|
100
|
-
module Optionals
|
101
|
-
|
102
|
-
OPTIONAL_KEYS = [ :positive, :negative, :not_given ]
|
103
|
-
|
104
|
-
def self.included(base) #:nodoc:
|
105
|
-
base.extend ClassMethods
|
106
|
-
end
|
107
|
-
|
108
|
-
module ClassMethods
|
109
|
-
|
110
|
-
protected
|
111
|
-
|
112
|
-
# Creates optional handlers for matchers dynamically.
|
113
|
-
#
|
114
|
-
# == Options
|
115
|
-
#
|
116
|
-
# * <tt>:default</tt> - The default value for this optional
|
117
|
-
# * <tt>:alias</tt> - An alias for this optional
|
94
|
+
# are appended to your description:
|
95
|
+
#
|
96
|
+
# * <tt>positive</tt> - When the optional is given and it evaluates to true (everything but false and nil).
|
97
|
+
# * <tt>negative</tt> - When the optional is given and it evaluates to false (false or nil).
|
98
|
+
# * <tt>not_given</tt> - When the optional is not given.
|
99
|
+
#
|
100
|
+
module Optionals
|
101
|
+
|
102
|
+
OPTIONAL_KEYS = [ :positive, :negative, :not_given ]
|
103
|
+
|
104
|
+
def self.included(base) #:nodoc:
|
105
|
+
base.extend ClassMethods
|
106
|
+
end
|
107
|
+
|
108
|
+
module ClassMethods
|
109
|
+
|
110
|
+
protected
|
111
|
+
|
112
|
+
# Creates optional handlers for matchers dynamically.
|
113
|
+
#
|
114
|
+
# == Options
|
115
|
+
#
|
116
|
+
# * <tt>:default</tt> - The default value for this optional
|
117
|
+
# * <tt>:alias</tt> - An alias for this optional
|
118
118
|
# * <tt>:splat</tt> - Should be true if you expects multiple arguments
|
119
|
-
# * <tt>:block</tt> - Tell this optional can also receive blocks
|
120
|
-
#
|
121
|
-
# == Examples
|
122
|
-
#
|
123
|
-
# class AllowValuesForMatcher < Remarkable::ActiveRecord::Base
|
124
|
-
# arguments :collection => :attributes, :as => :attribute
|
125
|
-
#
|
119
|
+
# * <tt>:block</tt> - Tell this optional can also receive blocks
|
120
|
+
#
|
121
|
+
# == Examples
|
122
|
+
#
|
123
|
+
# class AllowValuesForMatcher < Remarkable::ActiveRecord::Base
|
124
|
+
# arguments :collection => :attributes, :as => :attribute
|
125
|
+
#
|
126
126
|
# optional :message
|
127
|
-
# optional :in, :splat => true
|
127
|
+
# optional :in, :splat => true
|
128
128
|
# optional :allow_nil, :allow_blank, :default => true
|
129
129
|
# end
|
130
|
-
#
|
131
|
-
def optionals(*names)
|
130
|
+
#
|
131
|
+
def optionals(*names)
|
132
132
|
options = names.extract_options!
|
133
|
-
|
133
|
+
|
134
134
|
@matcher_optionals += names
|
135
135
|
default = options[:default] ? "=#{options[:default].inspect}" : nil
|
136
136
|
|
@@ -140,71 +140,71 @@ module Remarkable
|
|
140
140
|
', &block'
|
141
141
|
else
|
142
142
|
nil
|
143
|
-
end
|
144
|
-
|
143
|
+
end
|
144
|
+
|
145
145
|
splat = if options[:splat]
|
146
146
|
@matcher_optionals_splat += names
|
147
147
|
'*'
|
148
148
|
else
|
149
149
|
nil
|
150
150
|
end
|
151
|
-
|
152
|
-
names.each do |name|
|
153
|
-
class_eval <<-END, __FILE__, __LINE__
|
154
|
-
def #{name}(#{splat}value#{default}#{block})
|
151
|
+
|
152
|
+
names.each do |name|
|
153
|
+
class_eval <<-END, __FILE__, __LINE__
|
154
|
+
def #{name}(#{splat}value#{default}#{block})
|
155
155
|
@options ||= {}
|
156
|
-
#{"@options[:#{name}] ||= []" if splat}
|
157
|
-
@options[:#{name}] #{:+ if splat}= #{"block ||" if block} value
|
158
|
-
self
|
156
|
+
#{"@options[:#{name}] ||= []" if splat}
|
157
|
+
@options[:#{name}] #{:+ if splat}= #{"block ||" if block} value
|
158
|
+
self
|
159
159
|
end
|
160
160
|
def #{name}=(value)
|
161
161
|
@options ||= {}
|
162
|
-
@options[:#{name}] = value
|
162
|
+
@options[:#{name}] = value
|
163
163
|
self
|
164
|
-
end
|
165
|
-
END
|
164
|
+
end
|
165
|
+
END
|
166
166
|
end
|
167
|
-
|
167
|
+
|
168
168
|
class_eval %{
|
169
169
|
alias :#{options[:alias]} :#{names.last}
|
170
170
|
alias :#{options[:alias]}= :#{names.last}=
|
171
|
-
} if options[:alias]
|
172
|
-
|
173
|
-
# Call unique to avoid duplicate optionals.
|
174
|
-
@matcher_optionals.uniq!
|
175
|
-
end
|
176
|
-
alias :optional :optionals
|
177
|
-
|
178
|
-
# Instead of appending, prepend optionals to the beginning of optionals
|
171
|
+
} if options[:alias]
|
172
|
+
|
173
|
+
# Call unique to avoid duplicate optionals.
|
174
|
+
@matcher_optionals.uniq!
|
175
|
+
end
|
176
|
+
alias :optional :optionals
|
177
|
+
|
178
|
+
# Instead of appending, prepend optionals to the beginning of optionals
|
179
179
|
# array. This is important because the optionals declaration order
|
180
|
-
# changes how the description message is generated.
|
181
|
-
#
|
182
|
-
def prepend_optionals(*names)
|
183
|
-
current_optionals = @matcher_optionals.dup
|
184
|
-
@matcher_optionals = []
|
185
|
-
optional(*names)
|
186
|
-
@matcher_optionals += current_optionals
|
187
|
-
@matcher_optionals.uniq!
|
188
|
-
end
|
189
|
-
alias :prepend_optional :prepend_optionals
|
190
|
-
|
191
|
-
end
|
192
|
-
|
193
|
-
# Overwrites description to support optionals. Check <tt>optional</tt> for
|
194
|
-
# more information.
|
195
|
-
#
|
196
|
-
def description(options={}) #:nodoc:
|
197
|
-
message = super(options)
|
198
|
-
message.strip!
|
199
|
-
|
200
|
-
optionals = self.class.matcher_optionals.map do |optional|
|
201
|
-
if @options.key?(optional)
|
180
|
+
# changes how the description message is generated.
|
181
|
+
#
|
182
|
+
def prepend_optionals(*names)
|
183
|
+
current_optionals = @matcher_optionals.dup
|
184
|
+
@matcher_optionals = []
|
185
|
+
optional(*names)
|
186
|
+
@matcher_optionals += current_optionals
|
187
|
+
@matcher_optionals.uniq!
|
188
|
+
end
|
189
|
+
alias :prepend_optional :prepend_optionals
|
190
|
+
|
191
|
+
end
|
192
|
+
|
193
|
+
# Overwrites description to support optionals. Check <tt>optional</tt> for
|
194
|
+
# more information.
|
195
|
+
#
|
196
|
+
def description(options={}) #:nodoc:
|
197
|
+
message = super(options)
|
198
|
+
message.strip!
|
199
|
+
|
200
|
+
optionals = self.class.matcher_optionals.map do |optional|
|
201
|
+
if @options.key?(optional)
|
202
202
|
value = @options[optional]
|
203
|
-
|
203
|
+
|
204
204
|
defaults = [ (value ? :positive : :negative) ]
|
205
|
-
# If optional is a symbol and it's not any to any of the reserved symbols, search for it also
|
205
|
+
# If optional is a symbol and it's not any to any of the reserved symbols, search for it also
|
206
206
|
defaults.unshift(value) if value.is_a?(Symbol) && !OPTIONAL_KEYS.include?(value)
|
207
|
-
defaults << ''
|
207
|
+
defaults << ''
|
208
208
|
|
209
209
|
options = { :default => defaults, :inspect => value.inspect, :value => value.to_s }
|
210
210
|
|
@@ -216,12 +216,12 @@ module Remarkable
|
|
216
216
|
translate_optionals_with_namespace(optional, defaults.shift, options)
|
217
217
|
else
|
218
218
|
translate_optionals_with_namespace(optional, :not_given, :default => '')
|
219
|
-
end
|
220
|
-
end.compact
|
221
|
-
|
222
|
-
message << ' ' << array_to_sentence(optionals)
|
223
|
-
message.strip!
|
224
|
-
message
|
219
|
+
end
|
220
|
+
end.compact
|
221
|
+
|
222
|
+
message << ' ' << array_to_sentence(optionals)
|
223
|
+
message.strip!
|
224
|
+
message
|
225
225
|
end
|
226
226
|
|
227
227
|
def translate_optionals_with_namespace(optional, key, options={}) #:nodoc:
|
@@ -236,8 +236,8 @@ module Remarkable
|
|
236
236
|
return translation unless translation.empty?
|
237
237
|
|
238
238
|
nil
|
239
|
-
end
|
240
|
-
|
241
|
-
end
|
242
|
-
end
|
243
|
-
end
|
239
|
+
end
|
240
|
+
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
data/lib/remarkable/i18n.rb
CHANGED
@@ -4,74 +4,74 @@ module Remarkable
|
|
4
4
|
# Remarkable shouldn't rely on I18n default locale, because it might change
|
5
5
|
# throughout tests. So it's Remarkable responsibility to hold its own locale
|
6
6
|
# and send it to I18n.
|
7
|
-
#
|
8
|
-
module I18n
|
9
|
-
|
7
|
+
#
|
8
|
+
module I18n
|
9
|
+
|
10
10
|
# Add locale files to I18n and to load path, if it exists.
|
11
11
|
#
|
12
12
|
# == Examples
|
13
13
|
#
|
14
14
|
# Remarkable.add_locale "path/to/locale"
|
15
|
-
#
|
16
|
-
def add_locale(*locales)
|
17
|
-
::I18n.backend.load_translations *locales
|
18
|
-
::I18n.load_path += locales if ::I18n.respond_to?(:load_path)
|
19
|
-
end
|
20
|
-
|
15
|
+
#
|
16
|
+
def add_locale(*locales)
|
17
|
+
::I18n.backend.load_translations *locales
|
18
|
+
::I18n.load_path += locales if ::I18n.respond_to?(:load_path)
|
19
|
+
end
|
20
|
+
|
21
21
|
# Set Remarkable own locale.
|
22
22
|
#
|
23
23
|
# == Examples
|
24
24
|
#
|
25
25
|
# Remarkable.locale = :en
|
26
|
-
#
|
27
|
-
def locale=(locale)
|
28
|
-
@@locale = locale
|
29
|
-
end
|
30
|
-
|
26
|
+
#
|
27
|
+
def locale=(locale)
|
28
|
+
@@locale = locale
|
29
|
+
end
|
30
|
+
|
31
31
|
# Get Remarkable own locale.
|
32
32
|
#
|
33
33
|
# == Examples
|
34
34
|
#
|
35
35
|
# Remarkable.locale = :en
|
36
36
|
# Remarkable.locale #=> :en
|
37
|
-
#
|
38
|
-
def locale
|
39
|
-
@@locale
|
40
|
-
end
|
41
|
-
|
37
|
+
#
|
38
|
+
def locale
|
39
|
+
@@locale
|
40
|
+
end
|
41
|
+
|
42
42
|
# Wrapper for I18n.translate
|
43
|
-
#
|
44
|
-
def translate(string, options = {})
|
45
|
-
::I18n.translate string, { :locale => @@locale }.merge(options)
|
46
|
-
end
|
47
|
-
alias :t :translate
|
48
|
-
|
43
|
+
#
|
44
|
+
def translate(string, options = {})
|
45
|
+
::I18n.translate string, { :locale => @@locale }.merge(options)
|
46
|
+
end
|
47
|
+
alias :t :translate
|
48
|
+
|
49
49
|
# Wrapper for I18n.localize
|
50
|
-
#
|
51
|
-
def localize(object, options = {})
|
52
|
-
::I18n.localize object, { :locale => @@locale }.merge(options)
|
53
|
-
end
|
54
|
-
alias :l :localize
|
55
|
-
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
# Load I18n
|
60
|
-
RAILS_I18N = Object.const_defined?(:I18n) unless Object.const_defined?(:RAILS_I18N) # Rails >= 2.2
|
61
|
-
|
62
|
-
unless RAILS_I18N
|
63
|
-
begin
|
64
|
-
require 'i18n'
|
65
|
-
rescue LoadError
|
66
|
-
require 'rubygems'
|
67
|
-
# TODO Move to i18n gem as soon as it gets updated
|
68
|
-
gem 'svenfuchs-i18n'
|
69
|
-
require 'i18n'
|
70
|
-
end
|
71
|
-
|
72
|
-
# Set default locale
|
73
|
-
::I18n.default_locale = :en
|
74
|
-
end
|
75
|
-
|
76
|
-
Remarkable.extend Remarkable::I18n
|
77
|
-
Remarkable.locale = :en
|
50
|
+
#
|
51
|
+
def localize(object, options = {})
|
52
|
+
::I18n.localize object, { :locale => @@locale }.merge(options)
|
53
|
+
end
|
54
|
+
alias :l :localize
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Load I18n
|
60
|
+
RAILS_I18N = Object.const_defined?(:I18n) unless Object.const_defined?(:RAILS_I18N) # Rails >= 2.2
|
61
|
+
|
62
|
+
unless RAILS_I18N
|
63
|
+
begin
|
64
|
+
require 'i18n'
|
65
|
+
rescue LoadError
|
66
|
+
require 'rubygems'
|
67
|
+
# TODO Move to i18n gem as soon as it gets updated
|
68
|
+
gem 'svenfuchs-i18n'
|
69
|
+
require 'i18n'
|
70
|
+
end
|
71
|
+
|
72
|
+
# Set default locale
|
73
|
+
::I18n.default_locale = :en
|
74
|
+
end
|
75
|
+
|
76
|
+
Remarkable.extend Remarkable::I18n
|
77
|
+
Remarkable.locale = :en
|