active_mocker 1.3.2 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/README.md +136 -24
  4. data/Rakefile +8 -2
  5. data/active_mocker.gemspec +3 -3
  6. data/lib/active_mock/association.rb +7 -0
  7. data/lib/active_mock/base.rb +250 -0
  8. data/lib/active_mock/collection.rb +52 -0
  9. data/lib/active_mock/creators.rb +25 -0
  10. data/lib/active_mock/do_nothing_active_record_methods.rb +51 -0
  11. data/lib/active_mock/has_and_belongs_to_many.rb +7 -0
  12. data/lib/active_mock/has_many.rb +54 -0
  13. data/lib/active_mock/next_id.rb +16 -0
  14. data/lib/active_mock/object_inspect.rb +39 -0
  15. data/lib/{active_mocker/collection → active_mock}/queries.rb +26 -19
  16. data/lib/active_mock/records.rb +81 -0
  17. data/lib/active_mock/relation.rb +8 -0
  18. data/lib/active_mocker.rb +3 -1
  19. data/lib/active_mocker/active_mock.rb +26 -0
  20. data/lib/active_mocker/active_record.rb +18 -0
  21. data/lib/active_mocker/active_record/relationships.rb +57 -6
  22. data/lib/active_mocker/active_record/schema.rb +1 -1
  23. data/lib/active_mocker/active_record/scope.rb +1 -1
  24. data/lib/active_mocker/active_record/unknown_class_method.rb +1 -1
  25. data/lib/active_mocker/active_record/unknown_module.rb +10 -9
  26. data/lib/active_mocker/db_to_ruby_type.rb +26 -0
  27. data/lib/active_mocker/field.rb +16 -8
  28. data/lib/active_mocker/generate.rb +19 -174
  29. data/lib/active_mocker/loaded_mocks.rb +48 -8
  30. data/lib/active_mocker/logger.rb +2 -0
  31. data/lib/active_mocker/mock_template.erb +123 -53
  32. data/lib/active_mocker/model_reader.rb +42 -13
  33. data/lib/active_mocker/model_schema.rb +279 -0
  34. data/lib/active_mocker/model_schema/generate.rb +175 -0
  35. data/lib/active_mocker/reparameterize.rb +23 -3
  36. data/lib/active_mocker/table.rb +2 -2
  37. data/lib/active_mocker/version.rb +1 -1
  38. data/sample_app_rails_4/Gemfile +1 -1
  39. data/sample_app_rails_4/app/models/micropost.rb +13 -1
  40. data/sample_app_rails_4/db/schema.rb +1 -1
  41. data/sample_app_rails_4/spec/compare_mocker_and_record_spec.rb +194 -7
  42. data/sample_app_rails_4/spec/micropost_mock_spec.rb +145 -0
  43. data/sample_app_rails_4/spec/mocks/micropost_mock.rb +81 -55
  44. data/sample_app_rails_4/spec/mocks/relationship_mock.rb +85 -54
  45. data/sample_app_rails_4/spec/mocks/user_mock.rb +71 -72
  46. data/sample_app_rails_4/spec/reload_spec.rb +1 -1
  47. data/sample_app_rails_4/spec/user_mock_spec.rb +25 -7
  48. data/spec/lib/acitve_mock/queriable_spec.rb +207 -0
  49. data/spec/lib/active_mocker/db_to_ruby_type_spec.rb +124 -0
  50. data/spec/lib/active_mocker/loaded_mocks_spec.rb +167 -0
  51. data/spec/lib/active_mocker/logger_spec.rb +32 -0
  52. data/spec/lib/active_mocker/model_reader_spec.rb +79 -28
  53. data/spec/lib/active_mocker/model_schema/generate_spec.rb +111 -0
  54. data/spec/lib/active_mocker/model_schema_spec.rb +145 -0
  55. data/spec/lib/model.rb +2 -1
  56. data/spec/lib/reparameterize_spec.rb +202 -0
  57. data/spec/unit_logger.rb +2 -2
  58. metadata +55 -35
  59. data/lib/active_hash/ar_api.rb +0 -77
  60. data/lib/active_hash/init.rb +0 -32
  61. data/lib/active_mocker/collection/association.rb +0 -12
  62. data/lib/active_mocker/collection/base.rb +0 -65
  63. data/lib/active_mocker/collection/relation.rb +0 -11
  64. data/lib/active_mocker/mock_class_methods.rb +0 -92
  65. data/lib/active_mocker/mock_instance_methods.rb +0 -84
  66. data/lib/active_mocker/mock_requires.rb +0 -10
  67. data/spec/lib/active_mocker/collection.rb +0 -94
