r18n-core 0.4.14 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/.yardopts +1 -1
  2. data/ChangeLog +21 -0
  3. data/LICENSE +2 -2
  4. data/README.md +456 -0
  5. data/Rakefile +2 -1
  6. data/base/gl.yml +31 -0
  7. data/base/it.yml +1 -1
  8. data/lib/r18n-core/filter_list.rb +157 -0
  9. data/lib/r18n-core/filters.rb +40 -36
  10. data/lib/r18n-core/i18n.rb +17 -9
  11. data/lib/r18n-core/locale.rb +5 -2
  12. data/lib/r18n-core/translated.rb +18 -15
  13. data/lib/r18n-core/translated_string.rb +14 -0
  14. data/lib/r18n-core/translation.rb +19 -20
  15. data/lib/r18n-core/untranslated.rb +8 -5
  16. data/lib/r18n-core/utils.rb +5 -1
  17. data/lib/r18n-core/version.rb +1 -1
  18. data/lib/r18n-core/yaml_loader.rb +2 -2
  19. data/lib/r18n-core.rb +60 -13
  20. data/locales/ca.rb +1 -0
  21. data/locales/cs.rb +0 -1
  22. data/locales/en-au.rb +0 -1
  23. data/locales/en-gb.rb +0 -1
  24. data/locales/en-us.rb +0 -1
  25. data/locales/en.rb +1 -1
  26. data/locales/fr.rb +1 -1
  27. data/locales/gl.rb +21 -0
  28. data/locales/hu.rb +1 -2
  29. data/locales/nb-no.rb +2 -3
  30. data/locales/nl.rb +4 -2
  31. data/locales/pt-br.rb +0 -1
  32. data/locales/pt.rb +0 -1
  33. data/locales/sv-se.rb +2 -3
  34. data/locales/th.rb +1 -1
  35. data/locales/tr.rb +2 -4
  36. data/locales/zh-cn.rb +7 -0
  37. data/locales/zh-tw.rb +7 -0
  38. data/r18n-core.gemspec +10 -10
  39. data/spec/filters_spec.rb +38 -7
  40. data/spec/i18n_spec.rb +15 -18
  41. data/spec/locale_spec.rb +19 -14
  42. data/spec/locales/cs_spec.rb +1 -1
  43. data/spec/locales/pl_spec.rb +1 -1
  44. data/spec/locales/ru_spec.rb +1 -1
  45. data/spec/locales/sk_spec.rb +1 -1
  46. data/spec/r18n_spec.rb +64 -22
  47. data/spec/spec_helper.rb +2 -3
  48. data/spec/translated_spec.rb +18 -4
  49. data/spec/translation_spec.rb +17 -6
  50. data/spec/translations/general/en.yml +1 -0
  51. data/spec/yaml_loader_spec.rb +10 -10
  52. metadata +163 -141
  53. data/Gemfile +0 -5
  54. data/Gemfile.lock +0 -35
  55. data/README.rdoc +0 -482
  56. data/spec/translations/empty/en.yml +0 -0
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  # encoding: utf-8
2
- require 'rubygems'
3
2
  require 'pp'
4
3
 
5
4
  dir = Pathname(__FILE__).dirname
@@ -16,7 +15,7 @@ RSpec.configure do |config|
16
15
  config.before { R18n.cache.clear }
17
16
  end
18
17
 
19
- gem 'maruku'
18
+ gem 'kramdown'
20
19
  gem 'RedCloth'
21
20
 
22
21
  class CounterLoader
@@ -24,7 +23,7 @@ class CounterLoader
24
23
  attr_reader :loaded
25
24
 
26
25
  def initialize(*available)
27
- @available = available.map { |i| R18n::Locale.load(i) }
26
+ @available = available.map { |i| R18n.locale(i) }
28
27
  @loaded = 0
29
28
  end
30
29
 
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  require File.expand_path('../spec_helper', __FILE__)
3
- require File.expand_path('../../lib/r18n-core/translated', __FILE__)
4
3
 
5
4
  describe R18n::Translated do
6
5
  before do
@@ -51,7 +50,7 @@ describe R18n::Translated do
51
50
  obj = ::SomeTranslatedClass.new
52
51
 
53
52
  obj.name.should be_a(R18n::TranslatedString)
54
- obj.name.locale.should == R18n::Locale.load('en')
53
+ obj.name.locale.should == R18n.locale('en')
55
54
  obj.name.path.should == 'SomeTranslatedClass#name'
