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,175 @@
1
+ module ActiveMocker
2
+
3
+ class ModelSchema
4
+
5
+ class Generate
6
+
7
+ attr_reader :schema_file, :models_dir
8
+
9
+ def initialize(schema_file:nil, models_dir:nil, logger:nil)
10
+ @schema_file = schema_file
11
+ @models_dir = models_dir
12
+ Logger.set(logger)
13
+ end
14
+
15
+ def tables
16
+ @tables ||= SchemaReader.new({schema_file: schema_file}).search(nil)
17
+ end
18
+
19
+ def get_table(model , model_name)
20
+ table_name = get_table_name(model.table_name, model_name)
21
+ selected_table = tables.select{|table| table.name == table_name}.first
22
+ if selected_table.nil?
23
+ Logger.error "The Implicit or defined table, `#{table_name}`, can not be found for model #{model_name.camelize}."
24
+ end
25
+ tables.delete(selected_table)
26
+ selected_table
27
+ end
28
+
29
+ # noinspection RubyArgCount
30
+ def run
31
+ model_schemas = models.map do |model_name|
32
+
33
+ model = get_model(model_name)
34
+ next if model == false
35
+ table = get_table(model, model_name)
36
+ attributes = build_attributes(table.fields, primary_key(table.fields, model))
37
+
38
+ ModelSchema.new(class_name: model_name.camelize,
39
+ table_name: table.name,
40
+ attributes: attributes,
41
+ methods: build_methods(model),
42
+ relationships: build_relationships(model),
43
+ constants: model.constants)
44
+ end
45
+
46
+ ModelSchemaCollection.new(model_schemas.compact)
47
+ end
48
+
49
+
50
+
51
+ # noinspection RubyArgCount
52
+ def build_attributes(attributes, primary_attribute)
53
+ attributes.map do |attr|
54
+ attribute = ModelSchema::Attributes
55
+ .new(name: attr.name,
56
+ type: attr.type,
57
+ precision: attr.precision,
58
+ scale: attr.scale,
59
+ default_value: attr.default)
60
+ if primary_attribute == attr
61
+ attribute.primary_key = true
62
+ end
63
+ attribute
64
+ end
65
+ end
66
+
67
+ # noinspection RubyArgCount
68
+ def build_methods(model)
69
+ result = []
70
+ {instance: model.instance_methods_with_arguments,
71
+ class: model.class_methods_with_arguments}.each do |type,methods|
72
+ methods.map do |method|
73
+ method_name = method.keys.first.to_s
74
+ arguments = method.values.first
75
+
76
+ result.push(ModelSchema::Methods.new(name: method_name,arguments: arguments,type:type))
77
+ end
78
+ end
79
+ result
80
+ end
81
+
82
+ def build_relationships(model)
83
+ relations_by_type(model).map do |type, relations|
84
+ relations.map do |relation|
85
+ join_table = nil
86
+ join_table = find_join_table(relation, model) if type == :has_and_belongs_to_many
87
+ Relationships.new(name: relation.name,
88
+ class_name: relation.class_name,
89
+ type: type,
90
+ through: relation.through,
91
+ foreign_key: relation.foreign_key,
92
+ join_table: join_table)
93
+ end
94
+ end.flatten
95
+ end
96
+
97
+ def relations_by_type(model)
98
+ {belongs_to: model.belongs_to,
99
+ has_one: model.has_one,
100
+ has_many: model.has_many,
101
+ has_and_belongs_to_many: model.has_and_belongs_to_many
102
+
103
+ }
104
+ end
105
+
106
+ def find_join_table(relation, model)
107
+ return relation.join_table if relation.respond_to?(:join_table) && relation.join_table
108
+ tables.select do |table|
109
+
110
+ "#{model.table_name}_#{relation.name}" == table.name.to_s || "#{relation.name}_#{model.table_name}" == table.name.to_s
111
+ end.first
112
+ end
113
+
114
+ def primary_key(attributes, model)
115
+ result = model_primary_key_attribute(attributes, model)
116
+ return result unless result.nil?
117
+
118
+ result = find_primary_key(attributes)
119
+ return result unless result.nil?
120
+
121
+ find_id_attribute(attributes)
122
+ end
123
+
124
+ private
125
+
126
+ def model_primary_key_attribute(attributes, model)
127
+ if model.respond_to?(:primary_key) && model.primary_key
128
+ attributes.select do |attr|
129
+ model.primary_key.to_s == attr.name.to_s
130
+ end.first
131
+ end
132
+ end
133
+
134
+ def find_primary_key(attributes)
135
+ attributes.select do |attr|
136
+ attr.try(:primary_key)
137
+ end.first
138
+ end
139
+
140
+ def find_id_attribute(attributes)
141
+ attributes.select do |attr|
142
+ attr.name.to_sym == :id
143
+ end.first
144
+ end
145
+
146
+ public
147
+
148
+ def models
149
+ Dir["#{models_dir}/*.rb"].map do |file|
150
+ Pathname.new(file).basename.to_s.sub('.rb', '')
151
+ end
152
+ end
153
+
154
+ def get_model(model_file_name)
155
+ ModelReader.new({model_dir: models_dir}).parse(model_file_name)
156
+ end
157
+
158
+ def get_table_name(model_table_name, model_name)
159
+ return model_name.tableize if model_table_name.nil?
160
+ return model_table_name
161
+ end
162
+
163
+ def table_to_model_file(table_name)
164
+ table_name.singularize
165
+ end
166
+
167
+ def table_to_class_name(table)
168
+ table.camelize.singularize
169
+ end
170
+
171
+ end
172
+
173
+ end
174
+
175
+ end
@@ -1,8 +1,12 @@
1
+ module ActiveMocker
1
2
  class Reparameterize
