form_object 0.0.1 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. data/.travis.yml +5 -0
  2. data/Gemfile +6 -0
  3. data/{LICENSE.txt → LICENSE} +0 -0
  4. data/README.md +45 -1
  5. data/Rakefile +1 -1
  6. data/TODO +6 -3
  7. data/lib/form_object.rb +12 -2
  8. data/lib/form_object/base.rb +4 -3
  9. data/lib/form_object/base/collection.rb +33 -0
  10. data/lib/form_object/base/form_builder.rb +29 -0
  11. data/lib/form_object/base/mapping_information.rb +14 -0
  12. data/lib/form_object/dsl.rb +12 -0
  13. data/lib/form_object/dsl/class_methods.rb +25 -0
  14. data/lib/form_object/dsl/instance_methods.rb +18 -0
  15. data/lib/form_object/integrations.rb +24 -20
  16. data/lib/form_object/integrations/active_model.rb +19 -2
  17. data/lib/form_object/integrations/active_model/versions.rb +11 -0
  18. data/lib/form_object/integrations/active_record.rb +14 -2
  19. data/lib/form_object/integrations/active_record/versions.rb +15 -0
  20. data/lib/form_object/integrations/base.rb +69 -71
  21. data/lib/form_object/store.rb +32 -0
  22. data/lib/form_object/utils.rb +5 -0
  23. data/lib/form_object/utils/string_converter.rb +27 -0
  24. data/lib/form_object/version.rb +1 -1
  25. data/test/lib/form_object_test.rb +14 -2
  26. data/test/lib/form_relation_test.rb +16 -1
  27. data/test/lib/integrations/active_model_test.rb +16 -0
  28. data/test/lib/integrations/active_record_test.rb +39 -0
  29. data/test/lib/integrations/base_test.rb +2 -9
  30. data/test/lib/integrations_test.rb +20 -0
  31. data/test/lib/store_test.rb +36 -0
  32. data/test/support/active_record.rb +26 -0
  33. data/test/test_helper.rb +1 -0
  34. metadata +27 -9
  35. data/test/lib/forms_collection_test.rb +0 -11
  36. data/test/support/model.rb +0 -0
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ notifications:
5
+ disabled: true
data/Gemfile CHANGED
@@ -6,3 +6,9 @@ gemspec
6
6
  gem 'rake'
7
7
  gem 'minitest'
8
8
  gem 'turn'
9
+
10
+ group :test do
11
+ gem 'sqlite3'
12
+ gem 'activemodel'
13
+ gem 'activerecord'
14
+ end
File without changes
data/README.md CHANGED
@@ -21,7 +21,51 @@ Or install it yourself as:
21
21
 
22
22
  ## Usage
23
23
 
