reform 1.1.1 → 1.2.0.beta1

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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +35 -1
  3. data/Gemfile +1 -1
  4. data/README.md +83 -21
  5. data/TODO.md +8 -0
  6. data/database.sqlite3 +0 -0
  7. data/gemfiles/Gemfile.rails-4.0 +1 -0
  8. data/lib/reform.rb +4 -2
  9. data/lib/reform/active_record.rb +2 -1
  10. data/lib/reform/composition.rb +2 -2
  11. data/lib/reform/contract.rb +24 -7
  12. data/lib/reform/contract/setup.rb +21 -9
  13. data/lib/reform/contract/validate.rb +0 -6
  14. data/lib/reform/form.rb +6 -8
  15. data/lib/reform/form/active_model.rb +3 -2
  16. data/lib/reform/form/active_model/model_validations.rb +13 -1
  17. data/lib/reform/form/active_record.rb +1 -7
  18. data/lib/reform/form/changed.rb +9 -0
  19. data/lib/reform/form/json.rb +13 -0
  20. data/lib/reform/form/model_reflections.rb +18 -0
  21. data/lib/reform/form/save.rb +25 -3
  22. data/lib/reform/form/scalar.rb +4 -2
  23. data/lib/reform/form/sync.rb +82 -12
  24. data/lib/reform/form/validate.rb +38 -0
  25. data/lib/reform/rails.rb +1 -1
  26. data/lib/reform/representer.rb +14 -23
  27. data/lib/reform/schema.rb +23 -0
  28. data/lib/reform/twin.rb +20 -0
  29. data/lib/reform/version.rb +1 -1
  30. data/reform.gemspec +2 -2
  31. data/test/active_model_test.rb +2 -2
  32. data/test/active_record_test.rb +7 -4
  33. data/test/changed_test.rb +69 -0
  34. data/test/custom_validation_test.rb +47 -0
  35. data/test/deserialize_test.rb +2 -7
  36. data/test/empty_test.rb +30 -0
  37. data/test/fields_test.rb +24 -0
  38. data/test/form_composition_test.rb +24 -2
  39. data/test/form_test.rb +84 -0
  40. data/test/inherit_test.rb +12 -0
  41. data/test/model_reflections_test.rb +65 -0
  42. data/test/read_only_test.rb +28 -0
  43. data/test/reform_test.rb +2 -175
  44. data/test/representer_test.rb +47 -0
  45. data/test/save_test.rb +51 -1
  46. data/test/scalar_test.rb +0 -18
  47. data/test/skip_if_test.rb +62 -0
  48. data/test/skip_unchanged_test.rb +86 -0
  49. data/test/sync_option_test.rb +83 -0
  50. data/test/twin_test.rb +23 -0
  51. data/test/validate_test.rb +9 -1
  52. metadata +37 -9
  53. data/lib/reform/form/virtual_attributes.rb +0 -22