@@ -0,0 +1,124 @@
1
+ require 'rspec'
2
+ require 'rspec/given'
3
+ $:.unshift File.expand_path('../../../lib', __FILE__)
4
+ require 'bigdecimal'
5
+ require 'axiom/types'
6
+ require 'active_mocker/db_to_ruby_type'
7
+
8
+ describe ActiveMocker::DBToRubyType do
9
+
10
+ describe '::call' do
11
+
12
+ context 'integer' do
13
+
14
+ Given(:db_type) { :integer }
15
+
16
+ When (:call) { described_class.call(db_type) }
17
+
18
+ Then { expect(call).to eq(Fixnum) }
19
+
20
+ end
21
+
22
+ context 'float' do
23
+
24
+ Given(:db_type) { :float }
25
+
26
+ When (:call) { described_class.call(db_type) }
27
+
28
+ Then { expect(call).to eq(Float) }
29
+
30
+ end
31
+
32
+ context 'decimal' do
33
+
34
+ Given(:db_type) { :decimal }
35
+
36
+ When (:call) { described_class.call(db_type) }
37
+
38
+ Then { expect(call).to eq(BigDecimal) }
39
+
40
+ end
41
+
42
+ context 'timestamp' do
43
+
44
+ Given(:db_type) { :timestamp }
45
+
46
+ When (:call) { described_class.call(db_type) }
47
+
48
+ Then { expect(call).to eq(Time) }
49
+
50
+ end
51
+
52
+ context 'time' do
53
+
54
+ Given(:db_type) { :time }
55
+
56
+ When (:call) { described_class.call(db_type) }
57
+
58
+ Then { expect(call).to eq(Time) }
59
+
60
+ end
61
+
62
+ context 'datetime' do
63
+
64
+ Given(:db_type) { :datetime }
65
+
66
+ When (:call) { described_class.call(db_type) }
67
+
68
+ Then { expect(call).to eq(DateTime) }
69
+
70
+ end
71
+
72
+ context 'date' do
73
+
74
+ Given(:db_type) { :date }
75
+
76
+ When (:call) { described_class.call(db_type) }
77
+
78
+ Then { expect(call).to eq(Date) }
79
+
80
+ end
81
+
82
+ context 'text' do
83
+
84
+ Given(:db_type) { :text }
85
+
86
+ When (:call) { described_class.call(db_type) }
87
+
88
+ Then { expect(call).to eq(String) }
89
+
90
+ end
91
+
92
+ context 'string' do
93
+
94
+ Given(:db_type) { :string }
95
+
96
+ When (:call) { described_class.call(db_type) }
97
+
98
+ Then { expect(call).to eq(String) }
99
+
100
+ end
101
+
102
+ context 'binary' do
103
+
104
+ Given(:db_type) { :binary }
105
+
106
+ When (:call) { described_class.call(db_type) }
107
+
108
+ Then { expect(call).to eq(String) }
109
+
110
+ end
111
+
112
+ context 'boolean' do
113
+
114
+ Given(:db_type) { :boolean }
115
+
116
+ When (:call) { described_class.call(db_type) }
117
+
118
+ Then { expect(call).to eq(Axiom::Types::Boolean) }
119
+
120
+ end
121
+
122
+ end
123
+
124
+ end
@@ -0,0 +1,167 @@
1
+ require 'rspec'
2
+ $:.unshift File.expand_path('../../', __FILE__)
3
+ require 'active_mocker/loaded_mocks'
4
+
5
+ describe ActiveMocker::LoadedMocks do
6
+
7
+ before(:each) do
8
+
9
+ class MockClass
10
+ def self.mocked_class
11
+ @@clear_called = false
12
+ @@delete_all_called = false
13
+ @@reload_all_called = false
14
+ 'Object'
15
+ end
16
+
17
+ def self.clear_mock
18
+ @@clear_called = true
19
+ end
20
+
21
+ def self.delete_all
22
+ @@delete_all_called = true
23
+ end
24
+
25
+ def self.reload
26
+ @@reload_all_called = true
27
+ end
28
+ end
29
+
30
+ class MockClass2
31
+ def self.mocked_class
32
+ @@clear_called = false
33
+ @@delete_all_called = false
34
+ @@reload_all_called = false
35
+ 'Object'
36
+ end
37
+
38
+ def self.clear_mock
39
+ @@clear_called = true
40
+ end
41
+
42
+ def self.delete_all
43
+ @@delete_all_called = true
44
+ end
45
+
46
+ def self.reload
47
+ @@reload_all_called = true
48
+ end
49
+
50
+ end
51
+ end
52
+
53
+ after(:each) do
54
+ described_class.send(:internal_clear)
55
+ end
56
+
57
+ describe '::class_name_to_mock' do
58
+
59
+ subject{ described_class.class_name_to_mock }
60
+
61
+ it 'returns key of mocked_class and a constant of the mock class' do
62
+ described_class.add MockClass
63
+ expect(subject).to eq({'Object' => MockClass})
64
+ end
65
+
66
+ end
67
+
68
+ describe '::clear_all' do
69
+
70
+ before do
71
+ ActiveMocker::LoadedMocks.add MockClass
72
+ ActiveMocker::LoadedMocks.add_subclass MockClass2
73
+ described_class.clear_all
74
+ end
75
+
76
+ it 'will call clear_mock on each loaded mock' do
77
+ expect(clear_mock_called?(MockClass)).to eq true
78
+ expect(clear_mock_called?(MockClass2)).to eq true
79
+ end
80
+
81
+ it 'will empty the sub classes' do
82
+ expect(ActiveMocker::LoadedMocks.subclasses.empty?).to eq true
83
+ end
84
+
85
+ def clear_mock_called?(mock)
86
+ return true if mock.class_variable_get(:@@clear_called)
87
+ return false
88
+ end
89
+
90
+ end
91
+
92
+ describe '::delete_all' do
93
+
94
+ it 'will call delete_all on each loaded mock' do
95
+
96
+ described_class.add MockClass
97
+ described_class.add_subclass MockClass2
98
+ described_class.delete_all
99
+ expect(delete_all_called?(MockClass)).to eq true
100
+ expect(delete_all_called?(MockClass2)).to eq true
101
+
102
+ end
103
+
104
+ def delete_all_called?(mock)
105
+ return true if mock.class_variable_get(:@@delete_all_called)
106
+ return false
107
+ end
108
+
109
+ end
110
+
111
+ describe '::mocks' do
112
+
113
+ it 'returns hash the key being a string and the value being the constant' do
114
+
115
+ described_class.add MockClass
116
+ described_class.add MockClass2
117
+ expect(described_class.mocks).to eq({"MockClass" => MockClass, "MockClass2" => MockClass2})
118
+
119
+ end
120
+
121
+ end
122
+
123
+ describe '::all' do
124
+
125
+ it 'returns hash the key being a string and the value being the constant' do
126
+
127
+ described_class.add MockClass
128
+ described_class.add MockClass2
129
+ expect(described_class.all).to eq({"MockClass" => MockClass, "MockClass2" => MockClass2})
130
+
131
+ end
132
+
133
+ end
134
+
135
+ describe '::undefine_all' do
136
+
137
+ # it 'will call delete_all on each loaded mock' do
138
+ #
139
+ # described_class.add MockClass
140
+ # described_class.add MockClass2
141
+ #
142
+ # described_class.undefine_all
143
+ # expect(Object.const_defined?('MockClass')).to eq false
144
+ # expect(Object.const_defined?('MockClass2')).to eq false
145
+ #
146
+ # end
147
+
148
+ end
149
+
150
+ describe '::reload_all' do
151
+
152
+ it 'will call reload on each loaded mock' do
153
+ described_class.add MockClass
154
+ described_class.add_subclass MockClass2
155
+ described_class.reload_all
156
+ expect(reload_all_called?(MockClass)).to eq true
157
+ expect(reload_all_called?(MockClass2)).to eq true
158
+ end
159
+
160
+ def reload_all_called?(mock)
161
+ return true if mock.class_variable_get(:@@reload_all_called)
162
+ return false
163
+ end
164
+
165
+ end
166
+
167
+ end
@@ -0,0 +1,32 @@
1
+ require 'rspec'
2
+ $:.unshift File.expand_path('../../', __FILE__)
3
+ require 'active_mocker/logger'
4
+
5
+ describe ActiveMocker::Logger do
6
+
7
+ describe '::set' do
8
+
9
+ let(:logger){double()}
10
+
11
+ around do
12
+ described_class.class_variable_set(:@@logger, nil)
13
+ end
14
+
15
+ it 'set the logger to be used by the mock class' do
16
+ described_class.set(logger)
17
+ expect(described_class.class_variable_get(:@@logger)).to eq(logger)
18
+ end
19
+
20
+ it 'will pass any methods to the set logger' do
21
+ described_class.set(logger)
22
+ expect(logger).to receive(:info)
23
+ described_class.info
24
+ end
25
+
26
+ it 'will return nil if no logger is set' do
27
+ expect(described_class.any_method).to eq nil
28
+ end
29
+
30
+ end
31
+
32
+ end
@@ -1,5 +1,6 @@
1
1
  require 'rspec'