24
- TODO: Write usage instructions here
24
+ We have a model
25
+
26
+ ``` ruby
27
+ class User < ActiveRecord::Base
28
+ end
29
+
30
+ # attributes => {email: "test@example.com", name: "name"}
31
+ ```
32
+
33
+ Define forms:
34
+
35
+ ``` ruby
36
+ # For base auth
37
+ class BaseAuthForm < FormObject::Base
38
+ map_model User, as: :base_auth
39
+ attribute :email, String # => map form attribute to model attribute
40
+
41
+ validates :email, presence: true # => validate email in form ONLY!
42
+ end
43
+
44
+ # For any other auth
45
+ class TwitterAuthForm < FormObject::Base
46
+ map_model User # name => twitter_auth (name will be generated
47
+ # automatically from class name)
48
+ # There is nothing to validate
49
+ end
50
+ ```
51
+
52
+ In any place:
53
+
54
+ ``` ruby
55
+ @user = User.find(params[:id])
56
+ @form = @user.form( :base_auth ) # This retrive BaseAuthForm instance
57
+ # with attributes from model
58
+ @form.assign_attributes(params[:user]) # assign attributes from hash
59
+
60
+ if @form.valid?
61
+ @form.persist_model # TODO: maybe other method name?
62
+ end
63
+ ```
64
+
65
+ ## Can I help you?
66
+
67
+ Discuss the existing features and offer new features you can
68
+ [here](https://groups.google.com/d/forum/formobject "FormObject").
25
69
 
26
70
  ## Contributing
27
71
 
data/Rakefile CHANGED
@@ -4,7 +4,7 @@ require 'rake/testtask'
4
4
 
5
5
  Rake::TestTask.new do |t|
6
6
  t.libs << "test"
7
- t.test_files = FileList['test/lib/*_test.rb']
7
+ t.test_files = FileList['test/lib/**/*_test.rb']
8
8
  t.verbose = true
9
9
  end
10
10
 
data/TODO CHANGED
@@ -2,14 +2,17 @@ Features list
2
2
 
3
3
  * Features
4
4
  - Model:
5
- - Get the FormObject with filled attributes
6
- - Forms collection for retrive named form
5
+ + Get the FormObject instance with filled attributes
6
+ + Forms collection for retrive named form
7
7
  - FormObject:
8
8
  - Get the model with filled attributes
9
9
  - Create builder for markup (form_for, simple_form_for, etc...)
10
10
 
11
11
  * Integrations
12
- - ActiveRecord
12
+ +/- ActiveModel
13
+ +/- ActiveRecord
13
14
  - Mongoid
14
15
  - DataMapper 1.x
15
16
  - DataMapper 2.x
17
+ - Validations
18
+ - Move validations in the appropriate integration
@@ -3,7 +3,17 @@ require 'virtus'
3
3
  require 'active_model'
4
4
 
5
5
  module FormObject
6
- autoload :Base, 'form_object/base'
7
- autoload :Integrations, 'form_object/integrations'
6
+
7
+ class ModelUndefinedError < RuntimeError
8
+ def initialize( form )
9
+ super "Model not defined for #{form.inspect}"
10
+ end
11
+ end
12
+
13
+ autoload :Utils, 'form_object/utils'
14
+ autoload :Integrations, 'form_object/integrations'
15
+ autoload :Base, 'form_object/base'
16
+ autoload :Store, 'form_object/store'
17
+ autoload :Dsl, 'form_object/dsl'
8
18
  # Your code goes here...
9
19
  end
@@ -1,16 +1,17 @@
1
1
  module FormObject
2
2
  class Base
3
+ autoload :Collection, 'form_object/base/collection'
4
+ autoload :MappingInformation, 'form_object/base/mapping_information'
5
+ autoload :FormBuilder, 'form_object/base/form_builder'
3
6
  include Virtus
4
7
 
5
8
  extend ActiveModel::Naming
9
+ include Dsl
6
10
  include ActiveModel::Conversion
7
11
  include ActiveModel::Validations
8
12
 
9
13
  # Forms are never themselves persisted
10
14
  def persisted?; false; end
11
15
 
12
- def model
13
- nil
14
- end
15
16
  end
16
17
  end
@@ -0,0 +1,33 @@
1
+ module FormObject
2
+
3
+ class MappingInformationNotFound < RuntimeError
4
+ def initialize( critery )
5
+ super "#{critery.inspect} not found"
6
+ end
7
+ end
8
+
9
+ class Base::Collection
10
+ attr_reader :model, :form_classes
11
+
12
+ def initialize( model )
13
+ @model = model
14
+ @form_classes = find_form_classes
15
+ end
16
+
17
+ def []( name )
18
+ build_form_instance(name)
19
+ end
20
+
21
+ protected
22
+
23
+ def find_form_classes
24
+ FormObject::Store.instance.find(model: @model.class).inject({}){|c, i| c[i.name] = i; c}
25
+ end
26
+
27
+ def build_form_instance( name )
28
+ mapping_information = @form_classes[name]
29
+ raise MappingInformationNotFound.new(mapping_information) if mapping_information.nil?
30
+ FormObject::Base::FormBuilder.new(mapping_information, @model).build
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,29 @@
1
+ module FormObject
2
+ class Base::FormBuilder
3
+ attr_reader :mapping_information, :model
4
+
5
+ def initialize( mapping_information, model )
6
+ @mapping_information, @model = mapping_information, model
7
+ end
8
+
9
+ def build
10
+ form_instance
11
+ end
12
+
13
+ protected
14
+
15
+ def form_instance
16
+ @form_instance ||= assign_model_attributes(empty_form)
17
+ end
18
+
19
+ def empty_form
20
+ @mapping_information.form.new
21
+ end
22
+
23
+ def assign_model_attributes( form_instance )
24
+ form_instance.assign_model( @model )
25
+ form_instance
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,14 @@
1
+ module FormObject
2
+ class Base
3
+ MappingInformation = Struct.new(:form, :model, :name, :options) do
4
+
5
+ def match?( critery = {} )
6
+ critery.each do |k, v|
7
+ return false unless self[k] == v
8
+ end
9
+ true
10
+ end
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,12 @@
1
+ module FormObject
2
+ module Dsl
3
+ autoload :ClassMethods, 'form_object/dsl/class_methods'
4
+ autoload :InstanceMethods, 'form_object/dsl/instance_methods'
5
+
6
+ def self.included(receiver) #:nodoc:
7
+ receiver.extend ClassMethods
8
+ receiver.send :include, InstanceMethods
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,25 @@
1
+ module FormObject
2
+ module Dsl
3
+ module ClassMethods
4
+
5
+ def map_model( model_class, options = {} )
6
+ store.map_for_model( self, model_class, options )
7
+ end
8
+
9
+ def form_name
10
+ FormObject::Utils::StringConverter.form_name(self.name).to_sym
11
+ end
12
+
13
+ def model
14
+ store.find(form: self).first.try(:model)
15
+ end
16
+
17
+ protected
18
+
19
+ def store
20
+ FormObject::Store.instance
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,18 @@
1
+ module FormObject
2
+ module Dsl
3
+ module InstanceMethods
4
+
5
+ def model
6
+ raise ModelUndefinedError.new(self) unless @model
7
+ @model.assign_form_object_attributes(self)
8
+ @model
9
+ end
10
+
11
+ def assign_model( model_instance )
12
+ @model = model_instance
13
+ self.attributes = @model.form_object_attributes
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -1,11 +1,10 @@
1
1
  require 'form_object/integrations/base'
2
- Dir["#{File.dirname(__FILE__)}/integrations/*.rb"].sort.each do |path|
2
+ Dir[File.join(File.dirname(__FILE__), "integrations", "*.rb")].sort.each do |path|
3
3
  require "form_object/integrations/#{File.basename(path)}"
4
4
  end
5
5
 
6
6
  module FormObject
7
- # Invalid integration error
8
- class IntegrationNotFound < StandardError
7
+ class InvalidIntegration < RuntimeError
9
8
  def initialize( name )
10
9
  super "#{name.inspect} is invalid integration"
11
10
  end
@@ -13,31 +12,36 @@ module FormObject
13
12
 
14
13
  module Integrations
15
14
 
16
- # Get collection of all integrations
17
- # ActiveModel must be last always
18
- # == Example
15
+ # Find integrations for for selected class
19
16
  #
20
- # Object::Integrations.all
21
- # # => [FormObject::Integrations::ActiveRecord]
17
+ # == Examples:
18
+ # class User
19
+ # end
22
20
  #
23
- def self.all
24
- constants = self.constants.map{ |c| c.to_s }
25
- .select{ |c| c!= 'ActiveModel' }
26
- .sort << 'ActiveModel'
27
- constants.map{ |c| const_get(c) }
21
+ # class ActiveRecordUser < ActiveRecord::Base
22
+ # end
23
+ #
24
+ # FormObject::Integrations.match(User) # => nil
25
+ # FormObject::Integrations.match(ActiveRecordUser) # => FormObject::Integrations::ActiveRecord
26
+ def self.match( klass )
27
+ all.detect {|integration| integration.matches?(klass)}
28
28
  end
29
29
 
30
30
  # Find integration by name
31
- #
32
- # == Examples
33
- # FormObject::Integrations.find(:active_record) # => FormObject::Integrations::ActiveRecord
34
31
  #
35
- def self.find( name )
36
- all.detect {|i| i.integration_name == name} || raise(IntegrationNotFound.new(name))
32
+ # == Examples:
33
+ #
34
+ # FormObject::Integrations.find_by_name(:active_record) # => FormObject::Integrations::ActiveRecord
35
+ def self.find_by_name( name )
36
+ all.detect {|integration| integration.integration_name == name} || raise( InvalidIntegration.new(name) )
37
37
  end
38
38
 
39
- def self.match( *args )
40
- all.detect {|i| i.matches_ancestors?(args)}
39
+ def self.all
40
+ # ActiveModel should be last item
41
+ constants = self.constants.map {|c| c.to_s}
42
+ .select {|c| c != 'ActiveModel'}
43
+ .sort << 'ActiveModel'
44
+ constants.map {|c| const_get(c)}
41
45
  end
42
46
  end
43
47
  end
@@ -1,12 +1,29 @@
1
1
  module FormObject
2
2
  module Integrations
3
3
  module ActiveModel
4
+
5
+ def self.included( base ) #:nodoc:
6
+ base.versions.unshift(*versions)
7
+ end
8
+
4
9
  include Base
10
+ extend ClassMethods
11
+ require 'form_object/integrations/active_model/versions'
12
+
13
+ @defaults = {}
5
14
 
6
- def self.matching_ancestors
7
- %w(ActiveModel ActiveModel::Observing ActiveModel::Validations)
15
+ def self.maching_ancestors
16
+ %w{ActiveModel ActiveModel::Observing ActiveModel::Validations}
8
17
  end
9
18
 
19
+ def assign_form_object_attributes( form )
20
+ self.assign_attributes( form.attributes )
21
+ end
22
+
23
+ def form_object_attributes
24
+ self.attributes
25
+ end
26
+
10
27
  end
11
28
  end
12
29
  end
@@ -0,0 +1,11 @@
1
+ module FormObject
2
+ module Integrations
3
+ module ActiveModel
4
+ version '3.x' do
5
+ def self.active?
6
+ true
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,10 +1,22 @@
1
+ require 'form_object/integrations/active_model'
2
+
1
3
  module FormObject
2
4
  module Integrations
3
5
  module ActiveRecord
4
- include Base
5
6
 
7
+ include Base
8
+ include ActiveModel
9
+ require 'form_object/integrations/active_record/versions'
10
+
11
+ @defaults = {}
12
+
13
+ def self.extended( base ) #:nodoc:
14
+ require 'active_record/version'
15
+ super
16
+ end
17
+
6
18
  def self.matching_ancestors
7
- %w(ActiveRecord::Base)
19
+ %w{ActiveRecord::Base}
8
20
  end
9
21
 
10
22
  end
@@ -0,0 +1,15 @@
1
+ module FormObject
2
+ module Integrations
3
+ module ActiveRecord
4
+
5
+ version '3.x' do
6
+
7
+ def self.active?
8
+ true
9
+ end
10
+
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -1,110 +1,108 @@
1
1
  module FormObject
2
2
  module Integrations
3
3
  module Base
4
+
5
+ # DSL methods for integrations
4
6
  module ClassMethods
5
- # The default options to use for state machines using this integration
6
- attr_reader :defaults
7
-
8
- # FormsCollection for this model
9
- #
10
- # == Example
11
- #
12
- # class BaseForm < FormObject::Base
13
- # model User
14
- # end
15
- #
16
- # class TwitterForm < FormObject::Base
17
- # model User, as: :twitter
18
- # end
19
- #
20
- # @user = User.new
21
- # @base_form = @user.forms[:base] # => instance of BaseForm
22
- # @twitter_form = @iser.forms[:twitter] # => instance of TwitterForm
23
- #
24
- # Forms must have names. If the form name is not specified, it is taken
25
- # from class name.
26
- def forms
27
- nil
28
- end
7
+ # The default optons for integration
8
+ attr_accessor :defaults
29
9
 
30
- # The name of the integration
10
+ # The name of integration
31
11
  def integration_name
32
12
  @integration_name ||= begin
33
- name = self.name.split('::').last
34
- name.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
35
- name.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
36
- name.downcase!
37
- name.to_sym
13
+ FormObject::Utils::StringConverter.integration_name(self.name).to_sym
38
14
  end
39
15
  end
40
-
41
- # Whether this integration is available for the current library. This
42
- # is only true if the ORM that the integration is for is currently
43
- # defined.
44
- def available?
16
+
17
+ # Integration avaliable only if the ORM that integration is for
18
+ # currently defined
19
+ def avaliable?
45
20
  matching_ancestors.any? && Object.const_defined?(matching_ancestors[0].split('::')[0])
46
21
  end
47
-
48
- # The list of ancestor names that cause this integration to matched.
22
+
23
+ # The list of ancestor names that cause this integration to
24
+ # matched.
49
25
  def matching_ancestors
50
26
  []
51
27
  end
52
28
 
53
- # Whether the integration should be used for the given class.
54
- def matches?(klasses)
55
- ancestor_names = klasses.map {|klass| klass.ancestors.map(&:name)}
56
- matches_ancestors?(ancestor_names)
29
+ def matches?( klass )
30
+ matches_ancestors?(klass.ancestors.map(&:name))
57
31
  end
58
32
 
59
- # Whether the integration should be used for the given list of ancestors.
60
- def matches_ancestors?(ancestors)
33
+ def matches_ancestors?( ancestors )
61
34
  (ancestors & matching_ancestors).any?
62
35
  end
63
36
 
64
- # The path to the locale file containing translations for this
65
- # integration. This file will only exist for integrations that actually
66
- # support i18n.
67
- def locale_path
68
- path = "#{File.dirname(__FILE__)}/#{integration_name}/locale.rb"
69
- path if File.exists?(path)
70
- end
71
-
72
- # Extends the given object with any version overrides that are currently
73
- # active
74
- def extended(base)
75
- versions.each do |version|
76
- base.extend(version) if version.active?
77
- end
78
- end
79
-
80
- # Defined versions
81
37
  def versions
82
38
  @versions ||= []
83
39
  end
84
40
 
85
- # DSL for define version and version based methods
41
+ # Define current version for integration
42
+ # Can override some methods for different versions
86
43
  #
87
- def version( name, &block )
88
- mod = Module.new(&block)
89
- versions << mod
44
+ # == Example:
45
+ #
46
+ # module FormObject
47
+ # module Integrations
48
+ # module DataMapper
49
+ # version '1.x' do
50
+ # def persist_model
51
+ # # model.save
52
+ # end
53
+ # end
54
+ #
55
+ # version '2.x' do
56
+ # def persist_model
57
+ # # DataMapper[model.class].persist(model)
58
+ # end
59
+ # end
60
+ # end
61
+ # end
62
+ # end
63
+ #
64
+ def version( name, &blk )
65
+ versions << mod = Module.new( &blk )
90
66
  mod
91
67
  end
92
68
 
69
+ def assign_model_attributes( form_instance, model_instance )
70
+ form_instance.attributes = model_instance.attributes
71
+ end
72
+
73
+ # Extend only active versions
74
+ def extended( base )
75
+ versions.select(&:active?).each do |version|
76
+ base.extend(version)
77
+ end
78
+ end
79
+
93
80
  end
94
81
 
95
- extend ClassMethods
96
-
97
82
  module InstanceMethods
98
83
 
99
- # FormsCollection for this model
84
+ # Forms hash for current model
100
85
  def forms
101
- self.class.forms
86
+ @forms ||= FormObject::Base::Collection.new(self)
87
+ end
88
+
89
+ # Get form by given name
90
+ def form( name )
91
+ forms[name]
92
+ end
93
+
94
+ def form_object_attributes
95
+ Hash.new
102
96
  end
97
+
98
+
103
99
  end
100
+
101
+ extend ClassMethods
104
102
 
105
- def self.included(receiver) #:nodoc:
106
- receiver.extend ClassMethods
107
- receiver.send :include, InstanceMethods
103
+ def self.included(receiver)
104
+ receiver.class_eval { extend ClassMethods }
105
+ receiver.class_eval { include InstanceMethods }
108
106
  end
109
107
  end
110
108
  end
@@ -0,0 +1,32 @@
1
+ require 'singleton'
2
+
3
+ module FormObject
4
+ class Store
5
+ include Singleton
6
+
7
+ def storage
8
+ @storage ||= Set.new
9
+ end
10
+
11
+ def map_for_model( form, model, options = {})
12
+ form_name = retrive_form_name(form, options.delete(:as))
13
+ storage << FormObject::Base::MappingInformation.new(form, model, form_name, options )
14
+ include_integration( model )
15
+ end
16
+
17
+ def find(critery = {})
18
+ storage.select{|mapping_info| mapping_info.match?(critery)}
19
+ end
20
+
21
+ private
22
+
23
+ def retrive_form_name( form, name )
24
+ name ||= form.form_name
25
+ end
26
+
27
+ def include_integration( model_class )
28
+ integration = FormObject::Integrations.match(model_class)
29
+ model_class.send(:include, integration) unless integration.nil?
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,5 @@
1
+ module FormObject
2
+ module Utils
3
+ require 'form_object/utils/string_converter'
4
+ end
5
+ end
@@ -0,0 +1,27 @@
1
+ module FormObject
2
+ module Utils
3
+ module StringConverter
4
+
5
+ def self.integration_name( word )
6
+ name = word.split('::').last
7
+ underscore(name)
8
+ end
9
+
10
+ def self.form_name( word )
11
+ name = word.split('::').last
12
+ name.gsub!(/Form/, '')
13
+ underscore(name).to_sym
14
+ end
15
+
16
+ protected
17
+
18
+ def self.underscore( original_word, options = {} )
19
+ word = original_word.to_s.dup
20
+ word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
21
+ word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
22
+ word.downcase!
23
+ word
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,3 +1,3 @@
1
1
  module FormObject
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -3,6 +3,8 @@ require 'test_helper'
3
3
  class FormObjectTest < TestCase
4
4
  def setup
5
5
  @form = Filter.new(query: "find me")
6
+ @base_form = BaseAuthForm.new(email: "test@example.com", name: "test")
7
+ @twitter_form = TwitterAuthForm.new
6
8
  end
7
9
 
8
10
  def test_should_form_not_persisted
@@ -15,16 +17,26 @@ class FormObjectTest < TestCase
15
17
 
16
18
  def test_should_be_valid_form
17
19
  assert @form.valid?
20
+ assert @base_form.valid?
18
21
  end
19
22
 
20
23
  def test_should_be_invalid_with_empty_query
21
24
  @form.query = ""
22
- assert !@form.valid?
25
+ assert @form.invalid?
23
26
  end
24
27
 
25
28
  def test_should_have_not_nil_created_at_attribute
26
- assert @form.created_at.kind_of?(DateTime)
29
+ assert_kind_of DateTime, @form.created_at
27
30
  assert @form.created_at.present?
28
31
  end
29
32
 
33
+ def test_base_form_have_a_model
34
+ assert_equal User, @base_form.class.model
35
+ end
36
+
37
+ def test_form_should_have_name
38
+ assert_equal :base_auth, @base_form.class.form_name
39
+ assert_equal :twitter_auth, @twitter_form.class.form_name
40
+ end
41
+
30
42
  end
@@ -2,11 +2,26 @@ require 'test_helper'
2
2
 
3
3
  class FormRelationTest < TestCase
4
4
  def setup
5
+ @attributes = { email: "test@example.com", name: "name" }
5
6
  @form = Filter.new(query: "find me")
7
+ @model = User.new(@attributes)
6
8
  end
7
9
 
8
10
  def test_should_not_form_get_model
9
11
  assert_respond_to @form, :model
10
- assert @form.model.nil?
12
+ assert_raises FormObject::ModelUndefinedError do
13
+ @form.model
14
+ end
11
15
  end
16
+
17
+ def test_model_should_have_forms
18
+ base_auth_form = @model.form( :base_auth )
19
+ assert @attributes[:email], base_auth_form.email
20
+ end
21
+
22
+ def test_model_hould_not_have_undefined_inForm_field
23
+ base_auth_form = @model.form( :base_auth )
24
+ assert !base_auth_form.respond_to?( :name )
25
+ end
26
+
12
27
  end
@@ -0,0 +1,16 @@
1
+ require 'test_helper'
2
+
3
+ module Integrations
4
+ # Test ActiveModel integration
5
+ class ActiveModelTest < ::TestCase
6
+ # Test setup
7
+ def setup
8
+ @integration_name = :active_model
9
+ end
10
+
11
+ def test_should_integration_finded_by_name
12
+ assert_equal FormObject::Integrations::ActiveModel, FormObject::Integrations.find_by_name(@integration_name)
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,39 @@
1
+ require 'test_helper'
2
+
3
+ module Integrations
4
+ # Test ActiveRecord integration
5
+ class ActiveRecordTest < ::TestCase
6
+ # Test setup
7
+ def setup
8
+ @integration_name = :active_record
9
+ @user = User.new email: "test@example.com"
10
+ end
11
+
12
+ def test_should_integration_finded_by_name
13
+ assert_equal FormObject::Integrations::ActiveRecord, FormObject::Integrations.find_by_name(@integration_name)
14
+ end
15
+
16
+ def test_should_match_active_record_integration
17
+ assert_equal FormObject::Integrations::ActiveRecord, FormObject::Integrations.match(User)
18
+ end
19
+
20
+ def test_should_have_base_auth_form_instance_for_user_model
21
+ form = @user.form( :base_auth )
22
+ assert form, "base_auth form is nil!"
23
+ end
24
+
25
+ def test_form_should_have_attributes_from_model
26
+ form = @user.form( :base_auth )
27
+ assert_equal @user.email, form.email
28
+ end
29
+
30
+ def test_should_form_get_model_with_new_attributes
31
+ form = @user.form( :base_auth )
32
+ new_user_email = "user@example.com"
33
+ form.attributes = {email: new_user_email}
34
+ model = form.model
35
+ assert_equal new_user_email, model.email
36
+ end
37
+
38
+ end
39
+ end
@@ -1,19 +1,12 @@
1
1
  require 'test_helper'
2
2
 
3
3
  module Integrations
4
-
5
4
  class BaseTest < ::TestCase
6
-
7
5
  def setup
8
- superclass = Class.new
9
- self.class.const_set('Vehicle', superclass)
10
-
11
- @klass = Class.new(superclass)
12
6
  end
13
7
 
14
- def test_should_return_nil_if_match_not_found
15
- assert_nil FormObject::Integrations.match(@klass)
8
+ def test_filter_class_should_not_have_integrations
9
+ assert_nil FormObject::Integrations.match(Filter)
16
10
  end
17
-
18
11
  end
19
12
  end
@@ -0,0 +1,20 @@
1
+ require "test_helper"
2
+
3
+ class IntegrationsTest < TestCase
4
+ def setup
5
+ @integrations = [
6
+ FormObject::Integrations::Base,
7
+ FormObject::Integrations::ActiveModel,
8
+ FormObject::Integrations::ActiveRecord
9
+ ]
10
+ @base_form = BaseAuthForm.new(email: "test@example.com", name: "test")
11
+ @twitter_form = TwitterAuthForm.new
12
+ end
13
+
14
+ def test_integrations_should_bee
15
+ FormObject::Integrations.all.each do |integration|
16
+ assert_includes @integrations, integration
17
+ end
18
+ end
19
+
20
+ end
@@ -0,0 +1,36 @@
1
+ require 'test_helper'
2
+
3
+ class StoreTest < TestCase
4
+
5
+ def setup
6
+ @repo = FormObject::Store.instance
7
+ end
8
+
9
+ def test_should_have_base_auth_in_collection
10
+ assert_equal BaseAuthForm, @repo.find(name: :base_auth).first.form
11
+ end
12
+
13
+ def test_should_have_twitter_in_collection
14
+ assert_equal TwitterAuthForm, @repo.find(name: :twitter).first.form
15
+ end
16
+
17
+ def test_repo_shold_find_form_for_model
18
+ critery = {}
19
+ assert_operator 0, :<, @repo.find(critery).count
20
+ end
21
+
22
+ def test_should_find_by_model_class
23
+ assert_equal User, @repo.find(model: User).first.model
24
+ end
25
+
26
+ def test_repo_shold_find_form_for_model_with_critery
27
+ critery = {name: :base_auth}
28
+ assert_operator 0, :<, @repo.find(critery).count
29
+ end
30
+
31
+ def test_should_not_find_forms_for_wrong_critery
32
+ critery = { name: :wrong_name }
33
+ assert_equal [], @repo.find(critery)
34
+ end
35
+
36
+ end
@@ -0,0 +1,26 @@
1
+ require 'active_record'
2
+
3
+ ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"
4
+
5
+ ActiveRecord::Migration.create_table :users do |t|
6
+ t.string :email
7
+ t.string :name
8
+ t.timestamps
9
+ end
10
+
11
+ class User < ActiveRecord::Base
12
+ # Without form validations.
13
+ # Only Domain Validations
14
+ end
15
+
16
+ class BaseAuthForm < FormObject::Base
17
+ map_model User
18
+
19
+ attribute :email, String
20
+
21
+ validates :email, :presence => true
22
+ end
23
+
24
+ class TwitterAuthForm < FormObject::Base
25
+ map_model User, :as => :twitter
26
+ end
@@ -1,6 +1,7 @@
1
1
  require 'bundler/setup'
2
2
  Bundler.require
3
3
  require 'minitest/autorun'
4
+ require 'turn/autorun'
4
5
 
5
6
  Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].each {|f| require f}