56
55
  end
57
56
 
@@ -61,7 +60,7 @@ describe R18n::Translated do
61
60
 
62
61
  R18n.set(['no-LC', 'ru', 'en'])
63
62
  user.name_ru = 'Иван'
64
- user.name.locale.should == R18n::Locale.load('ru')
63
+ user.name.locale.should == R18n.locale('ru')
65
64
  end
66
65
 
67
66
  it "should use default locale" do
@@ -70,7 +69,7 @@ describe R18n::Translated do
70
69
 
71
70
  R18n.set('no-LC')
72
71
  user.name_en = 'John'
73
- user.name.locale.should == R18n::Locale.load('en')
72
+ user.name.locale.should == R18n.locale('en')
74
73
  end
75
74
 
76
75
  it "should use filters" do
@@ -133,4 +132,19 @@ describe R18n::Translated do
133
132
  user.name.should == :ivan
134
133
  end
135
134
 
135
+ it "should allow to change I18n object" do
136
+ @user_class.class_eval do
137
+ translation :name
138
+ attr_accessor :r18n
139
+ end
140
+ user = @user_class.new
141
+ user.name_ru = 'Иван'
142
+ user.name_en = 'John'
143
+
144
+ user.r18n = R18n::I18n.new('ru')
145
+ user.name.should == 'Иван'
146
+ user.r18n = R18n::I18n.new('en')
147
+ user.name.should == 'John'
148
+ end
149
+
136
150
  end
@@ -15,6 +15,18 @@ describe R18n::Translation do
15
15
  (i18n.one | 'default').should == 'One'
16
16
  end
17
17
 
18
+ it "should return html escaped string" do
19
+ klass = Class.new(R18n::TranslatedString) do
20
+ def html_safe
21
+ '2'
22
+ end
23
+ end
24
+ str = klass.new('1', nil, nil)
25
+
26
+ str.should be_html_safe
27
+ str.html_safe.should == '2'
28
+ end
29
+
18
30
  it "should load use hierarchical translations" do
19
31
  i18n = R18n::I18n.new(['ru', 'en'], DIR)
20
32
  i18n.in.another.level.should == 'Иерархический'
@@ -38,20 +50,19 @@ describe R18n::Translation do
38
50
 
39
51
  it "should return translation keys" do
40
52
  i18n = R18n::I18n.new('en', [DIR, TWO])
41
- i18n.in._keys.should =~ ['another', 'two']
53
+ i18n.in.translation_keys.should =~ ['another', 'two']
42
54
  end
43
55
 
44
56
  it "should return string with locale info" do
45
57
  i18n = R18n::I18n.new(['no-LC', 'en'], DIR)
46
58
  i18n.one.locale.should == R18n::UnsupportedLocale.new('no-LC')
47
- i18n.two.locale.should == R18n::Locale.load('en')
59
+ i18n.two.locale.should == R18n.locale('en')
48
60
  end
49
61
 
50
62
  it "should filter typed data" do
51
- en = R18n::Locale.load('en')
52
- translation = R18n::Translation.new(en, '', en, {
53
- 'count' => R18n::Typed.new('pl', { 1 => 'one', 'n' => 'many' })
54
- })
63
+ en = R18n.locale('en')
64
+ translation = R18n::Translation.new(en, '', :locale => en, :translations =>
65
+ { 'count' => R18n::Typed.new('pl', { 1 => 'one', 'n' => 'many' }) })
55
66
 
56
67
  translation.count(1).should == 'one'
57
68
  translation.count(5).should == 'many'
@@ -31,6 +31,7 @@ html: !!escape
31
31
  greater: 1 < 2 is %1
32
32
  no_escape: !!html
33
33
  <b>Warning</b>
34
+ escape_params: <b>%1</b>
34
35
 
35
36
  markdown:
36
37
  simple: !!markdown "**Hi!**"
@@ -24,13 +24,13 @@ describe R18n::Loader::YAML do
24
24
  end
25
25
 
26
26
  it "should return all available translations" do
27
- @loader.available.should =~ [R18n::Locale.load('ru'),
28
- R18n::Locale.load('en'),
29
- R18n::Locale.load('no-lc')]
27
+ @loader.available.should =~ [R18n.locale('ru'),
28
+ R18n.locale('en'),
29
+ R18n.locale('no-lc')]
30
30
  end
31
31
 
32
32
  it "should load translation" do