2
2
  $:.unshift File.expand_path('../../', __FILE__)
3
+ require 'active_support/core_ext/hash/indifferent_access'
3
4
  require 'singleton'
4
5
  require 'logger'
5
6
  require 'active_mocker/logger'
@@ -17,7 +18,9 @@ describe ActiveMocker::ModelReader do
17
18
  ActiveMocker::Logger.set(UnitLogger)
18
19
  end
19
20
 
20
- let(:subject){ described_class.new({model_dir: File.expand_path('../../', __FILE__)}).parse('model') }
21
+ let(:model_reader){ described_class.new({model_dir: File.expand_path('../../', __FILE__)}).parse('model') }
22
+
23
+ let(:subject){ model_reader}
21
24
 
22
25
  describe '#parse' do
23
26
 
@@ -61,64 +64,112 @@ describe ActiveMocker::ModelReader do
61
64
 
62
65
  end
63
66
 
64
- describe '#relationships_types' do
65
-
66
- it '#belongs_to' do
67
+ describe '#belongs_to' do
67
68
 
68
- expect(subject.relationships_types.belongs_to).to eq([[:company]])
69
+ let(:subject){model_reader.belongs_to}
69
70
 
71
+ it 'name of association' do
72
+ expect(subject.first.name).to eq(:company)
70
73
  end
