active_mocker 1.6.2 → 1.6.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d0fffbadcc8ae119c4d21f143ffd15bb0a39da50
4
- data.tar.gz: a571362fc14c543977695632341ee8bf998ca4ca
3
+ metadata.gz: 2b9ffc902e6ec65a43aced40034136b32162c83d
4
+ data.tar.gz: 05f4e7753af31a25d6df189bd345c8f4b966b832
5
5
  SHA512:
6
- metadata.gz: 7e997a86936372d4f9d9fe150c2ad0b6b844bbb962b36dd2db87260b48d3ed3d12e572b6710c3354225d60a2671741d0b200bbf097f7d7a076fc402706d5339d
7
- data.tar.gz: e09743ecb6b2df4f4fa40354b5e3131f8731ab21bfbaa1f24e02ef8ffa81437f1cd0c5b585e42be7c792ad24143e4c0da0b082006e5d1484696b4b3628ee6903
6
+ metadata.gz: 85bf777384443284ad2a40a38749d3c910145abc8590962a0b4f6b2682bfaf81b1a390eb29d9ff531c21052cfdb1481fd0284ed9c5e20d9b415f390d057211bf
7
+ data.tar.gz: 8d17e5205fda5b47b2f2eec67378aab8528eee1450106288c049732395b221c7fed13701159661a6e896c6e932b2413525b53368932947463970d032504c8cb3
data/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
  All notable changes to this project will be documented in this file.
3
+ ## 1.6.3 - 2014-08-14
4
+
5
+ ### Fix
6
+ - Remove check for object is defined and then deleting, it is no longer needed there are better ways to manage clearing state.
7
+ - `rake active_mock:build` failed parsing when an ActiveRecord Model had no table, example where `self.abstract_class = true` was set.
8
+ - `rake active_mock:build` failed for STI models.
9
+
10
+ ###Enhancement
11
+ - Removing methods `#hash` and `==` and using Ruby defaults gives modest performance improvements.
12
+ - Cache build_types object for small performance improvements.
13
+
3
14
  ## 1.6.2 - 2014-07-31
4
15
 
5
16
  ## Fix
data/README.md CHANGED
@@ -37,7 +37,7 @@ Examples from a real apps
37
37
 
38
38
  ---------------------------
39
39
 
40
- ## Documentation
40
+ ## Documentation [![Inline docs](http://inch-ci.org/github/zeisler/active_mocker.png?branch=master)](http://inch-ci.org/github/zeisler/active_mocker)
41
41
 
