hassox-machinist 0.1.7
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.
- data/lib/machinist.rb +88 -0
- data/lib/sham.rb +75 -0
- metadata +54 -0
data/lib/machinist.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'sham'
|
3
|
+
require File.join(File.dirname(__FILE__), "adapters", "abstract")
|
4
|
+
|
5
|
+
module Machinist
|
6
|
+
# :api: private
|
7
|
+
def self.adapters
|
8
|
+
@adapters ||= []
|
9
|
+
@_adapter_size ||= @adapters.size
|
10
|
+
unless @adapters.size == @_adapter_size
|
11
|
+
@adapters = @adapters.uniq.sort_by{|a| a.priority}.reverse
|
12
|
+
@_adapter_size = @adapters.size
|
13
|
+
end
|
14
|
+
@adapters
|
15
|
+
end
|
16
|
+
|
17
|
+
# :api: private
|
18
|
+
def self.add_adapter(adapter)
|
19
|
+
adapters << adapter
|
20
|
+
end
|
21
|
+
|
22
|
+
# :api: private
|
23
|
+
def self.adapter_for(klass)
|
24
|
+
adapters.detect{|a| a.use_for_class?(klass)} || raise("No Adapter found for #{klass}")
|
25
|
+
end
|
26
|
+
|
27
|
+
module Extensions
|
28
|
+
def self.included(base)
|
29
|
+
base.extend(ClassMethods)
|
30
|
+
end
|
31
|
+
|
32
|
+
module ClassMethods
|
33
|
+
def blueprint(&blueprint)
|
34
|
+
@blueprint = blueprint
|
35
|
+
@machinist_adapter = Machinist.adapter_for(self)
|
36
|
+
end
|
37
|
+
|
38
|
+
def make(attributes = {}, &block)
|
39
|
+
obj = make_unsaved(attributes.merge(:_save_ => true), &block)
|
40
|
+
@machinist_adapter.save(obj)
|
41
|
+
end
|
42
|
+
|
43
|
+
def make_unsaved(attributes = {})
|
44
|
+
raise "No blueprint for class #{self}" if @blueprint.nil?
|
45
|
+
lathe = Lathe.new(self, attributes)
|
46
|
+
lathe.instance_eval(&@blueprint)
|
47
|
+
returning(lathe.object) do |object|
|
48
|
+
yield object if block_given?
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class Lathe
|
55
|
+
def initialize(klass, attributes = {})
|
56
|
+
@save = !!attributes.delete(:_save_)
|
57
|
+
@object = klass.new
|
58
|
+
attributes.each {|key, value| @object.send("#{key}=", value) }
|
59
|
+
@assigned_attributes = attributes.keys.map(&:to_sym)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Undef a couple of methods that are common ActiveRecord attributes.
|
63
|
+
# (Both of these are deprecated in Ruby 1.8 anyway.)
|
64
|
+
undef_method :id
|
65
|
+
undef_method :type
|
66
|
+
|
67
|
+
attr_reader :object
|
68
|
+
|
69
|
+
def method_missing(symbol, *args, &block)
|
70
|
+
if @assigned_attributes.include?(symbol)
|
71
|
+
@object.send(symbol)
|
72
|
+
else
|
73
|
+
value = if block
|
74
|
+
block.call
|
75
|
+
elsif args.first.is_a?(Hash) || args.empty?
|
76
|
+
meth = @save ? :make : :make_unsaved
|
77
|
+
symbol.to_s.camelize.constantize.send(meth, (args.first || {}))
|
78
|
+
else
|
79
|
+
args.first
|
80
|
+
end
|
81
|
+
@object.send("#{symbol}=", value)
|
82
|
+
@assigned_attributes << symbol
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
require File.join(File.dirname(__FILE__), 'adapters/active_record') if defined?(ActiveRecord)
|
data/lib/sham.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
|
3
|
+
class Sham
|
4
|
+
@@shams = {}
|
5
|
+
|
6
|
+
# Over-ride module's built-in name method, so we can re-use it for
|
7
|
+
# generating names. This is a bit of a no-no, but we get away with
|
8
|
+
# it in this context.
|
9
|
+
def self.name(*args, &block)
|
10
|
+
method_missing(:name, *args, &block)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.method_missing(symbol, *args, &block)
|
14
|
+
if block_given?
|
15
|
+
@@shams[symbol] = Sham.new(symbol, args.pop || {}, &block)
|
16
|
+
else
|
17
|
+
sham = @@shams[symbol]
|
18
|
+
raise "No sham defined for #{symbol}" if sham.nil?
|
19
|
+
sham.fetch_value
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.reset
|
24
|
+
@@shams.values.each(&:reset)
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.define(&block)
|
28
|
+
definer = Object.new
|
29
|
+
class << definer
|
30
|
+
def method_missing(*args, &block)
|
31
|
+
Sham.send(*args, &block)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
definer.instance_eval(&block)
|
35
|
+
end
|
36
|
+
|
37
|
+
def initialize(name, options = {}, &block)
|
38
|
+
@name = name
|
39
|
+
@generator = block
|
40
|
+
@offset = 0
|
41
|
+
@unique = options.has_key?(:unique) ? options[:unique] : true
|
42
|
+
generate_values(12)
|
43
|
+
end
|
44
|
+
|
45
|
+
def reset
|
46
|
+
@offset = 0
|
47
|
+
end
|
48
|
+
|
49
|
+
def fetch_value
|
50
|
+
# Generate more values if we need them.
|
51
|
+
if @offset >= @values.length
|
52
|
+
generate_values(2 * @values.length)
|
53
|
+
raise "Can't generate more unique values for Sham.#{@name}" if @offset >= @values.length
|
54
|
+
end
|
55
|
+
returning @values[@offset] do
|
56
|
+
@offset += 1
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def generate_values(count)
|
63
|
+
@values = seeded { (1..count).map(&@generator) }
|
64
|
+
@values.uniq! if @unique
|
65
|
+
end
|
66
|
+
|
67
|
+
def seeded
|
68
|
+
begin
|
69
|
+
srand(1)
|
70
|
+
yield
|
71
|
+
ensure
|
72
|
+
srand
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
metadata
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hassox-machinist
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.7
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Pete Yandell
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-12-22 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: pete@nothat.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- lib/machinist.rb
|
26
|
+
- lib/sham.rb
|
27
|
+
has_rdoc: false
|
28
|
+
homepage: http://github.com/notahat/machinist
|
29
|
+
post_install_message:
|
30
|
+
rdoc_options: []
|
31
|
+
|
32
|
+
require_paths:
|
33
|
+
- lib
|
34
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - ">="
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: "0"
|
39
|
+
version:
|
40
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: "0"
|
45
|
+
version:
|
46
|
+
requirements: []
|
47
|
+
|
48
|
+
rubyforge_project:
|
49
|
+
rubygems_version: 1.2.0
|
50
|
+
signing_key:
|
51
|
+
specification_version: 2
|
52
|
+
summary: Fixtures aren't fun. Machinist is.
|
53
|
+
test_files: []
|
54
|
+
|