71
74
 
72
- it '#has_many' do
73
-
74
- expect(subject.relationships_types.has_many).to eq([[:users]])
75
-
75
+ it 'class_name override' do
76
+ expect(subject.first.class_name).to eq('PlanServiceCategory')
76
77
  end
77
78
 
78
- it '#has_one' do
79
-
80
- expect(subject.relationships_types.has_one).to eq([[:account]])
81
-
79
+ it 'infer class_name' do
80
+ expect(subject.last.class_name).to eq('Person')
82
81
  end
83
82
 
84
- it '#has_and_belongs_to_many' do
83
+ it 'infer foreign key' do
84
+ expect(subject.last.foreign_key).to eq('person_id')
85
+ end
85
86
 
86
- expect(subject.relationships_types.has_and_belongs_to_many).to eq([[:disclosures]])
87
+ it 'foreign key override' do
88
+ expect(subject.first.foreign_key).to eq('category_id')
89
+ end
87
90
 
91
+ it 'through' do
92
+ expect(subject.last.through).to eq('customer')
88
93
  end
89
94
 
90
95
  end
91
96
 
92
- describe '#relationships' do
93
-
94
- it 'returns an array of relations' do
97
+ describe '#has_one' do
95
98
 
96
- expect(subject.relationships).to eq [:users, :account, :company, :disclosures]
99
+ let(:subject) { model_reader.has_one }
97
100
 
