active_interaction 0.3.0 → 0.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 58a3ed3559d4e08664cc19fb81100a947bb597e8
4
- data.tar.gz: d7d1152399851b34028504b90b05a5cfda76e14f
3
+ metadata.gz: 1c363a94aaacce981bd5b48b6681e193a01f7449
4
+ data.tar.gz: 81bdc016e4c55ead1dc8d632fd361c1752ce4b9d
5
5
  SHA512:
6
- metadata.gz: 96954a543eb586113be298cef976bbbdc5bb1eeed62de460d5b42ac3ad3c2c56896483729ad1c4a012ef08757b1e92a47848b9b7db7c903ebea3f3455967cfba
7
- data.tar.gz: 046393507e5bb5acfea4db4bd0b1e95222d8dfafd156bb5289668c0139153ce1c9e9a643d1b3fc7c41d5bcdd444df5abc47c300301a9721a8757471eea2976e7
6
+ metadata.gz: 44c0c3dd501b88f1c23301a1b7baccbe3518a3b9f494c6c46ecf756d13e3825ca0886db66bde70bcc8db43c18df3ed9f3dbc129e0a53cb5044328bbc55be68e8
7
+ data.tar.gz: d9199c57073feb9afd9f22d84a026eb6bdb66f0713c8e9a0f43a0b5f96ee3b07ab02dd433789c61dbabfeb18d13395911ce3ab7479fdb911c512752aa250183e
@@ -1,5 +1,9 @@
1
1
  # [Master][]
2
2
 
3
+ # [0.4.0][]
4
+
5
+ - Support i18n translations.
6
+
3
7
  # [0.3.0][] (2013-08-07)
4
8
 
5
9
  - Give better error messages for nested attributes.
@@ -39,7 +43,8 @@
39
43
 
40
44
  - Initial release.
41
45
 
42
- [master]: https://github.com/orgsync/active_interaction/compare/v0.3.0...master
46
+ [master]: https://github.com/orgsync/active_interaction/compare/v0.4.0...master
47
+ [0.4.0]: https://github.com/orgsync/active_interaction/compare/v0.3.0...v0.4.0
43
48
  [0.3.0]: https://github.com/orgsync/active_interaction/compare/v0.2.2...v0.3.0
44
49
  [0.2.2]: https://github.com/orgsync/active_interaction/compare/v0.2.1...v0.2.2
45
50
  [0.2.1]: https://github.com/orgsync/active_interaction/compare/v0.2.0...v0.2.1
data/README.md CHANGED
@@ -22,7 +22,7 @@ This project uses [semantic versioning][].
22
22
  Add it to your Gemfile:
23
23
 
24
24
  ```ruby
25
- gem 'active_interaction', '~> 0.3.0'
25
+ gem 'active_interaction', '~> 0.4.0'
26
26
  ```
27
27
 
28
28
  And then execute:
@@ -197,6 +197,49 @@ end
197
197
 
198
198
  Check out the [documentation][] for a full list of methods.
199
199
 
200
+ ## How do I translate an interaction?
201
+
202
+ ActiveInteraction is i18n-aware out of the box! All you have to do
203
+ is add translations to your project. In Rails, they typically go
204
+ into `config/locales`. So, for example, let's say that (for whatever
205
+ reason) you want to print out everything backwards. Simply add
206
+ translations for ActiveInteraction to your `hsilgne` locale:
207
+
208
+ ```yaml
209
+ # config/locales/hsilgne.yml
210
+ hsilgne:
211
+ active_interaction:
212
+ types:
213
+ array: yarra
214
+ boolean: naeloob
215
+ date: etad
216
+ date_time: emit etad
217
+ file: elif
218
+ float: taolf
219
+ hash: hsah
220
+ integer: regetni
221
+ model: ledom
222
+ string: gnirts
223
+ time: emit
224
+ errors:
225
+ messages:
226
+ invalid: dilavni si
227
+ invalid_nested: '%{type} dilav a ton si'
228
+ missing: deriuqer si
229
+ ```
230
+
231
+ Then set your locale and run an interaction like normal:
232
+
233
+ ```ruby
234
+ I18n.locale = :hsilgne
235
+ class Interaction < ActiveInteraction::Base
236
+ boolean :a
237
+ def execute; end
238
+ end
239
+ p Interaction.run.errors.messages
240
+ # => {:a=>["deriuqer si"]}
241
+ ```
242
+
200
243
  ## Credits