@@ -0,0 +1,86 @@
1
+ require 'test_helper'
2
+
3
+ class SkipUnchangedTest < MiniTest::Spec
4
+ class SongForm < Reform::Form
5
+ include Sync::SkipUnchanged
6
+ register_feature Sync::SkipUnchanged
7
+
8
+ property :id
9
+ property :title
10
+ property :image, sync: lambda { |value, *| model.image = "processed via :sync: #{value}" }#, virtual: true
11
+ property :band do
12
+ property :name, sync: lambda { |value, *| model.name = "band, processed: #{value}" }
13
+ end
14
+ end
15
+
16
+ Song = Struct.new(:id, :title, :image, :band) do
17
+ def id=(v); raise "never call me #{v.inspect}"; end
18
+ end
19
+ Band = Struct.new(:name)
20
+
21
+ let (:song) { Song.new(1, "Injection", Object, Band.new("Rise Against")) }
22
+
23
+ # skips when not present in hash + SkipUnchanged.
24
+ it("zhz") do
25
+ form = SongForm.new(song)
26
+
27
+ form.validate("title" => "Ready To Fall").must_equal true
28
+ form.sync
29
+
30
+ song.id.must_equal 1 # old
31
+ song.title.must_equal "Ready To Fall" # new!
32
+ song.image.must_equal Object # old
33
+ song.band.name.must_equal "Rise Against" # old
34
+ end
35
+
36
+ # uses :sync when present in params hash.
37
+ it do
38
+ form = SongForm.new(song)
39
+
40
+ form.validate("title" => "Ready To Fall", "image" => Module, "band" => {"name" => Class})
41
+ form.sync
42
+
43
+ song.id.must_equal 1
44
+ song.image.must_equal "processed via :sync: Module"
45
+ # nested works.
46
+ song.band.name.must_equal "band, processed: Class"
47
+ end
48
+ end
49
+
50
+
51
+ # :virtual is considered with SkipUnchanged
52
+ class SkipUnchangedWithVirtualTest < MiniTest::Spec
53
+ Song = Struct.new(:title, :image, :band) do
54
+ def image=(v)
55
+ raise "i should not be called: #{v}"
56
+ end
57
+ end
58
+ Band = Struct.new(:name) do
59
+ def name=(v)
60
+ raise "i should not be called: #{v}"
61
+ end
62
+ end
63
+
64
+ let (:form) { HitForm.new(song) }
65
+ let (:song) { Song.new(nil, nil, Band.new) }
66
+
67
+ class HitForm < Reform::Form
68
+ include Sync::SkipUnchanged
69
+ register_feature Sync::SkipUnchanged
70
+
71
+ property :title
72
+ property :image, virtual: true
73
+ property :band do
74
+ property :name, virtual: true
75
+ end
76
+ end
77
+
78
+ it "hhy" do
79
+ form.validate("title" => "Full Throttle", "image" => "Funny photo of Steve Harris", "band" => {"name" => "Iron Maiden"}).must_equal true
80
+
81
+ form.sync
82
+ song.title.must_equal "Full Throttle"
83
+ song.image.must_equal nil
84
+ song.band.name.must_equal nil
85
+ end
86
+ end
@@ -0,0 +1,83 @@
1
+ require 'test_helper'
2
+
3
+ class SyncOptionTest < MiniTest::Spec
4
+ Band = Struct.new(:name)
5
+ let (:band) { Band.new("Metallica") }
6
+ let (:form) { BandForm.new(band) }
7
+
8
+ # access to :form!
9
+ describe ":sync allows you conditionals" do
10
+ class BandForm < Reform::Form
11
+ property :name, sync: lambda { |value, options| options.user_options[:form].changed?(:name) ? model.name = value : nil } # change if it hasn't changed
12
+ end
13
+
14
+ # don't set name, didn't change.
15
+ it do
16
+ band.instance_exec { def name=(*); raise; end }
17
+ form.validate("name" => "Metallica").must_equal true
18
+ form.sync
19
+ band.name.must_equal "Metallica"
20
+ end
21
+
22
+ # update name.
23
+ it do
24
+ form.validate("name" => "Iron Maiden").must_equal true
25
+ form.sync
26
+ form.name.must_equal "Iron Maiden"
27
+ end
28
+ end
29
+ end
30
+
31
+
32
+ class SyncWithDynamicOptionsTest < MiniTest::Spec
33
+ Song = Struct.new(:id, :title, :length)
34
+
35
+ class SongForm < Reform::Form
36
+ property :id
37
+ property :title, sync: true
38
+ property :length
39
+ end
40
+
41
+ let (:song) { Song.new }
42
+ let (:form) { SongForm.new(song) }
43
+
44
+ # we have access to original input value and outside parameters.
45
+ it do
46
+ form.validate("title" => "A Poor Man's Memory", "length" => 10)
47
+ length_seconds = 120
48
+ form.sync(title: lambda { |value, options| form.model.title = "#{value}: #{length_seconds}" })
49
+
50
+ song.title.must_equal "A Poor Man's Memory: 120"
51
+ song.length.must_equal 10
52
+ song.id.must_equal nil
53
+ end
54
+ end
55
+
56
+
57
+ # :virtual wins over :sync
58
+ # class SyncWithVirtualTest < MiniTest::Spec
59
+ # Song = Struct.new(:title, :image, :band)
60
+ # Band = Struct.new(:name)
61
+
62
+ # let (:form) { HitForm.new(song) }
63
+ # let (:song) { Song.new("Injection", Object, Band.new("Rise Against")) }
64
+
65
+ # class HitForm < Reform::Form
66
+ # include Sync::SkipUnchanged
67
+ # register_feature Sync::SkipUnchanged
68
+
69
+ # property :image, sync: lambda { |value, *| model.image = "processed via :sync: #{value}" }
70
+ # property :band do
71
+ # property :name, sync: lambda { |value, *| model.name = "band, processed: #{value}" }, virtual: true
72
+ # end
73
+ # end
74
+
75
+ # it "abc" do
76
+ # form.validate("image" => "Funny photo of Steve Harris", "band" => {"name" => "Iron Maiden"}).must_equal true
77
+
78
+ # form.sync
79
+ # song.image.must_equal "processed via :sync: Funny photo of Steve Harris"
80
+ # song.band.name.must_equal "Rise Against"
81
+ # end
82
+ # end
83
+
data/test/twin_test.rb ADDED
@@ -0,0 +1,23 @@
1
+ require 'test_helper'
2
+
3
+ require 'test_helper'
4
+ require 'reform/twin'
5
+
6
+ class TwinTest < MiniTest::Spec
7
+ class SongForm < Reform::Form
8
+ class Twin < Disposable::Twin
9
+ property :title
10
+ option :is_online # TODO: this should make it read-only in reform!
11
+ end
12
+
13
+ include Reform::Twin
14
+ twin Twin
15
+ end
16
+
17
+ let (:model) { OpenStruct.new(title: "Kenny") }
18
+
19
+ let (:form) { SongForm.new(model, is_online: true) }
20
+
21
+ it { form.title.must_equal "Kenny" }
22
+ it { form.is_online.must_equal true }
23
+ end
@@ -9,8 +9,11 @@ class ValidateTest < BaseTest
9
9
  "songs" => [{"title" => "Fallout"}, {"title" => "Roxanne"}]
