twitter_cldr_js 2.2.0 → 2.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +7 -0
  2. data/History.txt +8 -0
  3. data/README.md +11 -1
  4. data/Rakefile +4 -5
  5. data/lib/assets/javascripts/twitter_cldr/af.js +208 -98
  6. data/lib/assets/javascripts/twitter_cldr/ar.js +208 -98
  7. data/lib/assets/javascripts/twitter_cldr/be.js +211 -101
  8. data/lib/assets/javascripts/twitter_cldr/bg.js +208 -98
  9. data/lib/assets/javascripts/twitter_cldr/bn.js +208 -98
  10. data/lib/assets/javascripts/twitter_cldr/ca.js +208 -98
  11. data/lib/assets/javascripts/twitter_cldr/cs.js +208 -98
  12. data/lib/assets/javascripts/twitter_cldr/cy.js +208 -98
  13. data/lib/assets/javascripts/twitter_cldr/da.js +208 -98
  14. data/lib/assets/javascripts/twitter_cldr/de.js +208 -98
  15. data/lib/assets/javascripts/twitter_cldr/el.js +208 -98
  16. data/lib/assets/javascripts/twitter_cldr/en-GB.js +1994 -0
  17. data/lib/assets/javascripts/twitter_cldr/en.js +206 -96
  18. data/lib/assets/javascripts/twitter_cldr/es.js +209 -98
  19. data/lib/assets/javascripts/twitter_cldr/eu.js +209 -98
  20. data/lib/assets/javascripts/twitter_cldr/fa.js +209 -98
  21. data/lib/assets/javascripts/twitter_cldr/fi.js +209 -98
  22. data/lib/assets/javascripts/twitter_cldr/fil.js +209 -98
  23. data/lib/assets/javascripts/twitter_cldr/fr.js +209 -98
  24. data/lib/assets/javascripts/twitter_cldr/ga.js +212 -101
  25. data/lib/assets/javascripts/twitter_cldr/gl.js +209 -98
  26. data/lib/assets/javascripts/twitter_cldr/he.js +209 -98
  27. data/lib/assets/javascripts/twitter_cldr/hi.js +209 -98
  28. data/lib/assets/javascripts/twitter_cldr/hr.js +209 -98
  29. data/lib/assets/javascripts/twitter_cldr/hu.js +210 -99
  30. data/lib/assets/javascripts/twitter_cldr/id.js +209 -98
  31. data/lib/assets/javascripts/twitter_cldr/is.js +209 -98
  32. data/lib/assets/javascripts/twitter_cldr/it.js +209 -98
  33. data/lib/assets/javascripts/twitter_cldr/ja.js +209 -98
  34. data/lib/assets/javascripts/twitter_cldr/ko.js +209 -98
  35. data/lib/assets/javascripts/twitter_cldr/lv.js +209 -98
  36. data/lib/assets/javascripts/twitter_cldr/msa.js +209 -98
  37. data/lib/assets/javascripts/twitter_cldr/nl.js +209 -98
  38. data/lib/assets/javascripts/twitter_cldr/no.js +209 -98
  39. data/lib/assets/javascripts/twitter_cldr/pl.js +209 -98
  40. data/lib/assets/javascripts/twitter_cldr/pt.js +209 -98
  41. data/lib/assets/javascripts/twitter_cldr/ro.js +209 -98
  42. data/lib/assets/javascripts/twitter_cldr/ru.js +209 -98
  43. data/lib/assets/javascripts/twitter_cldr/sk.js +209 -98
  44. data/lib/assets/javascripts/twitter_cldr/sq.js +212 -101
  45. data/lib/assets/javascripts/twitter_cldr/sr.js +209 -98
  46. data/lib/assets/javascripts/twitter_cldr/sv.js +209 -98
  47. data/lib/assets/javascripts/twitter_cldr/ta.js +209 -98
  48. data/lib/assets/javascripts/twitter_cldr/th.js +209 -98
  49. data/lib/assets/javascripts/twitter_cldr/tr.js +209 -98
  50. data/lib/assets/javascripts/twitter_cldr/uk.js +209 -98
  51. data/lib/assets/javascripts/twitter_cldr/ur.js +210 -99
  52. data/lib/assets/javascripts/twitter_cldr/vi.js +209 -98
  53. data/lib/assets/javascripts/twitter_cldr/zh-cn.js +209 -98
  54. data/lib/assets/javascripts/twitter_cldr/zh-tw.js +209 -98
  55. data/lib/twitter_cldr/js/compiler.rb +24 -5
  56. data/lib/twitter_cldr/js/mustache/bundle.coffee +6 -0
  57. data/lib/twitter_cldr/js/mustache/parsers/number_parser.coffee +103 -0
  58. data/lib/twitter_cldr/js/renderers/base.rb +2 -0
  59. data/lib/twitter_cldr/js/renderers/parsers/number_parser.rb +34 -0
  60. data/lib/twitter_cldr/js/renderers.rb +4 -0
  61. data/lib/twitter_cldr/js/tasks/tasks.rb +15 -3
  62. data/lib/twitter_cldr/js/version.rb +2 -2
  63. data/lib/twitter_cldr/js.rb +0 -3
  64. data/spec/js/parsers/number_parser.spec.js +211 -0
  65. data/spec/js/utilities.spec.js +0 -3
  66. data/twitter_cldr_js.gemspec +7 -6
  67. metadata +25 -47