101
+ it 'name of association' do
102
+ expect(subject.first.name).to eq(:account)
98
103
  end
99
104
 
100
105
  end
101
106
 
102
- describe '#collections' do
103
-
104
- it 'returns an array of relations' do
107
+ describe '#has_many' do
105
108
 
106
- expect(subject.collections).to eq [:disclosures, :users]
109
+ let(:subject) { model_reader.has_many }
107
110
 
111
+ it 'name of association' do
112
+ expect(subject.first.name).to eq(:users)
108
113
  end
109
114
 
110
115
  end
111
116
 
112
- describe '#single_relationships' do
117
+ describe '#has_and_belongs_to_many' do
113
118
 
114
- it 'returns an array of relations' do
115
-
116
- expect(subject.single_relationships).to eq [:company, :account]
119
+ let(:subject) { model_reader.has_and_belongs_to_many }
117
120
 
121
+ it 'name of association' do
122
+ expect(subject.first.name).to eq(:disclosures)
118
123
  end
119
124
 
120
125
  end
121
126
 
127
+ # TODO JoinTable
128
+ # class Assembly < ActiveRecord::Base
129
+ # has_and_belongs_to_many :parts
130
+ # end
131
+ #
132
+ # class Part < ActiveRecord::Base
133
+ # has_and_belongs_to_many :assemblies
134
+ # end
135
+ # These need to be backed up by a migration to create the assemblies_parts table.This table should be created without a primary key:
136
+
137
+ # class CreateAssembliesPartsJoinTable < ActiveRecord::Migration
138
+ # def change
139
+ # create_table :assemblies_parts, id: false do |t|
140
+ # t.integer :assembly_id
141
+ # t.integer :part_id
142
+ # end
143
+ # end
144
+ # end
145
+
146
+ # TODO Polymorphic Associations
147
+ # A slightly more advanced twist on associations is the polymorphic association.With polymorphic associations, a model can belong to more than one other model, on a single association.For example, you might have a picture model that belongs to either an employee model or a product model.Here 's how this could be declared:
148
+ #
149
+ # class Picture < ActiveRecord::Base
150
+ # belongs_to :imageable, polymorphic: true
151
+ # end
152
+ #
153
+ # class Employee < ActiveRecord::Base
154
+ # has_many :pictures, as: :imageable
155
+ # end
156
+ #
157
+ # class Product < ActiveRecord::Base
158
+ # has_many :pictures, as: :imageable
159
+ # end
160
+
161
+ # class CreatePictures < ActiveRecord::Migration
162
+ # def change
163
+ # create_table :pictures do |t|
164
+ # t.string :name
165
+ # t.integer :imageable_id
166
+ # t.string :imageable_type
167
+ # t.timestamps
168
+ # end
169
+ # end
170
+ # end
171
+
172
+
122
173
 
123
174
  context 'inject string_reader as file_reader' do
124
175
 
@@ -143,7 +194,7 @@ describe ActiveMocker::ModelReader do
143
194
  let(:search){subject.parse('person')}
144
195
 
145
196
  it 'let not read a file but return a string instead to be evaluated' do
146
- expect(search.relationships_types.belongs_to).to eq [[:zip_code]]
197
+ expect(search.relationships_types.belongs_to.first.name).to eq :zip_code
147
198
  expect(subject.instance_methods).to eq([:full_name])
148
199
  expect(subject.instance_methods_with_arguments).to eq([{:full_name=>[[:req, :first_name], [:req, :last_name]]}])
149
200
  end