2
3
 
3
- def self.call(params, list=false)
4
- return params.map{|state, param| param }.join(", ") if list
4
+ def self.call(params, param_list:false)
5
+ return param_list(params) if param_list
6
+ method_arguments(params)
7
+ end
5
8
 
9
+ def self.method_arguments(params)
6
10
  params.map do |state, param|
7
11
  case state
8
12
  when :req
@@ -11,11 +15,27 @@ class Reparameterize
11
15
  "*#{param}"
12
16
  when :opt
13
17
  "#{param}=nil"
18
+ when :keyreq
19
+ "#{param}:"
20
+ when :key
21
+ "#{param}: nil"
14
22
  else
15
23
  param
16
24
  end
17
- end.join(", ")
25
+ end.join(', ')
26
+
27
+ end
18
28
 
29
+ def self.param_list(params)
30
+ params.map do |state, param|
31
+ case state
32
+ when :key, :keyreq
33
+ "#{param}: #{param}"
34
+ else
35
+ param
36
+ end
37
+ end.join(', ')
19
38
  end
20
39
 
40
+ end
21
41
  end
@@ -4,10 +4,10 @@ module ActiveMocker
4
4
 
5
5
  attr_reader :name, :fields
6
6
 
7
- def initialize(name, fields=[])
7
+ def initialize(name, id=true, fields=[])
8
8
  @name = name
9
9
  @fields = fields
10
- fields.unshift Field.new('id', :integer, {})
10
+ fields.unshift Field.new('id', :integer, [{primary_key: true}]) if id.nil?
11
11
  end
12
12
 
13
13
  def to_h
@@ -1,3 +1,3 @@
1
1
  module ActiveMocker
2
- VERSION = "1.3.2"
2
+ VERSION = "1.4.1"
3
3
  end
@@ -4,7 +4,7 @@ gem 'rails', '4.1'
4
4
 
5
5
  group :development, :test do
6
6
  gem 'sqlite3', '~>1.3'
7
- gem 'rspec-rails', '~>2'
7
+ gem 'rspec-rails', '2.14.1'
8
8
  end
9
9
 
10
10
  group :test do
@@ -1,12 +1,24 @@
1
1
  class Micropost < ActiveRecord::Base
2
2
  belongs_to :user
3
3
  default_scope -> { order('created_at DESC') }
4
+ MAGIC_ID_NUMBER = 90
5
+ MAGIC_ID_STRING = 'F-1'
4
6
 
7
+ module DoNotIncludeInMock
8
+
9
+ end
10
+ include DoNotIncludeInMock
11
+ # self.primary_key = :lol
12
+ # self.table_name = :posts
5
13
  # Returns microposts from the users being followed by the given user.
6
- def self.from_users_followed_by(user)
14
+ def self.from_users_followed_by(user=nil)
7
15
  followed_user_ids = "SELECT followed_id FROM relationships
8
16
  WHERE follower_id = :user_id"
9
17
  where("user_id IN (#{followed_user_ids}) OR user_id = :user_id",
10
18
  user_id: user.id)
11
19
  end
20
+
21
+ def display_name
22
+
23
+ end
12
24
  end
@@ -37,7 +37,7 @@ ActiveRecord::Schema.define(version: 20130315230445) do
37
37
  create_table "users", force: true do |t|
38
38
  t.string "name"
39
39
  t.string "email", default: ""
40
- t.decimal "credits"
40
+ t.decimal "credits", precision: 19, scale: 6
41
41
  t.datetime "created_at"