42
42
  [rdoc](http://rdoc.info/github/zeisler/active_mocker/master/ActiveMocker)
43
43
 
@@ -71,11 +71,15 @@ Or install it yourself as:
71
71
 
72
72
  ## Setup
73
73
 
74
+
75
+ See [example_rails_app](https://github.com/zeisler/active_mocker/tree/master/example_rails_app) for complete setup.
76
+
77
+
74
78
  ### Generate Mocks
75
79
 
76
80
  Running this rake task builds/rebuilds the mocks. It will be ran automatically after every schema modification. If the model changes this rake task needs to be called manually. You could add a file watcher for when your models change and have it run the rake task.
77
81
 
78
- rake active_mocker::build
82
+ rake active_mocker:build
79
83
 
80
84
  ## Usage
81
85
 
@@ -254,7 +258,7 @@ Running this rake task builds/rebuilds the mocks. It will be ran automatically a
254
258
 
255
259
 
256
260
  ### Scoped Methods
257
- * As long the mock file that holds the scope method is required it will be available but implemented.
261
+ * As long the mock file that holds the scope method is required it will be available but raise an `unimplemented error` when called.
258
262
 
259
263
  ### Managing Mocks
260
264
 
@@ -341,9 +345,9 @@ See [Documentation](http://rdoc.info/github/zeisler/active_mocker/master/ActiveM
341
345
  ### Known Limitations
342
346
  * Model names and table names must follow the default ActiveRecord naming pattern.
343
347
  * Whatever associations are setup in one mock object will not be reflected in any other objects.
344
- * There partial support for this feature coming in v1.6 when `ActiveMocker::Mock.config.experimental = true` is set.
348
+ * There's partial support for it to work more like ActiveRecord in v1.6 when `ActiveMocker::Mock.config.experimental = true` is set. When v1.7 comes out these features will be moved out of experimantal.
345
349
 
346
- * Validation are not present in mocks.
350
+ * Validation/Callbacks are not present in mocks. A Work around is putting the method into a module with required ActiveSupport/ActiveModel dependencies and make sure the code is supported by the mock.
347
351
  * Sql queries, joins, etc will never be supported.
348
352
 
349
353
  ## Inspiration
data/lib/active_mocker.rb CHANGED
@@ -24,4 +24,7 @@ require 'active_mocker/reparameterize'
24
24
  require 'active_mocker/db_to_ruby_type'
25
25
  require 'active_mocker/model_schema'
26
26
  require 'active_mocker/model_schema/generate'
27
+ require 'parser/current'
28
+ require 'unparser'
29
+ require 'active_mocker/ruby_parse'
27
30
  require 'virtus'
@@ -33,6 +33,7 @@ module ActiveMocker
33
33
  class ConstMissing
34
34
 
35
35
  def self.const_missing(name)
36
+ Logger.debug "ActiveMocker :: Debug :: const_missing #{name} from class #{self.name}.\n\t\t\t\t\t\t\t\t#{caller}\n"
36
37
  self.const_set name, Class.new(ConstMissing)
37
38
  end
38
39
 
@@ -1,3 +1,4 @@
1
+ require 'active_support/dependencies/autoload'
1
2
  require 'active_support/hash_with_indifferent_access'
2
3
  require 'active_support/core_ext/module/delegation'
3
4
  require 'active_support/inflector'
@@ -99,7 +99,8 @@ class Base
99
99
  end
100
100
 
101
101
  def build_type(type)
102
- Virtus::Attribute.build(type)
102
+ @@built_types ||= {}
103
+ @@built_types[type] ||= Virtus::Attribute.build(type)
103
104
  end
104
105
 
105
106
  def classes(klass)
@@ -256,16 +257,6 @@ class Base
256
257
  ObjectInspect.new(self.class.name, attributes).to_s
257
258
  end
258
259
 
259
- def hash
260
- attributes.hash
261
- end
262
-
263
- def ==(obj)
264
- return false if obj.nil?
265
- return hash == obj.attributes.hash if obj.respond_to?(:attributes)
266
- hash == obj.hash if obj.respond_to?(:hash)
267
- end
268
-
269
260
  module PropertiesGetterAndSetter
270
261
 
271
262
  # Returns the value of the attribute identified by <tt>attr_name</tt> after
@@ -1,5 +1,4 @@
1
1
  require 'active_mocker/mock'
2
- Object.send(:remove_const, "<%= class_name + @mock_append_name %>") if Object.const_defined?("<%= class_name + @mock_append_name %>")
3
2
 
4
3
  class <%= class_name + @mock_append_name %> < ActiveMocker::Mock::Base
5
4
  <% constants.each do |constant| -%>
@@ -1,5 +1,7 @@
1
+
1
2
  module ActiveMocker
2
3
  # @api private
4
+
3
5
  class ModelReader
4
6
 
5
7
  attr_reader :model_name, :model_dir, :file_reader
@@ -12,44 +14,68 @@ module ActiveMocker
12
14
  def parse(model_name)
13
15
  @model_name = model_name
14
16
  klass
15
- return self unless @klass == false
17
+ return self if @klass
16
18
  return false
17
19
  end
18
20
 
19
21
  def klass
20
- @klass ||= eval_file
22
+ @klass ||= eval_file(sandbox_model, file_path)
23
+ end
24
+
25
+ def sandbox_model
26
+ source = ActiveMocker::RubyParse.new(read_file)
27
+ if source.has_parent_class? && source.parent_class_name == 'ActiveRecord::Base'
28
+ source.modify_parent_class('ActiveMocker::ActiveRecord::Base')
29
+ else
30
+ load_parent_class(source.parent_class_name)
31
+ read_file
32
+ end
33
+ end
34
+
35
+ def load_parent_class(class_name)
36
+ file_name = class_name.tableize.singularize
37
+ source = ActiveMocker::RubyParse.new(read_file(file_name)).modify_parent_class('ActiveMocker::ActiveRecord::Base')
38
+ eval_file(source, file_path(file_name))
21
39
  end
22
40
 
23
- def eval_file
41
+ def module_namespace
42
+ @module ||= Module.new
43
+ end
44
+
45
+ def eval_file(string, file_path)
24
46
  failure = false
25
- begin
26
- m = Module.new
27
- m.module_eval(read_file, file_path)
28
- rescue SyntaxError => e
29
- Logger.error "ActiveMocker :: Error loading Model: #{model_name} \n \t\t\t\t\t\t\t\t`#{e}` \n"
30
- puts "ActiveMocker :: Error loading Model: #{model_name} \n \t\t\t\t\t\t\t\t`#{e}` \n"
31
- Logger.error "\t\t\t\t\t\t\t\t #{file_path}\n"
32
- puts "\t\t\t\t\t\t\t\t #{file_path}\n"
33
- failure = true
34
- rescue Exception => e
35
- Logger.error "ActiveMocker :: Error loading Model: #{model_name} \n \t\t\t\t\t\t\t\t`#{e}` \n"
36
- Logger.error "\t\t\t\t\t\t\t\t #{file_path}\n"
37
- failure = true
38
- end
39
- return m.const_get m.constants.first unless failure
40
- return false
47
+ begin
48
+
49
+ module_namespace.module_eval(string, file_path)
50
+ _klass = module_namespace.const_get(module_namespace.constants.last)
51
+ rescue SyntaxError => e
52
+ log_loading_error(e, true)
53
+ failure = true
54
+ rescue Exception => e
55
+ log_loading_error(e, false)
56
+ failure = true
57
+ end
58
+ return false if failure
59
+ _klass
60
+ end
61
+
62
+ def log_loading_error(msg, print_to_stdout=false)
63
+ main = "ActiveMocker :: Error loading Model: #{model_name} \n\t#{msg}\n"
64
+ file = "\t#{file_path}\n"
65
+ Logger.error main + file
66
+ print main + file if print_to_stdout
41
67
  end
42
68
 
43
69
  def real
44
70
  model_name.classify.constantize
45
71
  end
46
72
 
47
- def read_file
48
- file_reader.read(file_path)
73
+ def read_file(m_name=model_name)
74
+ file_reader.read(file_path(m_name))
49
75
  end
50
76
 
51
- def file_path
52
- "#{model_dir}/#{model_name}.rb"
77
+ def file_path(m_name=model_name)
78
+ "#{model_dir}/#{m_name}.rb"
53
79
  end
54
80
 
55
81
  def class_methods
@@ -74,12 +100,14 @@ module ActiveMocker
74
100
 
75
101
  def instance_methods_with_arguments
76
102
  instance_methods.map do |m|
77
- {m => klass.new.method(m).parameters }
103
+ {m => klass.instance_method(m).parameters }
78
104
  end
79
105
  end
80
106
 
81
107
  def instance_methods
82
- klass.public_instance_methods(false)
108
+ methods = klass.public_instance_methods(false)
109
+ methods << klass.superclass.public_instance_methods(false) if klass.superclass != ActiveRecord::Base
110
+ methods.flatten
83
111
  end
84
112
 
85
113
  def relationships_types
@@ -35,20 +35,22 @@ module ActiveMocker
35
35
  def run
36
36
  model_schemas = models.map do |model_name|
37
37
 
38
- model = get_model(model_name)
38
+ model = get_model(model_name)
39
39
  next if model == false
40
- table = get_table(model, model_name)
41
- attributes = build_attributes(table.fields, primary_key(table.fields, model))
40
+ table = get_table(model, model_name)
41
+ table_name = model_name
42
+ attributes = []
43
+ attributes = build_attributes(table.fields, primary_key(table.fields, model)) unless table.nil?
42
44
 
43
45
  increment_progress
44
46
 
45
- ModelSchema.new(class_name: model_name.camelize,
46
- table_name: table.name,
47
- attributes: attributes,
48
- methods: build_methods(model),
47
+ ModelSchema.new(class_name: model_name.camelize,
48
+ table_name: table_name,
49
+ attributes: attributes,
50
+ methods: build_methods(model),
49
51
  relationships: build_relationships(model),
50
- constants: model.constants,
51
- modules: model.modules)
52
+ constants: model.constants,
53
+ modules: model.modules)
52
54
 
53
55
  end
54
56
 
@@ -7,8 +7,8 @@ RSpec.configure do |config|
7
7
  ActiveMocker::LoadedMocks.class_name_to_mock.select { |name, mock| name == class_name }.values.first
8
8
  end
9
9
 
10
- config.before(:each) do
11
- if self.class.metadata[:active_mocker]
10
+ config.before(:each, active_mocker: true) do
11
+ unless ENV['RUN_WITH_RAILS'] && self.class.metadata[:rails_compatible]
12
12
  ActiveMocker::LoadedMocks.class_name_to_mock.each { |class_name, mock| stub_const(class_name, mock) }
13
13
  end
14
14
  end
@@ -0,0 +1,68 @@
1
+ module ActiveMocker
2
+
3
+ class RubyParse
4
+
5
+ attr_reader :source
6
+
7
+ def initialize(source)
8
+ @source = source
9
+ end
10
+
11
+ def is_class?
12
+ ast.type == :class
13
+ end
14
+
15
+ def class_name
16
+ Unparser.unparse(find_class.to_a[0])
17
+ end
18
+
19
+ def parent_class_name
20
+ Unparser.unparse(find_class.to_a[1])
21
+ end
22
+
23
+ def has_parent_class?
24
+ return false if find_class.nil?
25
+ find_class.to_a[1].try(:type) == :const
26
+ end
27
+
28
+ def change_class_name(class_name)
29
+ reset_nodes
30
+ nodes[0] = Parser::CurrentRuby.parse(class_name)
31
+ new_ast = ast.updated(nil, nodes, nil)
32
+ Unparser.unparse(new_ast)
33
+ end
34
+
35
+ def modify_parent_class(parent_class)
36
+ reset_nodes
37
+ if has_parent_class?
38
+ class_node = find_class.to_a.dup
39
+ class_node[1] = Parser::CurrentRuby.parse(parent_class)
40
+ new_ast = find_class.updated(nil, class_node, nil)
41
+ else
42
+ nodes[1] = nodes[0].updated(:const, [nil, parent_class.to_sym])
43
+ new_ast = ast.updated(nil, nodes, nil)
44
+ end
45
+ Unparser.unparse(new_ast)
46
+ end
47
+
48
+ def find_class
49
+ return ast if ast.try(:type) == :class
50
+ ast.to_a.select {|n| n.try(:type) == :class}.first
51
+ end
52
+
53
+ def ast
54
+ @ast ||= Parser::CurrentRuby.parse(source)
55
+ end
56
+
57
+ def nodes
58
+ @nodes ||= ast.to_a.dup
59
+ end
60
+
61
+ def reset_nodes
62
+ @nodes = nil
63
+ end
64
+
65
+ end
66
+
67
+ end
68
+
@@ -1,9 +1,20 @@
1
1
  namespace :active_mocker do
2
+
2
3
  desc('Rebuild mocks.')
3
4
  task :build => :environment do
4
5
  ActiveMocker::Generate.new
5
6
  end
6
7
 
8
+ desc('Run all tests tagged active_mocker')
9
+ task :test do
10
+ sh 'rspec --tag active_mocker'
11
+ end
12
+
13
+ desc('Run all tests tagged active_mocker and rails_compatible and will disable model stubbing')
14
+ task :rails_compatible do
15
+ sh 'RUN_WITH_RAILS=1 rspec --tag rails_compatible'
16
+ end
17
+
7
18
  end
8
19
 
9
20
  ['db:migrate'].each do |task|
@@ -1,3 +1,3 @@
1
1
  module ActiveMocker
2
- VERSION = "1.6.2"
2
+ VERSION = "1.6.3"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_mocker
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.2
4
+ version: 1.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dustin Zeisler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-31 00:00:00.000000000 Z
11
+ date: 2014-08-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -53,61 +53,75 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.4'
55
55
  - !ruby/object:Gem::Dependency
56
- name: bundler
56
+ name: parser
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '1.5'
62
- type: :development
61
+ version: '2.1'
62
+ type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '1.5'
68
+ version: '2.1'
69
69
  - !ruby/object:Gem::Dependency
70
- name: rake
70
+ name: unparser
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '10.1'
75
+ version: '0.1'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.1'
83
+ - !ruby/object:Gem::Dependency
84
+ name: bundler
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.5'
76
90
  type: :development
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
94
  - - "~>"
81
95
  - !ruby/object:Gem::Version
82
- version: '10.1'
96
+ version: '1.5'
83
97
  - !ruby/object:Gem::Dependency
84
- name: rspec
98
+ name: rake
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
- - - '='
101
+ - - "~>"
88
102
  - !ruby/object:Gem::Version
89
- version: 2.14.1
103
+ version: '10.1'
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
- - - '='
108
+ - - "~>"
95
109
  - !ruby/object:Gem::Version
96
- version: 2.14.1
110
+ version: '10.1'
97
111
  - !ruby/object:Gem::Dependency
98
- name: rspec-rails
112
+ name: rspec
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
115
  - - '='
102
116
  - !ruby/object:Gem::Version
103
- version: 2.14.2
117
+ version: '3'
104
118
  type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
107
121
  requirements:
108
122
  - - '='
109
123
  - !ruby/object:Gem::Version
110
- version: 2.14.2
124
+ version: '3'
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: sqlite3
113
127
  requirement: !ruby/object:Gem::Requirement
@@ -137,19 +151,19 @@ dependencies:
137
151
  - !ruby/object:Gem::Version
138
152
  version: '4.1'
139
153
  - !ruby/object:Gem::Dependency
140
- name: fuubar
154
+ name: rspec-rails
141
155
  requirement: !ruby/object:Gem::Requirement
142
156
  requirements:
143
157
  - - "~>"
144
158
  - !ruby/object:Gem::Version
145
- version: '1.3'
159
+ version: '3'
146
160
  type: :development
147
161
  prerelease: false
148
162
  version_requirements: !ruby/object:Gem::Requirement
149
163
  requirements:
150
164
  - - "~>"
151
165
  - !ruby/object:Gem::Version
152
- version: '1.3'
166
+ version: '3'
153
167
  - !ruby/object:Gem::Dependency
154
168
  name: rspec-given
155
169
  requirement: !ruby/object:Gem::Requirement
@@ -192,20 +206,6 @@ dependencies:
192
206
  - - "~>"
193
207
  - !ruby/object:Gem::Version
194
208
  version: '0.5'
195
- - !ruby/object:Gem::Dependency
196
- name: ruby-prof
197
- requirement: !ruby/object:Gem::Requirement
198
- requirements:
199
- - - "~>"
200
- - !ruby/object:Gem::Version
201
- version: '0.15'
202
- type: :development
203
- prerelease: false
204
- version_requirements: !ruby/object:Gem::Requirement
205
- requirements:
206
- - - "~>"
207
- - !ruby/object:Gem::Version
208
- version: '0.15'
209
209
  description: ActiveMocker creates mocks classes from ActiveRecord models. Allowing
210
210
  your test suite to run very fast by not loading Rails or hooking to a database.
211
211
  It parses the schema.rb and the defined methods on a model then generates a ruby
@@ -262,6 +262,7 @@ files:
262
262
  - lib/active_mocker/railtie.rb
263
263
  - lib/active_mocker/reparameterize.rb
264
264
  - lib/active_mocker/rspec_helper.rb
265
+ - lib/active_mocker/ruby_parse.rb
265
266
  - lib/active_mocker/schema_reader.rb
266
267
  - lib/active_mocker/string_reader.rb
267
268
  - lib/active_mocker/table.rb