form_object 0.0.1 → 0.1.1

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 (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