33
- @loader.load(R18n::Locale.load('ru')).should == {
33
+ @loader.load(R18n.locale('ru')).should == {
34
34
  'one' => 'Один', 'in' => {'another' => {'level' => 'Иерархический'}},
35
35
  'typed' => R18n::Typed.new('my', 'value') }
36
36
  end
@@ -41,13 +41,13 @@ describe R18n::Loader::YAML do
41
41
 
42
42
  it "should load in dir recursively" do
43
43
  loader = R18n::Loader::YAML.new(TRANSLATIONS)
44
- loader.available.should =~ [R18n::Locale.load('ru'),
45
- R18n::Locale.load('en'),
46
- R18n::Locale.load('fr'),
47
- R18n::Locale.load('no-tr'),
48
- R18n::Locale.load('no-lc')]
44
+ loader.available.should =~ [R18n.locale('ru'),
45
+ R18n.locale('en'),
46
+ R18n.locale('fr'),
47
+ R18n.locale('no-tr'),
48
+ R18n.locale('no-lc')]
49
49
 
50
- translation = loader.load(R18n::Locale.load('en'))
50
+ translation = loader.load(R18n.locale('en'))
51
51
  translation['two'].should == 'Two'
52
52
  translation['in']['two'].should == 'Two'
53
53
  translation['ext'].should == 'Extension'
metadata CHANGED
@@ -1,162 +1,184 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: r18n-core
3
- version: !ruby/object:Gem::Version
4
- hash: 19
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 4
9
- - 14
10
- version: 0.4.14
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Andrey "A.I." Sitnik
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2012-01-25 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
21
- type: :development
12
+ date: 2012-06-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
22
15
  name: bundler
23
- version_requirements: &id001 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
24
17
  none: false
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- hash: 3
29
- segments:
30
- - 1
31
- - 0
32
- - 10
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
33
21
  version: 1.0.10
34
- prerelease: false
35
- requirement: *id001
36
- - !ruby/object:Gem::Dependency
37
22
  type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 1.0.10
30
+ - !ruby/object:Gem::Dependency
38
31
  name: yard
39
- version_requirements: &id002 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
40
33
  none: false
41
- requirements:
42
- - - ">="
43
- - !ruby/object:Gem::Version
44
- hash: 3
45
- segments:
46
- - 0
47
- version: "0"
48
- prerelease: false
49
- requirement: *id002
50
- - !ruby/object:Gem::Dependency
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
51
38
  type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
52
47
  name: rake
53
- version_requirements: &id003 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
54
49
  none: false
55
- requirements:
56
- - - ">="
57
- - !ruby/object:Gem::Version
58
- hash: 3
59
- segments:
60
- - 0
61
- version: "0"
62
- - - "!="
63
- - !ruby/object:Gem::Version
64
- hash: 59
65
- segments:
66
- - 0
67
- - 9
68
- - 0
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ - - ! '!='
55
+ - !ruby/object:Gem::Version
69
56
  version: 0.9.0
70
- prerelease: false
71
- requirement: *id003
72
- - !ruby/object:Gem::Dependency
73
57
  type: :development
58
+ prerelease: false
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ! '>='
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ - - ! '!='
66
+ - !ruby/object:Gem::Version
67
+ version: 0.9.0
68
+ - !ruby/object:Gem::Dependency
74
69
  name: rspec-core
75
- version_requirements: &id004 !ruby/object:Gem::Requirement
70
+ requirement: !ruby/object:Gem::Requirement
76
71
  none: false
77
- requirements:
78
- - - ">="
79
- - !ruby/object:Gem::Version
80
- hash: 3
81
- segments:
82
- - 0
83
- version: "0"
84
- prerelease: false
85
- requirement: *id004
86
- - !ruby/object:Gem::Dependency
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
87
76
  type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ! '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
88
85
  name: rspec-expectations
89
- version_requirements: &id005 !ruby/object:Gem::Requirement
86
+ requirement: !ruby/object:Gem::Requirement
90
87
  none: false
91
- requirements:
92
- - - ">="
93
- - !ruby/object:Gem::Version
94
- hash: 3
95
- segments:
96
- - 0
97
- version: "0"
98
- prerelease: false
99
- requirement: *id005
100
- - !ruby/object:Gem::Dependency
88
+ requirements:
89
+ - - ! '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
101
92
  type: :development
93
+ prerelease: false
94
+ version_requirements: !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ! '>='
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ - !ruby/object:Gem::Dependency
102
101
  name: rspec-mocks
103
- version_requirements: &id006 !ruby/object:Gem::Requirement
102
+ requirement: !ruby/object:Gem::Requirement
104
103
  none: false
105
- requirements:
106
- - - ">="
107
- - !ruby/object:Gem::Version
108
- hash: 3
109
- segments:
110
- - 0
111
- version: "0"
112
- prerelease: false
113
- requirement: *id006
114
- - !ruby/object:Gem::Dependency
104
+ requirements:
105
+ - - ! '>='
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
115
108
  type: :development
116
- name: maruku
117
- version_requirements: &id007 !ruby/object:Gem::Requirement
118
- none: false
119
- requirements:
120
- - - ">="
121
- - !ruby/object:Gem::Version
122
- hash: 3
123
- segments:
124
- - 0
125
- version: "0"
126
109
  prerelease: false
127
- requirement: *id007
128
- - !ruby/object:Gem::Dependency
110
+ version_requirements: !ruby/object:Gem::Requirement
111
+ none: false
112
+ requirements:
113
+ - - ! '>='
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ - !ruby/object:Gem::Dependency
117
+ name: kramdown
118
+ requirement: !ruby/object:Gem::Requirement
119
+ none: false
120
+ requirements:
121
+ - - ! '>='
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
129
124
  type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ - !ruby/object:Gem::Dependency
130
133
  name: RedCloth
131
- version_requirements: &id008 !ruby/object:Gem::Requirement
134
+ requirement: !ruby/object:Gem::Requirement
132
135
  none: false
133
- requirements:
134
- - - ">="
135
- - !ruby/object:Gem::Version
136
- hash: 3
137
- segments:
138
- - 0
139
- version: "0"
136
+ requirements:
137
+ - - ! '>='
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ type: :development
140
141
  prerelease: false
141
- requirement: *id008
142
- description: " R18n is a i18n tool to translate your Ruby application.\n It has nice Ruby-style syntax, filters, flexible locales, custom loaders,\n translation support for any classes, time and number localization, several\n user language support, agnostic core package with out-of-box support for\n Rails, Sinatra, Merb and desktop applications.\n"
142
+ version_requirements: !ruby/object:Gem::Requirement
143
+ none: false
144
+ requirements:
145
+ - - ! '>='
146
+ - !ruby/object:Gem::Version
147
+ version: '0'
148
+ - !ruby/object:Gem::Dependency
149
+ name: redcarpet
150
+ requirement: !ruby/object:Gem::Requirement
151
+ none: false
152
+ requirements:
153
+ - - ! '>='
154
+ - !ruby/object:Gem::Version
155
+ version: '0'
156
+ type: :development
157
+ prerelease: false
158
+ version_requirements: !ruby/object:Gem::Requirement
159
+ none: false
160
+ requirements:
161
+ - - ! '>='
162
+ - !ruby/object:Gem::Version
163
+ version: '0'
164
+ description: ! " R18n is a i18n tool to translate your Ruby application.\n It
165
+ has nice Ruby-style syntax, filters, flexible locales, custom loaders,\n translation
166
+ support for any classes, time and number localization, several\n user language
167
+ support, agnostic core package with out-of-box support for\n Rails, Sinatra and
168
+ desktop applications.\n"
143
169
  email: andrey@sitnik.ru
144
170
  executables: []
145
-
146
171
  extensions: []
147
-
148
- extra_rdoc_files:
149
- - README.rdoc
172
+ extra_rdoc_files:
173
+ - README.md
150
174
  - LICENSE
151
175
  - ChangeLog
152
- files:
176
+ files:
153
177
  - .rspec
154
178
  - .yardopts
155
179
  - ChangeLog
156
- - Gemfile
157
- - Gemfile.lock
158
180
  - LICENSE
159
- - README.rdoc
181
+ - README.md
160
182
  - Rakefile
161
183
  - base/bg.yml
162
184
  - base/ca.yml
@@ -168,6 +190,7 @@ files:
168
190
  - base/es.yml
169
191
  - base/fi.yml
170
192
  - base/fr.yml
193
+ - base/gl.yml
171
194
  - base/hu.yml
172
195
  - base/it.yml
173
196
  - base/ja.yml
@@ -185,6 +208,7 @@ files:
185
208
  - base/uk.yml
186
209
  - base/zh.yml
187
210
  - lib/r18n-core.rb
211
+ - lib/r18n-core/filter_list.rb
188
212
  - lib/r18n-core/filters.rb
189
213
  - lib/r18n-core/helpers.rb
190
214
  - lib/r18n-core/i18n.rb
@@ -210,6 +234,7 @@ files:
210
234
  - locales/es.rb
211
235
  - locales/fi.rb
212
236
  - locales/fr.rb
237
+ - locales/gl.rb
213
238
  - locales/hu.rb
214
239
  - locales/it.rb
215
240
  - locales/ja.rb
@@ -226,6 +251,8 @@ files:
226
251
  - locales/th.rb
227
252
  - locales/tr.rb
228
253
  - locales/uk.rb
254
+ - locales/zh-cn.rb
255
+ - locales/zh-tw.rb
229
256
  - locales/zh.rb
230
257
  - r18n-core.gemspec
231
258
  - spec/filters_spec.rb
@@ -245,7 +272,6 @@ files:
245
272
  - spec/spec_helper.rb
246
273
  - spec/translated_spec.rb
247
274
  - spec/translation_spec.rb
248
- - spec/translations/empty/en.yml
249
275
  - spec/translations/extension/deep/en.yml
250
276
  - spec/translations/extension/en.yml
251
277
  - spec/translations/extension/no-tr.yml
@@ -255,39 +281,35 @@ files:
255
281
  - spec/translations/two/en.yml
256
282
  - spec/translations/two/fr.yml
257
283
  - spec/yaml_loader_spec.rb
258
- homepage: http://r18n.rubyforge.org/
284
+ homepage: https://github.com/ai/r18n
259
285
  licenses: []
260
-
261
286
  post_install_message:
262
287
  rdoc_options: []
263
-
264
- require_paths:
288
+ require_paths:
265
289
  - lib
266
- required_ruby_version: !ruby/object:Gem::Requirement
290
+ required_ruby_version: !ruby/object:Gem::Requirement
267
291
  none: false
268
- requirements:
269
- - - ">="
270
- - !ruby/object:Gem::Version
271
- hash: 3
272
- segments:
292
+ requirements:
293
+ - - ! '>='
294
+ - !ruby/object:Gem::Version
295
+ version: '0'
296
+ segments:
273
297
  - 0
274
- version: "0"
275
- required_rubygems_version: !ruby/object:Gem::Requirement
298
+ hash: -1924687969248369443
299
+ required_rubygems_version: !ruby/object:Gem::Requirement
276
300
  none: false
277
- requirements:
278
- - - ">="
279
- - !ruby/object:Gem::Version
280
- hash: 3
281
- segments:
301
+ requirements:
302
+ - - ! '>='
303
+ - !ruby/object:Gem::Version
304
+ version: '0'
305
+ segments:
282
306
  - 0
283
- version: "0"
307
+ hash: -1924687969248369443
284
308
  requirements: []
285
-
286
- rubyforge_project: r18n-core
287
- rubygems_version: 1.7.2
309
+ rubyforge_project:
310
+ rubygems_version: 1.8.23
288
311
  signing_key:
289
312
  specification_version: 3
290
313
  summary: I18n tool to translate your Ruby application.
291
314
  test_files: []
292
-
293
315
  has_rdoc:
data/Gemfile DELETED
@@ -1,5 +0,0 @@
1
- source :rubygems
2
-
3
- gem 'psych', :group => [ :test, :development ], :platforms => :mri_19
4
-
5
- gemspec
data/Gemfile.lock DELETED
@@ -1,35 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- r18n-core (0.4.14)
5
-
6
- GEM
7
- remote: http://rubygems.org/
8
- specs:
9
- RedCloth (4.2.9)
10
- diff-lcs (1.1.3)
11
- maruku (0.6.0)
12
- syntax (>= 1.0.0)
13
- psych (1.2.2)
14
- rake (0.9.2.2)
15
- rspec-core (2.8.0)
16
- rspec-expectations (2.8.0)
17
- diff-lcs (~> 1.1.2)
18
- rspec-mocks (2.8.0)
19
- syntax (1.0.0)
20
- yard (0.7.4)
21
-
22
- PLATFORMS
23
- ruby
24
-
25
- DEPENDENCIES
26
- RedCloth
27
- bundler (>= 1.0.10)
28
- maruku
29
- psych
30
- r18n-core!
31
- rake (>= 0, != 0.9.0)
32
- rspec-core
33
- rspec-expectations
34
- rspec-mocks
35
- yard