@@ -3,8 +3,14 @@
3
3
  # Copyright 2012 Twitter, Inc
4
4
  # http://www.apache.org/licenses/LICENSE-2.0
5
5
 
6
+ require 'mustache'
7
+ require 'uglifier'
8
+ require 'coffee-script'
9
+
6
10
  module TwitterCldr
7
11
  module Js
12
+ CompiledFile = Struct.new(:source, :source_map)
13
+
8
14
  class Compiler
9
15
  attr_reader :locales
10
16
 
@@ -12,6 +18,7 @@ module TwitterCldr
12
18
  @locales = options[:locales] || TwitterCldr.supported_locales
13
19
  @features = options[:features] || renderers.keys
14
20
  @prerender = options[:prerender].nil? ? true : options[:prerender]
21
+ @source_map = options[:source_map]
15
22
  end
16
23
 
17
24
  def compile_each(options = {})
@@ -28,13 +35,24 @@ module TwitterCldr
28
35
  bundle = TwitterCldr::Js::Renderers::Bundle.new
29
36
  bundle[:locale] = locale
30
37
  bundle[:contents] = contents
31
- result = CoffeeScript.compile(bundle.render, :bare => false)
38
+ bundle[:source_map] = @source_map
39
+
40
+ result = CoffeeScript.compile(bundle.render, {
41
+ :bare => false,
42
+ :sourceMap => @source_map
43
+ })
44
+
45
+ file = if @source_map
46
+ CompiledFile.new(result["js"], result["sourceMap"])
47
+ else
48
+ CompiledFile.new(result)
49
+ end
32
50
 
33
51
  # required alias definition that adds twitter_cldr to Twitter's static build process