10
10
  }
11
11
  }
12
+ let (:hit) { Song.new }
13
+ let (:song2) { Song.new }
14
+ let (:song1) { Song.new }
12
15
 
13
- subject { AlbumForm.new(Album.new(nil, Song.new, [Song.new, Song.new])) }
16
+ subject { AlbumForm.new(Album.new(nil, hit, [song1, song2])) }
14
17
 
15
18
  before { subject.validate(params) }
16
19
 
@@ -27,6 +30,11 @@ class ValidateTest < BaseTest
27
30
 
28
31
  it { subject.songs[1].must_be_kind_of Reform::Form }
29
32
  it { subject.songs[1].title.must_equal "Roxanne" }
33
+
34
+ # don't touch model.
35
+ it { hit.title.must_equal nil }
36
+ it { song1.title.must_equal nil }
37
+ it { song2.title.must_equal nil }
30
38
  end
31
39
 
32
40
  # TODO: the following tests go to populate_test.rb
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reform
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.2.0.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Sutterer
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-09-04 00:00:00.000000000 Z
12
+ date: 2014-10-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: representable
@@ -17,14 +17,14 @@ dependencies:
17
17
  requirements:
18
18
  - - "~>"
19
19
  - !ruby/object:Gem::Version
20
- version: 2.0.3
20
+ version: 2.1.0
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - "~>"
26
26
  - !ruby/object:Gem::Version
27
- version: 2.0.3
27
+ version: 2.1.0
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: disposable
30
30
  requirement: !ruby/object:Gem::Requirement
@@ -101,14 +101,14 @@ dependencies:
101
101
  requirements:
102
102
  - - '='
103
103
  - !ruby/object:Gem::Version
104
- version: 4.2.0
104
+ version: 5.4.1
105
105
  type: :development
106
106
  prerelease: false
107
107
  version_requirements: !ruby/object:Gem::Requirement
108
108
  requirements:
109
109
  - - '='
110
110
  - !ruby/object:Gem::Version
111
- version: 4.2.0
111
+ version: 5.4.1
112
112
  - !ruby/object:Gem::Dependency
113
113
  name: activerecord
114
114
  requirement: !ruby/object:Gem::Requirement
@@ -211,26 +211,32 @@ files:
211
211
  - lib/reform/form/active_model.rb
212
212
  - lib/reform/form/active_model/model_validations.rb
213
213
  - lib/reform/form/active_record.rb
214
+ - lib/reform/form/changed.rb
214
215
  - lib/reform/form/coercion.rb
215
216
  - lib/reform/form/composition.rb
217
+ - lib/reform/form/json.rb
218
+ - lib/reform/form/model_reflections.rb
216
219
  - lib/reform/form/module.rb
217
220
  - lib/reform/form/multi_parameter_attributes.rb
218
221
  - lib/reform/form/save.rb
219
222
  - lib/reform/form/scalar.rb
220
223
  - lib/reform/form/sync.rb
221
224
  - lib/reform/form/validate.rb
222
- - lib/reform/form/virtual_attributes.rb
223
225
  - lib/reform/rails.rb
224
226
  - lib/reform/representer.rb
227
+ - lib/reform/schema.rb
228
+ - lib/reform/twin.rb
225
229
  - lib/reform/version.rb
226
230
  - reform.gemspec
227
231
  - test/active_model_test.rb
228
232
  - test/active_record_test.rb
229
233
  - test/as_test.rb
