active_mocker 1.8.4 → 2.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +13 -0
  3. data/README.md +4 -2
  4. data/lib/active_mocker.rb +9 -25
  5. data/lib/active_mocker/config.rb +26 -46
  6. data/lib/active_mocker/generate.rb +115 -110
  7. data/lib/active_mocker/loaded_mocks.rb +76 -65
  8. data/lib/active_mocker/mock/base.rb +283 -287
  9. data/lib/active_mocker/mock/has_many.rb +2 -0
  10. data/lib/active_mocker/mock_creator.rb +262 -0
  11. data/lib/active_mocker/mock_template.erb +9 -186
  12. data/lib/active_mocker/mock_template/_associations.erb +82 -0
  13. data/lib/active_mocker/mock_template/_attributes.erb +11 -0
  14. data/lib/active_mocker/mock_template/_class_methods.erb +41 -0
  15. data/lib/active_mocker/mock_template/_defined_methods.erb +10 -0
  16. data/lib/active_mocker/mock_template/_modules_constants.erb +10 -0
  17. data/lib/active_mocker/mock_template/_scopes.erb +23 -0
  18. data/lib/active_mocker/null_progress.rb +9 -0
  19. data/lib/active_mocker/output_capture.rb +32 -0
  20. data/lib/active_mocker/parent_class.rb +64 -0
  21. data/lib/active_mocker/progress.rb +13 -0
  22. data/lib/active_mocker/public_methods.rb +15 -23
  23. data/lib/active_mocker/rspec.rb +16 -0
  24. data/lib/active_mocker/rspec_helper.rb +10 -8
  25. data/lib/active_mocker/task.rake +6 -1
  26. data/lib/active_mocker/template_creator.rb +22 -0
  27. data/lib/active_mocker/version.rb +1 -1
  28. metadata +43 -103
  29. data/lib/active_mocker/active_record.rb +0 -74
  30. data/lib/active_mocker/active_record/field.rb +0 -39
  31. data/lib/active_mocker/active_record/relationships.rb +0 -110
  32. data/lib/active_mocker/active_record/schema.rb +0 -81
  33. data/lib/active_mocker/active_record/scope.rb +0 -22
  34. data/lib/active_mocker/active_record/table.rb +0 -26
  35. data/lib/active_mocker/active_record/unknown_class_method.rb +0 -17
  36. data/lib/active_mocker/active_record/unknown_module.rb +0 -30
  37. data/lib/active_mocker/db_to_ruby_type.rb +0 -29
  38. data/lib/active_mocker/file_reader.rb +0 -11
  39. data/lib/active_mocker/model_reader.rb +0 -191
  40. data/lib/active_mocker/model_schema.rb +0 -285
  41. data/lib/active_mocker/model_schema/assemble.rb +0 -220
  42. data/lib/active_mocker/reparameterize.rb +0 -41
  43. data/lib/active_mocker/ruby_parse.rb +0 -68
  44. data/lib/active_mocker/schema_reader.rb +0 -30
  45. data/lib/active_mocker/string_reader.rb +0 -18