201
244
 
202
245
  This project was inspired by the fantastic work done in [Mutations][].
@@ -20,5 +20,9 @@ require 'active_interaction/filters/string_filter'
20
20
  require 'active_interaction/filters/time_filter'
21
21
  require 'active_interaction/base'
22
22
 
23
+ I18n.backend.load_translations(
24
+ Dir.glob(File.join(%w(lib active_interaction locale *.yml)))
25
+ )
26
+
23
27
  # @since 0.1.0
24
28
  module ActiveInteraction end
@@ -44,6 +44,14 @@ module ActiveInteraction
44
44
  false
45
45
  end
46
46
 
47
+ def self.i18n_scope
48
+ :active_interaction
49
+ end
50
+
51
+ def i18n_scope
52
+ self.class.i18n_scope
53
+ end
54
+
47
55
  extend OverloadHash
48
56
 
49
57
  # Returns the output from {#execute} if there are no validation errors or
@@ -191,12 +199,12 @@ module ActiveInteraction
191
199
  begin
192
200
  filter.prepare(attribute, send(attribute), options, &block)
193
201
  rescue InvalidNestedValue
194
- errors.add(attribute, 'is invalid')
202
+ errors.add(attribute, :invalid_nested)
195
203
  rescue InvalidValue
196
- errors.add(attribute,
197
- "is not a valid #{type.to_s.humanize.downcase}")
204
+ errors.add(attribute, :invalid,
205
+ type: I18n.translate("#{i18n_scope}.types.#{type.to_s}"))
198
206
  rescue MissingValue
199
- errors.add(attribute, 'is required')
207
+ errors.add(attribute, :missing)
200
208
  end
201
209
  end
202
210
  private validator
@@ -1,3 +1,3 @@
1
1
  module ActiveInteraction
2
- VERSION = Gem::Version.new('0.3.0')
2
+ VERSION = Gem::Version.new('0.4.0')
3
3
  end
@@ -234,4 +234,16 @@ describe ActiveInteraction::Base do
234
234
  expect(interaction).to_not be_persisted
235
235
  end
236
236
  end
237
+
238
+ describe '.i18n_scope' do
239
+ it 'returns the scope' do
240
+ expect(described_class.i18n_scope).to eq :active_interaction
241
+ end
242
+ end
243
+
244
+ describe '#i18n_scope' do
245
+ it 'returns the scope' do
246
+ expect(interaction.i18n_scope).to eq :active_interaction
247
+ end
248
+ end
237
249
  end