42
42
  t.datetime "updated_at"
43
43
  t.string "password_digest"
@@ -26,7 +26,7 @@ describe 'Comparing ActiveMocker Api to ActiveRecord Api' do
26
26
  describe '::superclass' do
27
27
 
28
28
  it 'mock has super of active hash' do
29
- expect(UserMock.superclass.name).to eq "ActiveHash::Base"
29
+ expect(UserMock.superclass.name).to eq "ActiveMock::Base"
30
30
  end
31
31
 
32
32
  it 'ar has super of ar' do
@@ -95,7 +95,9 @@ describe 'Comparing ActiveMocker Api to ActiveRecord Api' do
95
95
  describe '#attributes' do
96
96
 
97
97
  let(:user_ar){User.new(attributes)}
98
- let(:user_mock){UserMock.new(attributes)}
98
+ let(:user_mock){
99
+ UserMock.new(attributes)
100
+ }
99
101
 
100
102
  it 'mock' do
101
103
  expect(user_mock.attributes).to eq({"id" => nil, "name" => "Dustin Zeisler", "email" => "dustin@example.com", "credits" => nil, "created_at" => nil, "updated_at" => nil, "password_digest" => nil, "remember_token" => true, "admin" => false})
@@ -292,7 +294,7 @@ describe 'Comparing ActiveMocker Api to ActiveRecord Api' do
292
294
  end
293
295
 
294
296
  it 'UserMock' do
295
- where_no_options(UserMock, ActiveMocker::Collection::Queries::WhereNotChain)
297
+ where_no_options(UserMock, ActiveMock::Queries::WhereNotChain)
296
298
  end
297
299
 
298
300
  end
@@ -400,7 +402,7 @@ describe 'Comparing ActiveMocker Api to ActiveRecord Api' do
400
402
  end
401
403
 
402
404
  it 'UserMock' do
403
- supported_array_methods(UserMock, MicropostMock, ActiveMocker::Collection::Association)
405
+ supported_array_methods(UserMock, MicropostMock, ActiveMock::HasMany)
404
406
  end
405
407
 
406
408
  end
@@ -420,7 +422,7 @@ describe 'Comparing ActiveMocker Api to ActiveRecord Api' do
420
422
  end
421
423
 
422
424
  it 'UserMock' do
423
- collection_find(UserMock, MicropostMock, ActiveMocker::Collection::Association)
425
+ collection_find(UserMock, MicropostMock, ActiveMock::Association)
424
426
  end
425
427
 
426
428
  end
@@ -438,7 +440,7 @@ describe 'Comparing ActiveMocker Api to ActiveRecord Api' do
438
440
  end
439
441
 
440
442
  it 'UserMock' do
441
- collection_finds(UserMock, MicropostMock, ActiveMocker::Collection::Association)
443
+ collection_finds(UserMock, MicropostMock, ActiveMock::Association)
442
444
  end
443
445
 
444
446
  end
@@ -822,7 +824,7 @@ describe 'Comparing ActiveMocker Api to ActiveRecord Api' do
822
824
  end
823
825
 
824
826
  it 'UserMock' do
825
- find_by_exception(UserMock, ActiveMocker::RecordNotFound)
827
+ find_by_exception(UserMock, ActiveMock::RecordNotFound)
826
828
  end
827
829
 
828
830
  end
@@ -846,6 +848,191 @@ describe 'Comparing ActiveMocker Api to ActiveRecord Api' do
846
848
 
847
849
  end
848
850
 
851
+ describe '::transaction' do
849
852
 