@@ -0,0 +1,82 @@
1
+ # _associations.erb
2
+
3
+ <%= '# belongs_to' unless belongs_to.empty? -%>
4
+
5
+ <% belongs_to.each do |meth| -%>
6
+ def <%= meth.name %>
7
+ <% association = relation_find(:name, meth.name).first -%>
8
+ read_association(:<%= meth.name %>) || write_association(:<%= meth.name %>, classes('<%= association.class_name %>').try{ |k| k.find_by(id: <%= association.foreign_key %>)})
9
+ end
10
+ def <%= meth.name %>=(val)
11
+ write_association(:<%= meth.name %>, val)
12
+ ActiveMocker::Mock::BelongsTo.new(val, child_self: self, foreign_key: :<%= meth.foreign_key %>).item
13
+ end
14
+
15
+ def build_<%= meth.name %>(attributes={}, &block)
16
+ <% association = relation_find(:name, meth.name).first -%>
17
+ <% if association -%>
18
+ association = classes('<%= association.class_name %>').try(:new, attributes, &block)
19
+ write_association(:<%= meth.name %>, association) unless association.nil?
20
+ <% end -%>
21
+ end
22
+
23
+ def create_<%= meth.name %>(attributes={}, &block)
24
+ <% association = relation_find(:name, meth.name).first -%>
25
+ <% if association -%>
26
+ association = classes('<%= association.class_name %>').try(:create,attributes, &block)
27
+ write_association(:<%= meth.name %>, association) unless association.nil?
28
+ <% end -%>
29
+ end
30
+ alias_method :create_<%= meth.name %>!, :create_<%= meth.name %>
31
+ <% end -%>
32
+
33
+ <%= '# has_one' unless has_one.empty? -%>
34
+
35
+ <% has_one.each do |meth| -%>
36
+ def <%= meth.name %>
37
+ read_association(:<%= meth.name %>)
38
+ end
39
+
40
+ def <%= meth.name %>=(val)
41
+ write_association(:<%= meth.name %>, val)
42
+ ActiveMocker::Mock::HasOne.new(val, child_self: self, foreign_key: '<%= meth.foreign_key %>').item
43
+ end
44
+
45
+ def build_<%= meth.name %>(attributes={}, &block)
46
+ <% association = relation_find(:name, meth.name).first -%>
47
+ <% if association -%>
48
+ write_association(:<%= meth.name %>, classes('<%= association.class_name %>').new(attributes, &block)) if classes('<%= association.class_name %>')
49
+ <% end -%>
50
+ end
51
+
52
+ def create_<%= meth.name %>(attributes={}, &block)
53
+ <% association = relation_find(:name, meth.name).first -%>
54
+ <% if association -%>
55
+ write_association(:<%= meth.name %>, classes('<%= association.class_name %>').new(attributes, &block)) if classes('<%= association.class_name %>')
56
+ <% end -%>
57
+ end
58
+ alias_method :create_<%= meth.name %>!, :create_<%= meth.name %>
59
+ <% end -%>
60
+
61
+ <%= '# has_many' unless has_many.empty? -%>
62
+
63
+ <% has_many.each do |meth| -%>
64
+ def <%= meth.name %>
65
+ read_association(:<%= meth.name %>, -> { ActiveMocker::Mock::HasMany.new([],foreign_key: '<%= meth.foreign_key %>', foreign_id: self.id, relation_class: classes('<%= meth.class_name %>'), source: '<%= meth.source %>') })
66
+ end
67
+
68
+ def <%= meth.name %>=(val)
69
+ write_association(:<%= meth.name %>, ActiveMocker::Mock::HasMany.new(val, foreign_key: '<%= meth.foreign_key %>', foreign_id: self.id, relation_class: classes('<%= meth.class_name %>'), source: '<%= meth.source %>'))
70
+ end
71
+ <% end -%>
72
+ <%= '# has_and_belongs_to_many' unless has_and_belongs_to_many.empty? -%>
73
+
74
+ <% has_and_belongs_to_many.each do |meth| -%>
75
+ def <%= meth.name %>
76
+ read_association(:<%= meth.name %>, ->{ ActiveMocker::Mock::HasAndBelongsToMany.new([]) })
77
+ end
78
+
79
+ def <%= meth.name %>=(val)
80
+ write_association(:<%= meth.name %>, ActiveMocker::Mock::HasAndBelongsToMany.new(val))
81
+ end
82
+ <% end -%>
@@ -0,0 +1,11 @@
1
+ # _attributes.erb
2
+ <% attributes.each do |meth| -%>
3
+ def <%= meth.name %>
4
+ read_attribute(:<%= meth.name %>)
5
+ end
6
+
7
+
8
+ def <%= meth.name %>=(val)
9
+ write_attribute(:<%= meth.name %>, val)
10
+ end
11
+ <% end -%>
@@ -0,0 +1,41 @@
1
+ #_class_methods.erb
2
+ class << self
3
+ def attributes
4
+ @attributes ||= HashWithIndifferentAccess.new(<%= attributes_with_defaults %>).merge(super)
5
+ end
6
+
7
+ def types
8
+ @types ||= ActiveMocker::Mock::HashProcess.new(<%= types_hash %>, method(:build_type)).merge(super)
9
+ end
10
+
11
+ def associations
12
+ @associations ||= <%= associations %>.merge(super)
13
+ end
14
+
15
+ def associations_by_class
16
+ @associations_by_class ||= <%= associations_by_class %>.merge(super)
17
+ end
18
+
19
+ def mocked_class
20
+ <%= class_name.inspect %>
21
+ end
22
+
23
+ private :mocked_class
24
+
25
+ def attribute_names
26
+ @attribute_names ||= <%= attribute_names %> | super
27
+ end
28
+
29
+ def primary_key
30
+ <%= primary_key.name.inspect %>
31
+ end
32
+
33
+ def abstract_class?
34
+ <%= abstract_class.inspect %>
35
+ end
36
+
37
+ def table_name
38
+ <%= table_name.inspect %> || super
39
+ end
40
+
41
+ end
@@ -0,0 +1,10 @@
1
+ <% instance_methods.each do |method| -%>
2
+ def <%= method.name %><%= "(#{method.arguments.parameters})" unless method.arguments.parameters.to_a.empty? %>
3
+ call_mock_method(method: __method__, caller: Kernel.caller, arguments: [<%= method.arguments.arguments %>])
4
+ end
5
+ <% end -%>
6
+ <% class_methods.each do |method| -%>
7
+ def self.<%= method.name %><%= "(#{method.arguments.parameters})" unless method.arguments.parameters.to_a.empty? %>
8
+ call_mock_method(method: __method__, caller: Kernel.caller, arguments: [<%= method.arguments.arguments %>])
9
+ end
10
+ <% end -%>
@@ -0,0 +1,10 @@
1
+ # _modules_constants.erb
2
+ <% constants.each do |constant| -%>
3
+ <%= constant.first %> = <%= constant.last.inspect %>
4
+ <% end -%>
5
+ <% modules[:included].each do |constant| -%>
6
+ prepend <%= constant %>
7
+ <% end -%>
8
+ <% modules[:extended].each do |constant| -%>
9
+ extend <%= constant %>
10
+ <% end -%>
@@ -0,0 +1,23 @@
1
+ # _scopes.erb
2
+ module Scopes
3
+ include <%= parent_class %>::Scopes
4
+
5
+ <% scope_methods.each do |method| -%>
6
+ def <%= method.name %><%= "(#{method.arguments.parameters})" unless method.arguments.parameters.to_a.empty? %>
7
+ ActiveMocker::LoadedMocks.find('<%= class_name %>').send(:call_mock_method, method: '<%= method.name %>', caller: Kernel.caller, arguments: [<%= method.arguments.arguments %>])
8
+ end
9
+
10
+ <% end -%>
11
+ end
12
+
13
+ extend Scopes
14
+
15
+ class ScopeRelation < ActiveMocker::Mock::Association
16
+ include <%= class_name + mock_append_name %>::Scopes
17
+ end
18
+
19
+ def self.new_relation(collection)
20
+ <%= class_name + mock_append_name %>::ScopeRelation.new(collection)
21
+ end
22
+
23
+ private_class_method :new_relation
@@ -0,0 +1,9 @@
1
+ module ActiveMocker
2
+ class NullProgress
3
+ def initialize(*)
4
+
5
+ end
6
+ def increment
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,32 @@
1
+ module ActiveMocker
2
+ class OutputCapture
3
+ def self.capture(io, &block)
4
+ case io
5
+ when :stdout
6
+ capture_stdout(&block)
7
+ when :stderr
8
+ capture_stderr(&block)
9
+ else
10
+ raise "Unknown IO #{io}"
11
+ end
12
+ end
13
+
14
+ def self.capture_stdout(&block)
15
+ captured_stream = StringIO.new
16
+ orginal_io, $stdout = $stdout, captured_stream
17
+ block.call
18
+ captured_stream.string
19
+ ensure
20
+ $stdout = orginal_io
21
+ end
22
+
23
+ def self.capture_stderr(&block)
24
+ captured_stream = StringIO.new
25
+ orginal_io, $stderr = $stderr, captured_stream
26
+ block.call
27
+ captured_stream.string
28
+ ensure
29
+ $stderr = orginal_io
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,64 @@
1
+ module ActiveMocker
2
+ class ParentClass
3
+ def initialize(parsed_source:, klasses_to_be_mocked:, mock_append_name:, active_record_base_klass: ::ActiveRecord::Base)
4
+ @parsed_source = parsed_source
5
+ @klasses_to_be_mocked = klasses_to_be_mocked
6
+ @active_record_base_klass = active_record_base_klass
7
+ @mock_append_name = mock_append_name
8
+ end
9
+
10
+ attr_reader :error
11
+
12
+ def call
13
+ if has_parent_class?
14
+ deal_with_parent
15
+ else
16
+ create_error("#{class_name} is missing a parent class.")
17
+ end
18
+ self
19
+ end
20
+
21
+ def parent_mock_name
22
+ if @parent_mock_name
23
+ "#{@parent_mock_name}#{mock_append_name}"
24
+ else
25
+ 'ActiveMocker::Mock::Base'
26
+ end
27
+ end
28
+
29
+ private
30
+ attr_reader :parsed_source,
31
+ :klasses_to_be_mocked,
32
+ :active_record_base_klass,
33
+ :mock_append_name
34
+
35
+ def deal_with_parent
36
+ if parent_class <= active_record_base_klass
37
+ @parent_mock_name = parent_class_name if klasses_to_be_mocked.include?(parent_class_name)
38
+ else
39
+ create_error("#{class_name} does not inherit from ActiveRecord::Base")
40
+ end
41
+ end
42
+
43
+ def create_error(message)
44
+ @error = OpenStruct.new(class_name: class_name,
45
+ message: message)
46
+ end
47
+
48
+ def has_parent_class?
49
+ parsed_source.has_parent_class?
50
+ end
51
+
52
+ def parent_class_name
53
+ parsed_source.parent_class_name
54
+ end
55
+
56
+ def class_name
57
+ parsed_source.class_name
58
+ end
59
+
60
+ def parent_class
61
+ parent_class_name.constantize
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,13 @@
1
+ module ActiveMocker
2
+ class Progress
3
+ def initialize(count)
4
+ @progress = ProgressBar.create(title: 'Generating Mocks',
5
+ total: count,
6
+ format: '%t |%b>>%i| %p%%')
7
+ end
8
+
9
+ def increment
10
+ @progress.increment
11
+ end
12
+ end
13
+ end
@@ -1,39 +1,31 @@
1
1
  module ActiveMocker