6
7
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: form_object
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-19 00:00:00.000000000 Z
12
+ date: 2012-11-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: virtus
@@ -51,25 +51,40 @@ extensions: []
51
51
  extra_rdoc_files: []
52
52
  files:
53
53
  - .gitignore
54
+ - .travis.yml
54
55
  - Gemfile
55
- - LICENSE.txt
56
+ - LICENSE
56
57
  - README.md
57
58
  - Rakefile
58
59
  - TODO
59
60
  - form_object.gemspec
60
61
  - lib/form_object.rb
61
62
  - lib/form_object/base.rb
63
+ - lib/form_object/base/collection.rb
64
+ - lib/form_object/base/form_builder.rb
65
+ - lib/form_object/base/mapping_information.rb
66
+ - lib/form_object/dsl.rb
67
+ - lib/form_object/dsl/class_methods.rb
68
+ - lib/form_object/dsl/instance_methods.rb
62
69
  - lib/form_object/integrations.rb
63
70
  - lib/form_object/integrations/active_model.rb
71
+ - lib/form_object/integrations/active_model/versions.rb
64
72
  - lib/form_object/integrations/active_record.rb
73
+ - lib/form_object/integrations/active_record/versions.rb
65
74
  - lib/form_object/integrations/base.rb
75
+ - lib/form_object/store.rb
76
+ - lib/form_object/utils.rb
77
+ - lib/form_object/utils/string_converter.rb
66
78
  - lib/form_object/version.rb
