active_mocker 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a57ab19178452d40493f706844efc26d8381d0b1
4
+ data.tar.gz: 360196e9eccecb12fef06ca111e002bfdd1cb5a7
5
+ SHA512:
6
+ metadata.gz: ff22e9d0e5bef978329f85385e6865dcce9803a10a703de790ce2682f7715efda58b017007a05b4ab4e0d3ac7d24a2fb9c6255d078d9a9e974ca04f0f3029f16
7
+ data.tar.gz: 6b94c9d8b9025619a45f8991cb7592a5c43dd44258822405726cbfcdffc4730eaddbd94687e02842cb5ed219c7f08d8136ad501dd771820c30748f6aa5e61c7e
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.3"
4
+ - "2.0.0"
5
+ - "2.1.0"
6
+ - "2.1.1"
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in active_mocker.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Dustin Zeisler
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,29 @@
1
+ # ActiveMocker
2
+ [![Build Status](https://travis-ci.org/zeisler/active_mocker.png?branch=master)](https://travis-ci.org/zeisler/active_mocker)
3
+ Create mocks from active record models without loading rails or running a datebase
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'active_mocker'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install active_mocker
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it ( http://github.com/<my-github-username>/active_mocker/fork )
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ task :default => 'specs'
4
+
5
+ task :specs do
6
+ system 'rspec'
7
+ end
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'active_mocker/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "active_mocker"
8
+ spec.version = ActiveMocker::VERSION
9
+ spec.authors = ["Dustin Zeisler"]
10
+ spec.email = ["dustin@zive.me"]
11
+ spec.summary = %q{Create mocks from active record models without loading rails or running a database}
12
+ spec.description = %q{Create mocks from active record models without loading rails or running a database. The Mocks methods have the same arguments as the AR model and if they change you get a error in your test.}
13
+ spec.homepage = "https://github.com/zeisler/active_mocker"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.5"
22
+ spec.add_development_dependency "rake", "~>10.1"
23
+ spec.add_development_dependency "rspec", "~>2.14"
24
+ spec.add_development_dependency "i18n", "~>0.6"
25
+ spec.add_development_dependency "activesupport", "~>4.0"
26
+
27
+ #spec.add_development_dependency "debase", "~>0.0"
28
+ #spec.add_development_dependency "ruby-debug-ide", "~>0.4"
29
+
30
+ end
@@ -0,0 +1,5 @@
1
+ require "active_mocker/version"
2
+
3
+ module ActiveMocker
4
+ # Your code goes here...
5
+ end
@@ -0,0 +1,12 @@
1
+ $:.unshift File.expand_path('../../', __FILE__)
2
+ require 'active_mocker/active_record/scope'
3
+ require 'active_mocker/active_record/relationships'
4
+
5
+ module ActiveMocker
6
+ module ActiveRecord
7
+ class Base
8
+ extend Scope
9
+ extend Relationships
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,34 @@
1
+ require 'ostruct'
2
+
3
+ module Relationships
4
+
5
+ def relationships
6
+ OpenStruct.new({has_many: @has_many ||= [],
7
+ has_one: @has_one ||= [],
8
+ belongs_to: @belongs_to ||= [],
9
+ has_and_belongs_to_many: @has_and_belongs_to_many ||= []})
10
+ end
11
+
12
+ private
13
+
14
+ def has_many(*args)
15
+ @has_many ||= []
16
+ @has_many.push args
17
+ end
18
+
19
+ def has_one(*args)
20
+ @has_one ||= []
21
+ @has_one.push args
22
+ end
23
+
24
+ def belongs_to(*args)
25
+ @belongs_to ||= []
26
+ @belongs_to.push args
27
+ end
28
+
29
+ def has_and_belongs_to_many(*args)
30
+ @has_and_belongs_to_many ||= []
31
+ @has_and_belongs_to_many.push args
32
+ end
33
+
34
+ end
@@ -0,0 +1,81 @@
1
+ module ActiveMocker
2
+ module ActiveRecord
3
+
4
+ class Schema
5
+
6
+ def self.define(version: version, &block)
7
+ search_result = search_cache(@table_search)
8
+ search_result unless search_result.nil?
9
+ schema = parse
10
+ schema.instance_eval(&block)
11
+ add_to_cache schema.tables.first
12
+ schema.tables.first
13
+ end
14
+
15
+ def self.parse
16
+ SchemaParser.new(@table_search)
17
+ end
18
+
19
+ def self.add_to_cache(table)
20
+ @@tables_cache ||= []
21
+ @@tables_cache << table unless table.nil?
22
+ end
23
+
24
+ def self.search_cache(table_name)
25
+ @@tables_cache ||= []
26
+ @@tables_cache.find do |h|
27
+ h.name == table_name
28
+ end
29
+ end
30
+
31
+ def self.clear_cache
32
+ @@tables_cache = []
33
+ end
34
+
35
+ def self.search(table_name)
36
+ @table_search = table_name
37
+ end
38
+
39
+ end
40
+
41
+ class SchemaParser
42
+
43
+ attr_reader :tables, :table_search
44
+
45
+ def initialize(table_search)
46
+ @table_search = table_search
47
+ @tables = []
48
+
49
+ end
50
+
51
+ def create_table(name, options={}, &block)
52
+ tables << ActiveMocker::Table.new(name, CreateTable.new.instance_eval(&block)) if name == table_search
53
+ end
54
+
55
+ def method_missing(meth, *args)
56
+ end
57
+
58
+ end
59
+ end
60
+
61
+ class CreateTable
62
+
63
+ attr_reader :fields
64
+
65
+ def initialize
66
+ @fields = []
67
+ end
68
+
69
+ def method_missing(meth, *args)
70
+ base_field meth, args
71
+ end
72
+
73
+ def base_field(type, args)
74
+ fields << Field.new(name: args.shift, type: type, options: args)
75
+ end
76
+
77
+ end
78
+
79
+ end
80
+
81
+
@@ -0,0 +1,12 @@
1
+ module Scope
2
+
3
+ def scope(method_name, proc)
4
+ singleton_class.class_eval do
5
+ params = Reparameterize.call(proc.parameters)
6
+ block = eval("lambda { |#{params}| }")
7
+ define_method(method_name, block)
8
+ end
9
+ end
10
+
11
+ end
12
+
@@ -0,0 +1,170 @@
1
+ module ActiveMocker
2
+
3
+ #TODO DRY up method creation
4
+ #TODO have instance variable array for instance method
5
+ #TODO have class variable array for class method
6
+ #TODO enable support for active_hash as base class
7
+ #TODO work on options interface
8
+
9
+ class Base
10
+
11
+ attr_reader :model_name,
12
+ :model_options,
13
+ :options_schema,
14
+ :mass_assignment,
15
+ :model_relationships,
16
+ :schema_attributes,
17
+ :model_methods
18
+
19
+ def initialize(options={})
20
+ @schema_attributes = options.fetch(:schema_attributes, true)
21
+ @model_relationships = options.fetch(:model_relationships, true)
22
+ @model_methods = options.fetch(:model_methods, true)
23
+ @mass_assignment = options.fetch(:mass_assignment, true)
24
+ @model_options = options[:model]
25
+ @options_schema = options[:schema]
26
+ end
27
+
28
+ def mock(model_name)
29
+ @model_name = model_name
30
+ mock_class
31
+ end
32
+
33
+ def model_definition
34
+ return @model_definition unless @model_definition.nil?
35
+ @model_definition = ModelReader.new(model_options).parse(model_file_name)
36
+ end
37
+
38
+ def model_file_name
39
+ model_name.tableize.singularize
40
+ end
41
+
42
+ def table_definition
43
+ table_name = model_name.tableize
44
+ table = SchemaReader.new(options_schema).search(table_name)
45
+ raise "#{table_name} table not found." if table.nil?
46
+ return table
47
+ end
48
+
49
+ def mock_class
50
+ add_method_mock_of
51
+ add_instance_methods if model_methods
52
+ add_mock_instance_method if model_methods
53
+ add_relationships if model_relationships
54
+ add_class_methods if model_methods
55
+ add_column_names_method if schema_attributes
56
+ add_table_attributes if schema_attributes
57
+ create_initializer if mass_assignment
58
+ return @klass
59
+ end
60
+
61
+ def create_initializer
62
+ klass = create_klass
63
+ klass.instance_eval do
64
+ define_method('initialize') do |options={}|
65
+ options.each {|method, value| send("#{method}=", value)}
66
+ end
67
+ end
68
+ end
69
+
70
+ def add_relationships
71
+ klass = create_klass
72
+ model_definition.relationships.each do |m|
73
+ klass.instance_variable_set("@#{m}", nil)
74
+ klass.class_eval { attr_accessor m }
75
+ end
76
+ end
77
+
78
+ def add_method_mock_of
79
+ klass = create_klass
80
+ klass.class_variable_set(:@@model_name, model_name)
81
+ klass.instance_eval do
82
+ define_method(:mock_of) {klass.class_variable_get :@@model_name}
83
+ end
84
+ end
85
+
86
+ def add_table_attributes
87
+ klass = create_klass
88
+ table_definition.column_names.each do |m|
89
+ klass.instance_variable_set("@#{m}", nil)
90
+ klass.class_eval { attr_accessor m }
91
+ end
92
+ end
93
+
94
+ def add_instance_methods
95
+ klass = create_klass
96
+ model_definition.instance_methods_with_arguments.each do |method|
97
+ m = method.keys.first
98
+ params = Reparameterize.call(method.values.first)
99
+ params_pass = Reparameterize.call(method.values.first, true)
100
+ klass.instance_variable_set("@#{m}", eval_lambda(params, %Q[raise "##{m} is not Implemented for Class: #{klass.name}"]))
101
+ block = eval_lambda(params, %Q[ self.class.instance_variable_get("@#{m}").call(#{params_pass})])
102
+ klass.instance_eval do
103
+ define_method(m, block)
104
+ end
105
+ end
106
+ end
107
+
108
+ def eval_lambda(arguments, block)
109
+ eval(%Q[ ->(#{arguments}){ #{block} }])
110
+ end
111
+
112
+ def add_mock_instance_method
113
+ klass = create_klass
114
+ klass.singleton_class.class_eval do
115
+ define_method(:mock_instance_method) do |method, &block|
116
+ klass.instance_variable_set("@#{method.to_s}", block)
117
+ end
118
+ end
119
+ end
120
+
121
+ def add_class_methods
122
+ klass = create_klass
123
+ model_definition.class_methods.each do |m|
124
+ klass.singleton_class.class_eval do
125
+ define_method(m) do
126
+ raise "::#{m} is not Implemented for Class: #{klass.name}"
127
+ end
128
+ end
129
+ end
130
+ end
131
+
132
+ def add_column_names_method
133
+ klass = create_klass
134
+ table = table_definition
135
+ klass.singleton_class.class_eval do
136
+ define_method(:column_names) do
137
+ table.column_names
138
+ end
139
+ end
140
+ end
141
+
142
+ def create_klass
143
+ @klass ||= const_class
144
+ end
145
+
146
+ def const_class
147
+ remove_const(mock_class_name) if class_exists? mock_class_name
148
+ return Object.const_set(mock_class_name, Class.new) unless Object.const_defined?(mock_class_name)
149
+ return Object.const_get(mock_class_name, false)
150
+ end
151
+
152
+ def remove_const(class_name)
153
+ Object.send(:remove_const, class_name)
154
+ end
155
+
156
+ def class_exists?(class_name)
157
+ klass = Module.const_get(class_name)
158
+ return klass.is_a?(Class)
159
+ rescue NameError
160
+ return false
161
+ end
162
+
163
+ def mock_class_name
164
+ "#{model_name}Mock"
165
+ end
166
+
167
+ end
168
+
169
+ end
170
+