hickey 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,38 @@
1
+ module Hickey
2
+ module DomainDetector
3
+ module Configurable
4
+ def self.included(base)
5
+ base.class_eval do
6
+ @@configurations = {}
7
+ cattr_accessor :configurations, :instance_writer => false
8
+ alias_method_chain :new_instance, :configuration
9
+ end
10
+ end
11
+
12
+ private
13
+ def new_instance_with_configuration(class_or_instance, record)
14
+ instance = new_instance_without_configuration(class_or_instance, record)
15
+ instance.instance_eval do
16
+ def valid_without_callbacks?
17
+ true
18
+ end
19
+ end
20
+ unless configuration_of(instance)[:callbacks] == :all
21
+ callbacks = configuration_of(instance)[:callbacks] || []
22
+ instance.instance_eval <<-"end_eval"
23
+ alias :original_callback :callback
24
+ def callback(method)
25
+ [#{callbacks.collect(&:inspect).join(',')}].include?(method) ? original_callback(method) : true
26
+ end
27
+ end_eval
28
+ end
29
+ instance
30
+ end
31
+
32
+ def configuration_of(instance)
33
+ klass = instance.class
34
+ @@configurations[klass.name.underscore.to_sym] || @@configurations[klass.base_class.name.underscore.to_sym] || {}
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,30 @@
1
+ module Hickey
2
+ module DomainDetector
3
+ module Scopes
4
+ def self.included(base)
5
+ base.send(:alias_method_chain, :visit_hash, :scopes)
6
+ base.send(:alias_method_chain, :new_instance, :scopes)
7
+ end
8
+
9
+ def visit_hash_with_scopes(attribute, record)
10
+ scopes.each do |foreign_key, owner|
11
+ record[foreign_key] = owner.id unless record[foreign_key]
12
+ end
13
+ returning visit_hash_without_scopes(attribute, record) do |instance|
14
+ scopes.delete instance.class.name.foreign_key
15
+ end
16
+ end
17
+
18
+ def new_instance_with_scopes(class_or_instance, record)
19
+ returning new_instance_without_scopes(class_or_instance, record) do |instance|
20
+ scopes[instance.class.name.foreign_key] = instance
21
+ end
22
+ end
23
+
24
+ private
25
+ def scopes
26
+ @scopes ||= {}
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,17 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + '/test_helper'
2
+
3
+ class BelongsToAssociationTest < Test::Unit::TestCase
4
+ def test_create_associated_belongs_to_model
5
+ Hickey.dump :projects_member => {:user => {:login => 'xli'}}
6
+ assert_not_nil projects_member.user
7
+ assert_equal 'xli', projects_member.user.login
8
+ end
9
+
10
+ def test_create_associated_belongs_to_model_with_class_name
11
+ Hickey.dump :topic => {:title => 'Bla bla...', :owner => {:login => 'xli'}}
12
+
13
+ topic = Topic.find(:first)
14
+ assert_not_nil topic.owner
15
+ assert_equal 'xli', topic.owner.login
16
+ end
17
+ end
@@ -0,0 +1,20 @@
1
+ require 'logger'
2
+
3
+ RAILS_DEFAULT_LOGGER = Logger.new(File.expand_path(File.dirname(__FILE__)) + '/debug.log')
4
+ RAILS_DEFAULT_LOGGER.level = Logger::DEBUG
5
+ ActiveRecord::Base.logger = RAILS_DEFAULT_LOGGER
6
+
7
+ ActiveRecord::Base.configurations = {
8
+ 'test' => {
9
+ :database => ":memory:",
10
+ :adapter => 'sqlite3',
11
+ :timeout => 500
12
+ }
13
+ }
14
+
15
+ ActiveRecord::Base.establish_connection 'test'
16
+
17
+ ActiveRecord::Base.silence do
18
+ ActiveRecord::Migration.verbose = false
19
+ load File.join(File.dirname(__FILE__), 'schema.rb')
20
+ end
@@ -0,0 +1,144 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + '/test_helper'
2
+
3
+ class EnableCallbacksTest < Test::Unit::TestCase
4
+
5
+ def teardown
6
+ Hickey.setup.clear
7
+ Simple.public_instance_methods(false).each do |method|
8
+ next if method == 'id'
9
+ Simple.class_eval "def #{method};end"
10
+ end
11
+ end
12
+
13
+ def test_configuration_setup_should_not_effect_other_instances
14
+ Hickey.setup(:simple => {:callbacks => [:after_save]})
15
+ simple = Hickey.dump(:simple => {})
16
+ assert simple.respond_to?(:original_callback, true)
17
+
18
+ simple = Simple.find(:all).first
19
+ assert !simple.respond_to?(:original_callback, true)
20
+ end
21
+
22
+ def test_invoke_before_save_and_after_save_after_configured_all_callbacks
23
+ Hickey.setup(:simple => {:callbacks => :all})
24
+ Simple.class_eval do
25
+ before_save :create_user_before_save
26
+ after_save :create_user_after_save
27
+ def create_user_after_save
28
+ Hickey.dump(:user => {:login => 'create_user_after_save'})
29
+ end
30
+ def create_user_before_save
31
+ Hickey.dump(:user => {:login => 'create_user_before_save'})
32
+ end
33
+ def validate
34
+ raise 'should bypass'
35
+ end
36
+ end
37
+
38
+ Hickey.dump(:simple => {})
39
+
40
+ assert_equal ['create_user_before_save', 'create_user_after_save'].sort, User.find(:all).collect(&:login).sort
41
+ end
42
+
43
+ def test_invoke_before_validation_on_create_after_configured_all_callbacks
44
+ Hickey.setup(:simple => {:callbacks => :all})
45
+ Simple.class_eval do
46
+ before_validation_on_create :create_user_before_validation_on_create
47
+ def create_user_before_validation_on_create
48
+ Hickey.dump(:user => {:login => 'create_user_before_validation_on_create'})
49
+ end
50
+ def validate
51
+ raise 'should bypass'
52
+ end
53
+ end
54
+
55
+ Hickey.dump(:simple => {})
56
+ assert_equal ['create_user_before_validation_on_create'], User.find(:all).collect(&:login)
57
+ end
58
+
59
+ def test_invoke_before_validation_after_configured_all_callbacks
60
+ Hickey.setup(:simple => {:callbacks => :all})
61
+ Simple.class_eval do
62
+ before_validation :create_user_before_validation
63
+ def create_user_before_validation
64
+ Hickey.dump(:user => {:login => 'create_user_before_validation'})
65
+ end
66
+ def validate
67
+ raise 'should bypass'
68
+ end
69
+ end
70
+
71
+ Hickey.dump(:simple => {})
72
+ assert_equal ['create_user_before_validation'], User.find(:all).collect(&:login)
73
+ end
74
+
75
+ def test_invoke_before_validation_after_configured_all_callbacks
76
+ Hickey.setup(:simple => {:callbacks => :all})
77
+ Simple.class_eval do
78
+ after_validation :create_user_after_validation
79
+ def create_user_after_validation
80
+ Hickey.dump(:user => {:login => 'create_user_after_validation'})
81
+ end
82
+ def validate
83
+ raise 'should bypass'
84
+ end
85
+ end
86
+
87
+ Hickey.dump(:simple => {})
88
+ assert_equal ['create_user_after_validation'], User.find(:all).collect(&:login)
89
+ end
90
+
91
+ def test_should_not_callback_before_validation_on_create_if_pass_in_existed_model
92
+ simple = Hickey.dump(:simple => {})
93
+ Hickey.setup(:simple => {:callbacks => :all})
94
+ Simple.class_eval do
95
+ before_validation_on_create :create_user_before_validation_on_create
96
+ def create_user_before_validation_on_create
97
+ Hickey.dump(:user => {:login => 'create_user_before_validation_on_create'})
98
+ end
99
+ def validate
100
+ raise 'should bypass'
101
+ end
102
+ end
103
+
104
+ Hickey.dump(simple => {})
105
+ assert_equal [], User.find(:all).collect(&:login)
106
+ end
107
+
108
+ def test_should_enable_configuration_of_invoking_all_callbacks_for_all_subclasses
109
+ Hickey.setup(:property_definition => {:callbacks => :all})
110
+ DatePropertyDefinition.class_eval do
111
+ after_validation :create_user_after_validation
112
+ def create_user_after_validation
113
+ Hickey.dump(:user => {:login => 'create_user_after_validation'})
114
+ end
115
+ def validate
116
+ raise 'should bypass'
117
+ end
118
+ end
119
+
120
+ Hickey.dump(:property_definition => {:type => 'DatePropertyDefinition'})
121
+
122
+ assert_equal ['create_user_after_validation'], User.find(:all).collect(&:login)
123
+ end
124
+
125
+ def test_invoke_callback_specified_after_configured
126
+ Hickey.setup(:simple => {:callbacks => [:after_create, :before_create]})
127
+ Simple.class_eval do
128
+ before_create :create_user_before_create
129
+ after_create :create_user_after_create
130
+ def create_user_before_create
131
+ Hickey.dump(:user => {:login => 'create_user_before_create'})
132
+ end
133
+ def create_user_after_create
134
+ Hickey.dump(:user => {:login => 'create_user_after_create'})
135
+ end
136
+ def validate
137
+ raise 'should bypass'
138
+ end
139
+ end
140
+
141
+ Hickey.dump(:simple => {})
142
+ assert_equal ['create_user_after_create', 'create_user_before_create'].sort, User.find(:all).collect(&:login).sort
143
+ end
144
+ end
@@ -0,0 +1,62 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + '/test_helper'
2
+
3
+ class FindOrCreateActionsTest < Test::Unit::TestCase
4
+ def test_create_action
5
+ assert Hickey.dump(:simple => {:create => {}})
6
+ end
7
+
8
+ def test_create_multi_models
9
+ result = Hickey.dump(:simple => {:create => {}}, :user => {:create => {:login => 'xli'}})
10
+ assert_equal({:simple => Simple.find(:first), :user => User.find(:first)}, result)
11
+ end
12
+
13
+ def test_create_association_model
14
+ Hickey.dump(:project => {:identifier => 'hickey', :users => [{:create => {:login => 'xli', :admin => true}}]})
15
+
16
+ assert_equal 'xli', project.users.first.login
17
+ end
18
+
19
+ def test_find_action
20
+ simple1 = Hickey.dump(:simple => {})
21
+ simple2 = Hickey.dump(:simple => {:find => {}})
22
+ assert_equal simple1, simple2
23
+ assert_equal 1, Simple.count(:all)
24
+ end
25
+
26
+ def test_find_by_attributes
27
+ Hickey.dump(:user => {:login => 'mm'})
28
+ user1 = Hickey.dump(:user => {:login => 'xli'})
29
+ user2 = Hickey.dump(:user => {:find => {:login => 'xli'}})
30
+ assert_equal user1, user2
31
+ assert_equal 2, User.count(:all)
32
+ end
33
+
34
+ def test_should_find_model_without_association
35
+ Hickey.dump(:project => {:identifier => 'hickey', :users => [{:login => 'xli', :admin => true}]})
36
+
37
+ project = Hickey.dump(:project => {:find => {:identifier => 'hickey', :users => [{:login => 'xli', :admin => true}]}})
38
+ assert_equal 'hickey', project.identifier
39
+ assert_equal 'xli', project.users.first.login
40
+ assert_equal 1, Project.count(:all)
41
+
42
+ assert_equal 2, User.count(:all)
43
+ end
44
+
45
+ def test_find_model_with_finding_association
46
+ Hickey.dump(:project => {:identifier => 'hickey', :users => [{:login => 'xli', :admin => true}]})
47
+
48
+ project = Hickey.dump(:project => {:find => {:identifier => 'hickey', :users => [{:find => {:login => 'xli', :admin => true}}]}})
49
+ assert_equal 'hickey', project.identifier
50
+ assert_equal 'xli', project.users.first.login
51
+ assert_equal 1, Project.count(:all)
52
+
53
+ assert_equal 1, User.count(:all)
54
+ end
55
+
56
+ def test_find_or_create
57
+ Hickey.dump(:simple => {:find_or_create => {}})
58
+ assert_equal 1, Simple.count(:all)
59
+ Hickey.dump(:simple => {:find_or_create => {}})
60
+ assert_equal 1, Simple.count(:all)
61
+ end
62
+ end
@@ -0,0 +1,10 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + '/test_helper'
2
+
3
+ class HasAndBelongsToManyAssociationTest < Test::Unit::TestCase
4
+ def test_create_associated_has_and_belongs_to_many_models
5
+ Hickey.dump :user => {:login => 'xli', :countries => [{:name => 'China'}]}
6
+
7
+ assert_equal 1, user.countries.size
8
+ assert_equal 'China', user.countries.first.name
9
+ end
10
+ end
@@ -0,0 +1,71 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + '/test_helper'
2
+
3
+ class HasManyAssociationTest < Test::Unit::TestCase
4
+
5
+ def test_create_associated_empty_models
6
+ Hickey.dump(:project => {:identifier => 'hickey', :projects_members => []})
7
+ assert_equal [], project.projects_members
8
+ end
9
+
10
+ def test_create_associated_many_existed_models
11
+ Hickey.dump :project => {:identifier => 'hickey', :projects_members => [{}, {}]}
12
+
13
+ assert_equal 2, project.projects_members.size
14
+ assert_not_nil project.projects_members.first
15
+ assert_not_nil project.projects_members.last
16
+ end
17
+
18
+ def test_option_class_name
19
+ Hickey.dump :user => {:login => 'xli', :my_topics => [{:title => 'Bla bla...'}]}
20
+ assert_equal 1, user.my_topics.size
21
+ assert_equal 'Bla bla...', user.my_topics.first.title
22
+ end
23
+
24
+ def test_option_through_models
25
+ Hickey.dump :project => {:identifier => 'hickey', :users => [{:login => 'xli'}]}
26
+ assert_equal 1, project.projects_members.size
27
+ assert_not_nil project.projects_members.first.user
28
+ assert_equal 'xli', project.projects_members.first.user.login
29
+
30
+ assert_equal 'xli', project.users.first.login
31
+ end
32
+
33
+ def test_option_foreign_key
34
+ Hickey.dump :writer => {:login => 'xli', :addresses => [{:location => 'BeiJing'}, {:location => 'ShangHai'}]}
35
+ assert_equal 2, writer.addresses.size
36
+ assert_equal ['BeiJing', 'ShangHai'].sort, writer.addresses.collect(&:location).sort
37
+ end
38
+
39
+ def test_option_as
40
+ Hickey.dump :writer => {:topics => [{:title => 'Hello world'}, {:title => 'Hello world again'}]}
41
+ assert_equal ['Hello world', 'Hello world again'].sort, writer.topics.collect(&:title).sort
42
+ end
43
+
44
+ def test_option_through_and_as
45
+ Hickey.dump :writer => {:login => 'writer', :disscutions => [{:speaker => {:login => 'xli'}}, {:speaker => {:login => 'oo'}}]}
46
+ speakers = writer.disscutions.collect(&:speaker)
47
+ assert_equal ['writer', 'xli', 'oo'].sort, User.find(:all).collect(&:login).sort
48
+ assert_equal 2, speakers.size
49
+ speakers = [speakers.first.login, speakers.last.login]
50
+ assert_equal ['xli', 'oo'].sort, speakers.sort
51
+ end
52
+
53
+ def test_specifying_type_attribute_for_single_table_inheritance
54
+ Hickey.dump :project => {:all_property_definitions => [{:name => 'status', :type => 'EnumPropertyDefinition'}, {:name => 'owner', :type => 'UserPropertyDefinition'}]}
55
+
56
+ assert_equal ['status', 'owner'].sort, project.all_property_definitions.collect(&:name).sort
57
+ end
58
+
59
+ def test_subclass_relationship_of_single_table_inheritance
60
+ Hickey.dump :property_definition => {:type => 'EnumPropertyDefinition', :enum_values => [{:value => 'new'}, {:value => 'open'}]}
61
+
62
+ assert_equal ['new', 'open'].sort, property_definition.enum_values.collect(&:value).sort
63
+ end
64
+
65
+ def test_should_raise_active_record_subclass_not_found_error_when_cant_find_subclass
66
+ assert_raise ActiveRecord::SubclassNotFound do
67
+ Hickey.dump :property_definition => {:type => 'NotPropertyDefinition'}
68
+ end
69
+ end
70
+
71
+ end
@@ -0,0 +1,53 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + '/test_helper'
2
+
3
+ class HasOneAssociationTest < Test::Unit::TestCase
4
+ def test_user_has_one_address
5
+ Hickey.dump :user => {:address => {:location => 'BeiJing'}}
6
+ assert_equal 'BeiJing', user.address.location
7
+ end
8
+
9
+ def test_with_option_foreign_key
10
+ Hickey.dump :author => {:address => {:location => 'BeiJing'}}
11
+ assert_equal 'BeiJing', author.address.location
12
+ end
13
+
14
+ def test_with_option_as_and_class_name
15
+ Hickey.dump :author => {:working_topic => {:title => 'Hello world'}}
16
+ assert_equal 'Hello world', author.working_topic.title
17
+ end
18
+
19
+ def test_with_option_through_has_one
20
+ Hickey.dump :author => {:country => {:name => 'China'}}
21
+ assert_equal 'China', author.country.name
22
+ end
23
+
24
+ def test_with_option_through_source
25
+ Hickey.dump :author => {:living_country => {:name => 'China'}}
26
+ assert_equal 'China', author.living_country.name
27
+ end
28
+
29
+ def test_with_option_through_source_type
30
+ Hickey.dump :disscution => {:speaker => {:login => 'xli'}}
31
+ assert_equal 'xli', disscution.speaker.login
32
+ end
33
+
34
+ def test_through_and_as
35
+ # fail('do we need this?')
36
+ end
37
+
38
+ #active_record couldn't work on has_one :through belongs to
39
+ def xtest_with_option_through_belongs_to
40
+ user = User.create(:login => 'xli')
41
+ DisscutionBelongsToTopic.create!(:owner => user)
42
+ assert_equal 'xli', d.owner.login
43
+
44
+ Hickey.dump :disscution_belongs_to_topic => {:owner => {:login => 'xli'}}
45
+ assert_equal 'xli', disscution_belongs_to_topic.owner.login
46
+ end
47
+
48
+ #active_record couldn't work on has_one :through belongs to
49
+ def xtest_with_option_through_source_type
50
+ Hickey.dump :disscution_belongs_to_topic => {:speaker => {:login => 'xli'}}
51
+ assert_equal 'xli', disscution_belongs_to_topic.speaker.login
52
+ end
53
+ end