67
79
  - test/lib/form_object_test.rb
68
80
  - test/lib/form_relation_test.rb
69
- - test/lib/forms_collection_test.rb
81
+ - test/lib/integrations/active_model_test.rb
82
+ - test/lib/integrations/active_record_test.rb
70
83
  - test/lib/integrations/base_test.rb
84
+ - test/lib/integrations_test.rb
85
+ - test/lib/store_test.rb
86
+ - test/support/active_record.rb
71
87
  - test/support/filter.rb
72
- - test/support/model.rb
73
88
  - test/test_helper.rb
74
89
  homepage:
75
90
  licenses: []
@@ -85,7 +100,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
85
100
  version: '0'
86
101
  segments:
87
102
  - 0
88
- hash: -476988463
103
+ hash: 305297741
89
104
  required_rubygems_version: !ruby/object:Gem::Requirement
90
105
  none: false
91
106
  requirements:
@@ -94,7 +109,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
94
109
  version: '0'
95
110
  segments:
96
111
  - 0
97
- hash: -476988463
112
+ hash: 305297741
98
113
  requirements: []
99
114
  rubyforge_project: form_object
100
115
  rubygems_version: 1.8.24
@@ -104,8 +119,11 @@ summary: Form object implementation
104
119
  test_files:
105
120
  - test/lib/form_object_test.rb
106
121
  - test/lib/form_relation_test.rb
107
- - test/lib/forms_collection_test.rb
122
+ - test/lib/integrations/active_model_test.rb
123
+ - test/lib/integrations/active_record_test.rb
108
124
  - test/lib/integrations/base_test.rb
125
+ - test/lib/integrations_test.rb
126
+ - test/lib/store_test.rb
127
+ - test/support/active_record.rb
109
128
  - test/support/filter.rb
110
- - test/support/model.rb
111
129
  - test/test_helper.rb
@@ -1,11 +0,0 @@
1
- require 'test_helper'
2
-
3
- class FormsCollectionTest < TestCase
4
- def setup
5
- @form = Filter.new(query: "find me")
6
- end
7
-
8
- def test_should_model_have_forms_collection
9
-
10
- end
11
- end
File without changes