230
234
  - test/builder_test.rb
235
+ - test/changed_test.rb
231
236
  - test/coercion_test.rb
232
237
  - test/composition_test.rb
233
238
  - test/contract_test.rb
239
+ - test/custom_validation_test.rb
234
240
  - test/deserialize_test.rb
235
241
  - test/dummy/Rakefile
236
242
  - test/dummy/app/controllers/albums_controller.rb
@@ -255,19 +261,29 @@ files:
255
261
  - test/dummy/db/test.sqlite3
256
262
  - test/dummy/log/production.log
257
263
  - test/dummy/log/server.log
264
+ - test/empty_test.rb
258
265
  - test/errors_test.rb
259
266
  - test/feature_test.rb
267
+ - test/fields_test.rb
260
268
  - test/form_builder_test.rb
261
269
  - test/form_composition_test.rb
270
+ - test/form_test.rb
262
271
  - test/inherit_test.rb
272
+ - test/model_reflections_test.rb
263
273
  - test/model_validations_test.rb
264
274
  - test/nested_form_test.rb
265
275
  - test/rails/integration_test.rb
276
+ - test/read_only_test.rb
266
277
  - test/reform_test.rb
278
+ - test/representer_test.rb
267
279
  - test/save_test.rb
268
280
  - test/scalar_test.rb
281
+ - test/skip_if_test.rb
282
+ - test/skip_unchanged_test.rb
283
+ - test/sync_option_test.rb
269
284
  - test/sync_test.rb
270
285
  - test/test_helper.rb
286
+ - test/twin_test.rb
271
287
  - test/validate_test.rb
272
288
  homepage: https://github.com/apotonick/reform
273
289
  licenses:
@@ -284,9 +300,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
284
300
  version: '0'
285
301
  required_rubygems_version: !ruby/object:Gem::Requirement
286
302
  requirements:
287
- - - ">="
303
+ - - ">"
288
304
  - !ruby/object:Gem::Version
289
- version: '0'
305
+ version: 1.3.1
290
306
  requirements: []
291
307
  rubyforge_project:
292
308
  rubygems_version: 2.2.2
@@ -299,9 +315,11 @@ test_files:
299
315
  - test/active_record_test.rb
300
316
  - test/as_test.rb
301
317
  - test/builder_test.rb
318
+ - test/changed_test.rb
302
319
  - test/coercion_test.rb
303
320
  - test/composition_test.rb
304
321
  - test/contract_test.rb
322
+ - test/custom_validation_test.rb
305
323
  - test/deserialize_test.rb
306
324
  - test/dummy/Rakefile
307
325
  - test/dummy/app/controllers/albums_controller.rb
@@ -326,17 +344,27 @@ test_files:
326
344
  - test/dummy/db/test.sqlite3
327
345
  - test/dummy/log/production.log
328
346
  - test/dummy/log/server.log
347
+ - test/empty_test.rb
329
348
  - test/errors_test.rb
330
349
  - test/feature_test.rb
350
+ - test/fields_test.rb
331
351
  - test/form_builder_test.rb
332
352
  - test/form_composition_test.rb
353
+ - test/form_test.rb
333
354
  - test/inherit_test.rb
355
+ - test/model_reflections_test.rb
334
356
  - test/model_validations_test.rb
335
357
  - test/nested_form_test.rb
336
358
  - test/rails/integration_test.rb
359
+ - test/read_only_test.rb
337
360
  - test/reform_test.rb
361
+ - test/representer_test.rb
338
362
  - test/save_test.rb
339
363
  - test/scalar_test.rb
364
+ - test/skip_if_test.rb
365
+ - test/skip_unchanged_test.rb
366
+ - test/sync_option_test.rb
340
367
  - test/sync_test.rb
341
368
  - test/test_helper.rb
369
+ - test/twin_test.rb
342
370
  - test/validate_test.rb
@@ -1,22 +0,0 @@
1
- class Reform::Form < Reform::Contract
2
- # TODO: this should be in Representer namespace.
3
- module EmptyAttributesOptions
4
- def options
5
- empty_fields = representable_attrs.
6
- find_all { |d| d[:empty] }.
7
- collect { |d| d.name.to_sym }
8
-
9
- super.exclude!(empty_fields)
10
- end
11
- end
12
-
13
- module ReadonlyAttributesOptions
14
- def options
15
- readonly_fields = representable_attrs.
16
- find_all { |d| d[:virtual] }.
17
- collect { |d| d.name.to_sym }
18
-
19
- super.exclude!(readonly_fields)
20
- end
21
- end
22
- end