853
+ context 'will run code in block' do
854
+
855
+ def transaction(user_class)
856
+ user_class.transaction do
857
+ user_class.create(email: '1')
858
+ user_class.create(email: '2')
859
+ end
860
+
861
+ expect(user_class.count).to eq 2
862
+ end
863
+
864
+ it 'User' do
865
+ transaction(User)
866
+ end
867
+
868
+ it 'UserMock' do
869
+ transaction(UserMock)
870
+ end
871
+
872
+ end
873
+
874
+ end
875
+
876
+ describe 'belongs_to association' do
877
+
878
+ describe 'when setting association by object it will set id if object is persisted' do
879
+
880
+ def id_set_by_object(post_class, user_class)
881
+ user = user_class.create
882
+ post = post_class.create(user: user)
883
+ expect(post.user_id).to eq user.id
884
+ end
885
+
886
+ it 'User' do
887
+ id_set_by_object(Micropost, User)
888
+ end
889
+
890
+ it 'UserMock' do
891
+ id_set_by_object(MicropostMock, UserMock)
892
+ end
893
+
894
+ end
895
+
896
+ describe 'when setting association by object it will set the child association', pending:true do
897
+
898
+ def set_by_object(post_class, user_class)
899
+ user = user_class.create
900
+ post = post_class.create(user: user)
901
+ expect(user.microposts).to eq [post]
902
+ end
903
+
904
+ it 'User' do
905
+ set_by_object(Micropost, User)
906
+ end
907
+
908
+ it 'UserMock' do
909
+ set_by_object(MicropostMock, UserMock)
910
+ end
911
+
912
+ end
913
+
914
+ describe 'when setting association by id it will set the object on the parent' do
915
+
916
+ def object_set_by_id(post_class, user_class)
917
+ user = user_class.create
918
+ post = post_class.create(user_id: user.id)
919
+ expect(post.user).to eq user
920
+ end
921
+
922
+ it 'User' do
923
+ object_set_by_id(Micropost, User)
924
+ end
925
+
926
+ it 'UserMock' do
927
+ object_set_by_id(MicropostMock, UserMock)
928
+ end
929
+
930
+ end
931
+
932
+ describe 'when setting association by object it will not set id if object is not persisted' do
933
+
934
+ def id_set_by_object(post_class, user_class)
935
+ user = user_class.new
936
+ post = post_class.new(user: user)
937
+ expect(post.user_id).to eq nil
938
+ end
939
+
940
+ it 'User' do
941
+ id_set_by_object(Micropost, User)
942
+ end
943
+
944
+ it 'UserMock' do
945
+ id_set_by_object(MicropostMock, UserMock)
946
+ end
947
+
948
+ end
949
+
950
+ describe 'can build' do
951
+
952
+ def build_belong_to(post_class, user_class)
953
+ post = post_class.new
954
+ user = post.build_user
955
+ expect(user.class).to eq user_class
956
+ expect(post.user).to eq user
957
+ end
958
+
959
+ it 'User' do
960
+ build_belong_to(Micropost, User)
961
+ end
962
+
963
+ it 'UserMock' do
964
+ build_belong_to(MicropostMock, UserMock)
965
+ end
966
+
967
+ end
968
+
969
+ end
970
+
971
+ describe 'has_many association' do
972
+
973
+ describe 'when passing in collection all item in collection will set its foreign key to the parent', pending: true do
974
+
975
+ def id_set_to_children(user_class, post_class)
976
+ posts = [post_class.create, post_class.create, post_class.create]
977
+ user = user_class.create(microposts: posts)
978
+ expect(user.microposts.map(&:user_id)).to eq posts.map(&:user_id)
979
+ expect(posts.map(&:user_id)).to eq [user.id, user.id, user.id]
980
+ end
981
+
982
+ it 'User' do
983
+ id_set_to_children(User, Micropost)
984
+ end
985
+
986
+ it 'UserMock' do
987
+ id_set_to_children(UserMock, MicropostMock)
988
+ end
989
+
990
+ end
991
+
992
+ end
993
+
994
+ describe 'can build new object from collection' do
995
+
996
+ def new_record_on_collection(user_class, post_class)
997
+ user = user_class.create
998
+ new_post = user.microposts.build
999
+ expect(new_post.class).to eq(post_class)
1000
+ expect(new_post.attributes).to eq({"id" => nil, "content" => nil, "user_id" => 1, "up_votes" => nil, "created_at" => nil, "updated_at" => nil})
1001
+ expect(user.microposts.count).to eq 0
1002
+ new_post.save
1003
+ expect(user.microposts.count).to eq(1)
1004
+ expect(user.microposts.first).to eq(new_post)
1005
+ end
1006
+
1007
+ it 'User' do
1008
+ new_record_on_collection(User, Micropost)
1009
+ end
1010
+
1011
+ it 'UserMock' do
1012
+ new_record_on_collection(UserMock, MicropostMock)
1013
+ end
1014
+
1015
+ end
1016
+
1017
+ describe 'can create new object from collection' do
1018
+
1019
+ def create_record_on_collection(user_class, post_class)
1020
+ user = user_class.create
1021
+ new_post = user.microposts.create
1022
+ expect(new_post.class).to eq(post_class)
1023
+ expect(new_post.user_id).to eq(1)
1024
+ expect(user.microposts.count).to eq 1
1025
+ expect(user.microposts.first).to eq(new_post)
1026
+ end
1027
+
1028
+ it 'User' do
1029
+ create_record_on_collection(User, Micropost)
1030
+ end
1031
+
1032
+ it 'UserMock' do
1033
+ create_record_on_collection(UserMock, MicropostMock)
1034
+ end
1035
+
1036
+ end
850
1037
 
851
1038
  end