active_mocker 1.3.2 → 1.4.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 (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