2
-
3
2
  class << self
4
-
5
- # Method will be deprecated in v2
6
- def self.mock(model_name, options=nil)
7
- require File.join(Config.mock_dir,
8
- "#{model_name.tableize.singularize}_mock.rb")
9
- "#{model_name}Mock".constantize
10
- end
11
-
12
3
  # Override default Configurations
13
4
  #
14
- # ActiveMocker.configure do |config|
15
- # config.schema_file = File.join(Rails.root, 'db/schema.rb')
16
- # config.model_dir = File.join(Rails.root, 'app/models')
17
- # config.mock_dir = File.join(Rails.root, 'spec/mocks')
18
- #
19
- # # If a model has a base class that still behaves like ActiveRecord but doesn't directly inherit from it add it
20
- # # to the model_base_classes array
21
- # config.model_base_classes = %w[ ActiveRecord::Base ]
22
- #
23
- # config.logger = Rails.logger
5
+ # ActiveMocker.configure do |c|
6
+ # c.model_dir= # Directory of ActiveRecord models
7
+ # c.mock_dir= # Directory to save mocks
8
+ # c.single_model_path= # Path to generate a single mock
9
+ # c.progress_bar= # False disables progress bar from sending to STDOUT
10
+ # or pass a class that takes a count in the initializer and responds to #increment.
11
+ # c.error_verbosity= # 0 = none, 1 = One line per error, 2 = More details
12
+ # c.disable_modules_and_constants= # Modules are include/extend along with constant declarations.
13
+ # # Default is false, to disable set to true.
24
14
  # end