34
- result.gsub!(/\/\*<<module_def>>\s+\*\//, %Q(/*-module-*/\n/*_lib/twitter_cldr_*/))
35
- result = Uglifier.compile(result) if options[:minify]
52
+ file.source.gsub!(/\/\*<<module_def>>\s+\*\//, %Q(/*-module-*/\n/*_lib/twitter_cldr_*/))
53
+ file.source = Uglifier.compile(file.source) if options[:minify]
36
54
 
37
- yield result, TwitterCldr.twitter_locale(locale)
55
+ yield file, TwitterCldr.twitter_locale(locale)
38
56
  end
39
57
  end
40
58
 
@@ -50,7 +68,8 @@ module TwitterCldr
50
68
  :currencies => TwitterCldr::Js::Renderers::Shared::CurrenciesRenderer,
51
69
  :lists => TwitterCldr::Js::Renderers::Shared::ListRenderer,
52
70
  :bidi => TwitterCldr::Js::Renderers::Shared::BidiRenderer,
53
- :calendar => TwitterCldr::Js::Renderers::Shared::CalendarRenderer
71
+ :calendar => TwitterCldr::Js::Renderers::Shared::CalendarRenderer,
72
+ :number_parser => TwitterCldr::Js::Renderers::Parsers::NumberParser
54
73
  }
55
74
  end
56
75
  end
@@ -10,6 +10,12 @@
10
10
  // Description: Provides date, time, number, and list formatting functionality for various Twitter-supported locales in Javascript.
11
11
  ###
12
12
 
13
+ {{#source_map}}
14
+ ###
15
+ //@ sourceMappingURL={{locale}}.map
16
+ ###
17
+ {{/source_map}}
18
+
13
19
  # required alias definition that adds twitter_cldr to Twitter's static build process
14
20
  ###<<module_def>>###
15
21
 
@@ -0,0 +1,103 @@
1
+ # Copyright 2012 Twitter, Inc
2
+ # http://www.apache.org/licenses/LICENSE-2.0
3
+
4
+ class TwitterCldr.NumberParser
5
+ constructor: ->
6
+ @group_separator = "{{{group_separator}}}"
7
+ @decimal_separator = "{{{decimal_separator}}}"
8
+ @separator_chars = ['\\.', ',', '\\s'].join("")
9
+
10
+ parse: (number_text, options = {}) ->
11
+ options.strict = true if options.strict is undefined
12
+ separators = this.get_separators(options.strict)
13
+ tokens = this.tokenize(number_text, separators.group, separators.decimal)
14
+ num_list = []
15
+ punct_list = []
16
+
17
+ for token in tokens
18
+ if token.type == "numeric"
19
+ num_list.push(token)
20
+ else
21
+ punct_list.push(token)
22
+
23
+ throw "Invalid number" unless this.is_punct_valid(punct_list)
24
+ throw "Invalid number" unless tokens.slice(-1)[0] &&
25
+ tokens.slice(-1)[0]["type"] == "numeric"
26
+
27
+ if punct_list.length > 0 && punct_list.slice(-1)[0]["type"] == "decimal"
28
+ result = parseInt((num.value for num in num_list[0..-2]).join("")) || 0
29
+ last = num_list.slice(-1)[0];
30
+ result + parseInt(last.value) / Math.pow(10.0, last.value.length)
31
+ else
32
+ parseInt((num.value for num in num_list).join(""))
33
+
34
+ try_parse: (number_text, default_value = null, callback = null, options = {}) ->
35
+ result = try
36
+ this.parse(number_text, options)
37
+ catch err
38
+ if err.toString() == "Invalid number"
39
+ null
40
+ else
41
+ throw err
42
+
43
+ if callback
44
+ callback(result)
45
+ else
46
+ result || default_value
47
+
48
+ is_valid: (number_text, options = {}) ->
49
+ try
50
+ this.parse(number_text, options)
51
+ true
52
+ catch err
53
+ if err.toString() == "Invalid number"
54
+ false
55
+ else
56
+ throw err
57
+
58
+ @is_numeric: (text, separators) ->
59
+ unless separators?
60
+ separators = new NumberParser().separator_chars
61
+
62
+ regexp = new RegExp("^[0-9" + separators + "]+$")
63
+ regexp.test(text)
64
+
65
+ is_punct_valid: (punct_list) ->
66
+ # all group, allowed one decimal at end
67
+ valid = true
68
+
69
+ for punct, index in punct_list
70
+ valid = valid && (punct.type == "group" ||
71
+ (index == (punct_list.length - 1) && punct.type == "decimal")
72
+ )
73
+
74
+ valid
75
+
76
+ get_separators: (strict = false) ->
77
+ group = if strict then @group_separator else @separator_chars
78
+ decimal = if strict then @decimal_separator else @separator_chars
79
+ { group: group, decimal: decimal }
80
+
81
+ tokenize: (number_text, group, decimal) ->
82
+ regexp = new RegExp("([\\d]*)([" + group + "]{0,1})([\\d]*)([" + decimal + "]{0,1})([\\d]*)")
83
+ match_data = number_text.split(regexp)
84
+ match_data = (match for match in match_data when match != "")
85
+ tokens = (this.identify(match, group, decimal) for match in match_data)
86
+ token for token in tokens when token.type != null
87
+
88
+ identify: (text, group, decimal) ->
89
+ result = { value: text }
90
+ result.type = if NumberParser.is_numeric(result.value, "")
91
+ "numeric"
92
+ else
93
+ group_regexp = new RegExp("[" + group + "]")
94
+ decimal_regexp = new RegExp("[" + decimal + "]")
95
+
96
+ if group_regexp.test(result.value)
97
+ "group"
98
+ else if decimal_regexp.test(result.value)
99
+ "decimal"
100
+ else
101
+ null
102
+
103
+ result
@@ -8,6 +8,8 @@ module TwitterCldr
8
8
  module Renderers
9
9
  class Base < Mustache
10
10
 
11
+ attr_reader :locale
12
+
11
13
  def initialize(options = {})
12
14
  @locale = options[:locale]
13
15
  end
@@ -0,0 +1,34 @@
1
+ # encoding: UTF-8
2
+
3
+ # Copyright 2012 Twitter, Inc
4
+ # http://www.apache.org/licenses/LICENSE-2.0
5
+
6
+ module TwitterCldr
7
+ module Js
8
+ module Renderers
9
+ module Parsers
10
+
11
+ class NumberParser < TwitterCldr::Js::Renderers::Base
12
+ self.template_file = File.expand_path(
13
+ File.join(File.dirname(__FILE__), "../..", "mustache/parsers/number_parser.coffee")
14
+ )
15
+
16
+ def group_separator
17
+ Regexp.escape(parser.send(:group_separator))
18
+ end
19
+
20
+ def decimal_separator
21
+ Regexp.escape(parser.send(:decimal_separator))
22
+ end
23
+
24
+ private
25
+
26
+ def parser
27
+ @parser = TwitterCldr::Parsers::NumberParser.new(locale)
28
+ end
29
+ end
30
+
31
+ end
32
+ end
33
+ end
34
+ end
@@ -30,6 +30,10 @@ module TwitterCldr
30
30
  autoload :BidiRenderer, 'twitter_cldr/js/renderers/shared/bidi_renderer'
31
31
  autoload :CalendarRenderer, 'twitter_cldr/js/renderers/shared/calendar_renderer'
32
32
  end
33
+
34
+ module Parsers
35
+ autoload :NumberParser, 'twitter_cldr/js/renderers/parsers/number_parser'
36
+ end
33
37
  end
34
38
  end
35
39
  end
@@ -30,8 +30,13 @@ module TwitterCldr
30
30
  locales = get_locales
31
31
  $stdout.write(options[:begin_msg])
32
32
 
33
- prerender = ENV["PRERENDER"] ? ENV["PRERENDER"] == "true" : nil
34
- compiler = TwitterCldr::Js::Compiler.new(:locales => locales, :prerender => prerender)
33
+ compiler_options = {
34
+ :locales => locales,
35
+ :prerender => ENV["PRERENDER"] ? ENV["PRERENDER"] == "true" : nil,
36
+ :source_map => ENV["SOURCE_MAP"] ? ENV["SOURCE_MAP"] == "true" : false
37
+ }
38
+
39
+ compiler = TwitterCldr::Js::Compiler.new(compiler_options)
35
40
  output_dir = File.expand_path(options[:output_dir] || get_output_dir)
36
41
 
37
42
  build_duration = time_operation do
@@ -40,7 +45,14 @@ module TwitterCldr
40
45
  out_file = File.join(output_dir, file_pattern % locale)
41
46
  FileUtils.mkdir_p(File.dirname(out_file))
42
47
  File.open(out_file, "w+") do |f|
43
- f.write(bundle)
48
+ f.write(bundle.source)
49
+ end
50
+
51
+ if bundle.source_map
52
+ ext = File.extname(out_file)
53
+ File.open("#{out_file.chomp(ext)}.map", "w+") do |f|
54
+ f.write(bundle.source_map)
55
+ end
44
56
  end
45
57
  end
46
58
  end
@@ -5,6 +5,6 @@
5
5
 
6
6
  module TwitterCldr
7
7
  module Js
8
- VERSION = "2.2.0"
8
+ VERSION = "2.2.2"
9
9
  end
10
- end
10
+ end
@@ -5,10 +5,7 @@
5
5
 
6
6
  require 'rails'
7
7
  require 'twitter_cldr'
8
- require 'mustache'
9
8
  require 'json'
10
- require 'uglifier'
11
- require 'coffee-script'
12
9
  require 'rake'
13
10
 
14
11
  require 'twitter_cldr/js/version'
@@ -0,0 +1,211 @@
1
+ // Copyright 2012 Twitter, Inc
2
+ // http://www.apache.org/licenses/LICENSE-2.0
3
+
4
+ var TwitterCldr = require('../../../lib/assets/javascripts/twitter_cldr/en.js');
5
+
6
+ describe("NumberParser", function() {
7
+ beforeEach(function() {
8
+ separators = [",", "\\."]
9
+ parser = new TwitterCldr.NumberParser();
10
+ });
11
+
12
+ describe("#group_separator", function() {
13
+ it("returns the correct group separator", function() {
14
+ expect(parser.group_separator).toEqual(",");
15
+ });
16
+ });
17
+
18
+ describe("#decimal_separator", function() {
19
+ it("returns the correct decimal separator", function() {
20
+ expect(parser.decimal_separator).toEqual("\\\.");
21
+ });
22
+ });
23
+
24
+ describe("#identify", function() {
25
+ it("properly identifies a numeric value", function() {
26
+ expect(
27
+ parser.identify("7841", separators[0], separators[1])
28
+ ).toEqual({value: "7841", type: "numeric"});
29
+ });
30
+
31
+ it("properly identifies a decimal separator", function() {
32
+ expect(
33
+ parser.identify(".", separators[0], separators[1])
34
+ ).toEqual({value: ".", type: "decimal"});
35
+ });
36
+
37
+ it("properly identifies a group separator", function() {
38
+ expect(
39
+ parser.identify(",", separators[0], separators[1])
40
+ ).toEqual({value: ",", type: "group"});
41
+ });
42
+
43
+ it("returns nil if the text doesn't match a number or either separators", function() {
44
+ expect(
45
+ parser.identify("abc", separators[0], separators[1])
46
+ ).toEqual({value: "abc", type: null});
47
+ });
48
+ });
49
+
50
+ describe("#tokenize", function() {
51
+ it("splits text by numericality and group/decimal separators", function() {
52
+ expect(
53
+ parser.tokenize("1,33.00", separators[0], separators[1])
54
+ ).toEqual([
55
+ {value: "1", type: "numeric"},
56
+ {value: ",", type: "group"},
57
+ {value: "33", type: "numeric"},
58
+ {value: ".", type: "decimal"},
59
+ {value: "00", type: "numeric"}
60
+ ]);
61
+ });
62
+
63
+ it("returns an empty array for a non-numeric string", function() {
64
+ expect(parser.tokenize("abc", separators[0], separators[1])).toEqual([]);
65
+ });
66
+ });
67
+
68
+ describe("#get_separators", function() {
69
+ it("returns all separators when strict mode is off", function() {
70
+ var found_separators = parser.get_separators(false);
71
+ expect(found_separators.group).toEqual('\\.,\\s');
72
+ expect(found_separators.decimal).toEqual('\\.,\\s');
73
+ });
74
+
75
+ it("returns only locale-specific separators when strict mode is on", function() {
76
+ var found_separators = parser.get_separators(true);
77
+ expect(found_separators.group).toEqual(',');
78
+ expect(found_separators.decimal).toEqual('\\.');
79
+ });
80
+ });
81
+
82
+ describe("#is_punct_valid", function() {
83
+ function strip_numerics(token_list) {
84
+ var tokens = [];
85
+
86
+ for (var idx in token_list) {
87
+ if (token_list[idx].type != "numeric") {
88
+ tokens.push(token_list[idx]);
89
+ }
90
+ }
91
+
92
+ return tokens;
93
+ }
94
+
95
+ it("correctly validates a number with no decimal", function() {
96
+ var tokens = strip_numerics(parser.tokenize("1.337", separators[0], separators[1]));
97
+ expect(parser.is_punct_valid(tokens)).toEqual(true);
98
+ });
99
+
100
+ it("correctly validates a number with a decimal", function() {
101
+ var tokens = strip_numerics(parser.tokenize("1,337.00", separators[0], separators[1]));
102
+ expect(parser.is_punct_valid(tokens)).toEqual(true);
103
+ });
104
+
105
+ it("reports on an invalid number when it has more than one decimal", function() {
106
+ var tokens = strip_numerics(parser.tokenize("1.337.00", separators[0], separators[1]));
107
+ expect(parser.is_punct_valid(tokens)).toEqual(false);
108
+ });
109
+ });
110
+
111
+ describe("#is_numeric?", function() {
112
+ it("returns true if the text is numeric", function() {
113
+ expect(TwitterCldr.NumberParser.is_numeric("4839", "")).toEqual(true);
114
+ expect(TwitterCldr.NumberParser.is_numeric("1", "")).toEqual(true);
115
+ });
116
+
117
+ it("returns false if the text is not purely numeric", function() {
118
+ expect(TwitterCldr.NumberParser.is_numeric("abc", "")).toEqual(false);
119
+ expect(TwitterCldr.NumberParser.is_numeric("123abc", "")).toEqual(false);
120
+ });
121
+
122
+ it("returns false if the text is blank", function() {
123
+ expect(TwitterCldr.NumberParser.is_numeric("", "")).toEqual(false);
124
+ });
125
+
126
+ it("accepts the given characters as valid numerics", function() {
127
+ expect(TwitterCldr.NumberParser.is_numeric("a123a", "a")).toEqual(true);
128
+ expect(TwitterCldr.NumberParser.is_numeric("1,234.56")).toEqual(true); // default separator chars used here
129
+ });
130
+ });
131
+
132
+ describe("#valid?", function() {
133
+ it("correctly identifies a series of valid cases", function() {
134
+ var nums = ["5", "5.0", "1,337", "1,337.0", "0.05", ".5", "1,337,000.00"];
135
+ for (var idx in nums) {
136
+ expect(parser.is_valid(nums[idx])).toEqual(true);
137
+ }
138
+ });
139
+
140
+ it("correctly identifies a series of invalid cases", function() {
141
+ var nums = ["12.0.0", "5.", "5,"];
142
+ for (var idx in nums) {
143
+ expect(parser.is_valid(nums[idx])).toEqual(false);
144
+ }
145
+ });
146
+ });
147
+
148
+ describe("#parse", function() {
149
+ it("correctly parses a series of valid numbers", function() {
150
+ var cases = {
151
+ "5": 5,
152
+ "5.0": 5.0,
153
+ "1,337": 1337,
154
+ "1,337.0": 1337.0,
155
+ "0.05": 0.05,
156
+ ".5": 0.5, // Borked
157
+ "1,337,000.00": 1337000.0
158
+ };
159
+
160
+ for (var text in cases) {
161
+ var expected = cases[text];
162
+ expect(parser.parse(text)).toEqual(expected);
163
+ }
164
+ });
165
+
166
+ it("correctly raises an error when asked to parse invalid numbers", function() {
167
+ var cases = ["12.0.0", "5.", "5,"];
168
+
169
+ for (var idx in cases) {
170
+ expect(function() {
171
+ parser.parse(cases[idx])
172
+ }).toThrow(new Error("Invalid number"));
173
+ }
174
+ });
175
+
176
+ describe("non-strict", function() {
177
+ it("succeeds in parsing even if inexact punctuation is used", function() {
178
+ expect(parser.parse("5 100", {strict: false})).toEqual(5100);
179
+ });
180
+ });
181
+ });
182
+
183
+ describe("#try_parse", function() {
184
+ it("parses correctly with a valid number", function() {
185
+ expect(parser.try_parse("1,234")).should == 1234;
186
+ });
187
+
188
+ it("parses correctly with a valid number and calls the callback", function() {
189
+ var pre_result = null;
190
+ parser.try_parse("1,234", null, function(result) { pre_result = result; });
191
+ pre_result.should == 1234
192
+ });
193
+
194
+ it("falls back on the default value if the number is invalid", function() {
195
+ expect(parser.try_parse("5.")).toEqual(null);
196
+ expect(parser.try_parse("5.", 0)).toEqual(0);
197
+ });
198
+
199
+ it("falls back on the block if the number is invalid", function() {
200
+ var pre_result = null;
201
+ parser.try_parse("5.", null, function(result) { pre_result = 9 });
202
+ expect(pre_result).toEqual(9);
203
+ });
204
+
205
+ it("re-raises any unexpected errors", function() {
206
+ expect(function() {
207
+ parser.try_parse({});
208
+ }).toThrow(new Error("Object #<Object> has no method 'split'"));
209
+ });
210
+ });
211
+ });
@@ -4,9 +4,6 @@
4
4
  var TwitterCldr = require('../../lib/assets/javascripts/twitter_cldr/en.js');
5
5
 
6
6
  describe("Utilities", function() {
7
- beforeEach(function() {
8
- });
9
-
10
7
  describe("#is_even", function() {
11
8
  it("should return true if the given number is even", function() {
12
9
  for(var i = 0; i <= 1000; i += 2) {
@@ -17,12 +17,13 @@ Gem::Specification.new do |s|
17
17
  s.add_dependency 'json'
18
18
  s.add_dependency 'twitter_cldr', '~> 2.4.0'
19
19
  s.add_dependency 'railties', '~> 3.1'
20
- s.add_dependency 'rake', '~> 0.9.2.2'
21
- s.add_dependency 'mustache', '~> 0.99.4'
22
- s.add_dependency 'ruby_parser', '~> 2.3.1'
23
- s.add_dependency 'therubyracer', '~> 0.9.10'
24
- s.add_dependency 'uglifier', '~> 1.2.4'
25
- s.add_dependency 'coffee-script', '~> 2.2.0'
20
+
21
+ s.add_development_dependency 'rake'
22
+ s.add_development_dependency 'mustache', '~> 0.99.4'
23
+ s.add_development_dependency 'ruby_parser', '~> 2.3.1'
24
+ s.add_development_dependency 'therubyracer', '~> 0.11.4'
25
+ s.add_development_dependency 'uglifier', '~> 1.2.4'
26
+ s.add_development_dependency 'coffee-script', '~> 2.2.0'
26
27
 
27
28
  s.require_path = 'lib'
28
29