@@ -0,0 +1,108 @@
1
+ require 'spec_helper'
2
+
3
+ class I18nInteraction < ActiveInteraction::Base
4
+ hash :a do
5
+ hash :x
6
+ end
7
+
8
+ def execute; end
9
+ end
10
+
11
+ describe I18nInteraction do
12
+ include_context 'interactions'
13
+
14
+ TYPES = %w(
15
+ array
16
+ boolean
17
+ date
18
+ date_time
19
+ file
20
+ float
21
+ hash
22
+ integer
23
+ model
24
+ string
25
+ time
26
+ )
27
+
28
+ shared_examples 'translation' do
29
+ context 'types' do
30
+ TYPES.each do |type|
31
+ it "has a translation for #{type}" do
32
+ key = "#{described_class.i18n_scope}.types.#{type}"
33
+ expect { I18n.translate(key, raise: true) }.to_not raise_error
34
+ end
35
+ end
36
+ end
37
+
38
+ context 'error messages' do
39
+ let(:translation) { I18n.translate(key, type: type, raise: true) }
40
+ let(:type) { I18n.translate("#{described_class.i18n_scope}.types.hash") }
41
+
42
+ context ':invalid' do
43
+ let(:key) { "#{described_class.i18n_scope}.errors.messages.invalid" }
44
+
45
+ it 'has a translation' do
46
+ expect { translation }.to_not raise_error
47
+ end
48
+
49
+ it 'returns the translation' do
50
+ options.merge!(a: Object.new)
51
+ expect(outcome.errors[:a]).to eq [translation]
52
+ end
53
+ end
54
+
55
+ context ':invalid_nested' do
56
+ let(:key) {
57
+ "#{described_class.i18n_scope}.errors.messages.invalid_nested"
58
+ }
59
+
60
+ it 'has a translation' do
61
+ expect { translation }.to_not raise_error
62
+ end
63
+
64
+ it 'returns the translation' do
65
+ options.merge!(a: { x: Object.new })
66
+ expect(outcome.errors[:a]).to eq [translation]
67
+ end
68
+ end
69
+
70
+ context ':missing' do
71
+ let(:key) { "#{described_class.i18n_scope}.errors.messages.missing" }
72
+
73
+ it 'has a translation' do
74
+ expect { translation }.to_not raise_error
75
+ end
76
+
77
+ it 'returns the translation' do
78
+ expect(outcome.errors[:a]).to eq [translation]
79
+ end
80
+ end
81
+ end
82
+ end
83
+
84
+ context 'english' do
85
+ include_examples 'translation'
86
+
87
+ before do
88
+ I18n.locale = :en
89
+ end
90
+ end
91
+
92
+ context 'english'.reverse do
93
+ include_examples 'translation'
94
+
95
+ before do
96
+ I18n.locale = 'english'.reverse
97
+
98
+ I18n.backend.store_translations(I18n.locale, active_interaction: {
99
+ errors: { messages: {
100
+ invalid: "%{type} #{'invalid'.reverse}",
101
+ invalid_nested: 'invalid_nested'.reverse,
102
+ missing: 'missing'.reverse
103
+ } },
104
+ types: TYPES.reduce({}) { |a, e| a[e] = e.reverse; a }
105
+ })
106
+ end
107
+ end
108
+ end
@@ -17,6 +17,10 @@ shared_examples_for 'an interaction' do |type, generator, filter_options = {}|
17
17
  send(type, :defaults_1, :defaults_2,
18
18
  filter_options.merge(default: generator.call))
19
19
 
20
+ def self.name
21
+ SecureRandom.hex
22
+ end
23
+
20
24
  def execute
21
25
  {
22
26
  required: required,
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_interaction
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Lasseigne
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-08-07 00:00:00.000000000 Z
12
+ date: 2013-08-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activemodel
@@ -180,6 +180,7 @@ files:
180
180
  - spec/active_interaction/filters/model_filter_spec.rb
181
181
  - spec/active_interaction/filters/string_filter_spec.rb
182
182
  - spec/active_interaction/filters/time_filter_spec.rb
183
+ - spec/active_interaction/i18n_spec.rb
183
184
  - spec/active_interaction/integration/array_interaction_spec.rb
184
185
  - spec/active_interaction/integration/boolean_interaction_spec.rb
185
186
  - spec/active_interaction/integration/date_interaction_spec.rb
@@ -238,6 +239,7 @@ test_files:
238
239
  - spec/active_interaction/filters/model_filter_spec.rb
239
240
  - spec/active_interaction/filters/string_filter_spec.rb
240
241
  - spec/active_interaction/filters/time_filter_spec.rb
242
+ - spec/active_interaction/i18n_spec.rb
241
243
  - spec/active_interaction/integration/array_interaction_spec.rb
242
244
  - spec/active_interaction/integration/boolean_interaction_spec.rb
243
245
  - spec/active_interaction/integration/date_interaction_spec.rb