25
15
  #
16
+ # @param [block]
17
+ # @returns self
26
18
  def configure(&block)
27
19
  Config.set(&block)
20
+ self
28
21
  end
29
-
30
22
  alias_method :config, :configure
31
23
 
32
24
  # Generates Mocks file
25
+ # @returns self
33
26
  def create_mocks
34
- Generate.new
27
+ Generate.new.call
28
+ self
35
29
  end
36
-
37
30
  end
38
-
39
31
  end
@@ -0,0 +1,16 @@
1
+ module ActiveMocker
2
+ module Rspec
3
+
4
+ # @return ActiveMocker::LoadedMocks
5
+ def active_mocker
6
+ ActiveMocker::LoadedMocks
7
+ end
8
+
9
+ # @deprecated method, will be removed in version 2.1
10
+ # Use +active_mocker.mocks.find('ClassName')+ instead
11
+ def mock_class(*args)
12
+ active_mocker.mocks.find(*args)
13
+ end
14
+
15
+ end
16
+ end
@@ -1,20 +1,22 @@
1
1
  require 'active_mocker/loaded_mocks'
2
+ require 'active_mocker/rspec'
2
3
 
3
4
  RSpec.configure do |config|
4
5
 
5
- def mock_class(class_name)
6
- return class_name.constantize if defined?(Rails) && !self.class.metadata[:active_mocker]
7
- ActiveMocker::LoadedMocks.class_name_to_mock.select { |name, mock| name == class_name }.values.first
8
- end
6
+ config.include ActiveMocker::Rspec
9
7
 
10
8
  config.before(:each, active_mocker: true) do
11
- unless ENV['RUN_WITH_RAILS'] && self.class.metadata[:rails_compatible]
12
- ActiveMocker::LoadedMocks.class_name_to_mock.each { |class_name, mock| stub_const(class_name, mock) }
9
+ unless ENV['RUN_WITH_RAILS'] && self.class.metadata[:rails_compatible]
10
+ active_mocker.mocks.each { |class_name, mock| stub_const(class_name, mock) }
13
11
  end
14
12
  end
15
13
 
16
- config.after(:all) do
17
- ActiveMocker::LoadedMocks.clear_all if self.class.metadata[:active_mocker]
14
+ config.after(:all, active_mocker: true) do
15
+ ActiveMocker::LoadedMocks.delete_all
16
+ end
17
+
18
+ config.before(:all, active_mocker: true) do
19
+ ActiveMocker::LoadedMocks.delete_all
18
20
  end
19
21
 
20
22
  end
@@ -2,7 +2,12 @@ namespace :active_mocker do
2
2
 
3
3
  desc('Rebuild mocks.')
4
4
  task :build => :environment do
5
- ActiveMocker::Generate.new
5
+ ActiveMocker.configure do |c|
6
+ c.single_model_path = ENV["MODEL"] if ENV["MODEL"]
7
+ c.progress_bar = false if ENV["MUTE_PROGRESS_BAR"]
8
+ c.error_verbosity = ENV["ERROR_VERBOSITY"].to_i if ENV["ERROR_VERBOSITY"]
9
+ c.disable_modules_and_constants = false
10
+ end.create_mocks
6
11
  end
7
12
 
8
13
  desc('Run all tests tagged active_mocker')
@@ -0,0 +1,22 @@
1
+ require 'forwardable'
2
+
3
+ module ActiveMocker
4
+ class TemplateCreator
5
+
6
+ def initialize(erb_template:, file_out: nil, binding:)
7
+ @erb_template = erb_template
8
+ @binding = binding
9
+ @file_out = file_out || Tempfile.new('TemplateModel')
10
+ end
11
+
12
+ def render
13
+ template = ERB.new(erb_template.read, nil, '>')
14
+ file_out.write template.result(binding).gsub(/\n{2,5}/, "\n\n")
15
+ file_out
16
+ end
17
+
18
+ private
19
+
20
+ attr_reader :erb_template, :binding, :file_out
21
+ end
22
+ end