fixjour 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,21 @@
1
+ module Fixjour
2
+ class Builder
3
+ attr_reader :klass
4
+
5
+ def initialize(klass, options={})
6
+ @klass, @options = klass, options
7
+ end
8
+
9
+ def name
10
+ @name ||= (@options[:as] || @klass.name.underscore).to_s
11
+ end
12
+
13
+ def eql?(other)
14
+ @klass == other.klass
15
+ end
16
+
17
+ def hash
18
+ @klass.hash
19
+ end
20
+ end
21
+ end
@@ -1,5 +1,8 @@
1
1
  module Fixjour
2
- include Counter
2
+ def counter(key=nil)
3
+ Counter.counter(key)
4
+ end
5
+
3
6
  class << self
4
7
  include Definitions
5
8
 
@@ -13,20 +16,19 @@ module Fixjour
13
16
  # This method should always return a valid instance of
14
17
  # a model object.
15
18
  def define_builder(klass, options={}, &block)
16
- add_builder(klass)
19
+ builder = Builder.new(klass, :as => options.delete(:as))
20
+ add_builder(builder)
17
21
 
18
22
  if block_given?
19
- define_new(klass, &block)
23
+ define_new(builder, &block)
20
24
  else
21
- define_new(klass) do |proxy, overrides|
25
+ define_new(builder) do |proxy, overrides|
22
26
  proxy.new(options.merge(overrides))
23
27
  end
24
28
  end
25
29
 
26
- name = name_for(klass)
27
-
28
- define_create(name)
29
- define_valid_attributes(name)
30
+ define_create(builder)
31
+ define_valid_attributes(builder)
30
32
  end
31
33
 
32
34
  # Adds builders to Fixjour.
@@ -45,19 +47,24 @@ module Fixjour
45
47
  # Checks to see whether or not a builder is defined. Duh.
46
48
  def builder_defined?(builder)
47
49
  case builder
48
- when Class then builders.include?(builders)
49
- when String, Symbol then builders.map(&:name).include?(builder)
50
+ when Class then builders.map(&:klass).include?(builders)
51
+ when String then builders.map(&:name).include?(builder)
52
+ when Symbol then builders.map(&:name).include?(builder.to_s)
50
53
  end
51
54
  end
52
55
 
56
+ def remove(builder)
57
+ builders.delete(Builder.new(builder))
58
+ end
59
+
53
60
  private
54
61
 
55
62
  # Registers a class' builder. This allows us to make sure
56
63
  # redundant builders aren't defined, which can lead to confusion
57
64
  # when trying to figure out where objects are being created.
58
- def add_builder(klass)
59
- unless builders.add?(klass) or Fixjour.allow_redundancy
60
- raise RedundantBuilder.new("You already defined a builder for #{klass.inspect}")
65
+ def add_builder(builder)
66
+ unless builders.add?(builder) or Fixjour.allow_redundancy
67
+ raise RedundantBuilder.new("You already defined a builder for #{builder.klass.inspect}")
61
68
  end
62
69
  end
63
70
 
@@ -1,20 +1,30 @@
1
1
  module Fixjour
2
- module Counter
3
- def self.reset(key=nil)
4
- if key
5
- @counters[key] = lambda { s ||= 0; s += 1 }
6
- else
7
- @counters = Hash.new { |h,k| s ||= 0; c = lambda { s += 1 }; h[k] = c }
2
+ class Counter
3
+ class << self
4
+ def reset(key=nil)
5
+ key ? counters.delete(key) : counters.clear
6
+ end
7
+
8
+ def counter(key)
9
+ counters[key] ||= new
10
+ counters[key].next
11
+ end
12
+
13
+ private
14
+
15
+ def counters
16
+ @counters ||= {}
8
17
  end
9
18
  end
19
+
10
20
  reset
11
21
 
12
- def self.counter(key)
13
- @counters[key][]
22
+ def initialize
23
+ @value = 0
14
24
  end
15
25
 
16
- def counter(key=nil)
17
- Counter.counter(key)
26
+ def next
27
+ @value += 1
18
28
  end
19
29
  end
20
30
  end
@@ -1,25 +1,25 @@
1
1
  module Fixjour
2
2
  module Definitions
3
3
  # Defines the new_* method
4
- def define_new(klass, &block)
5
- define_method("new_#{name_for(klass)}") do |*args|
6
- Generator.new(klass, block).call(self, args.extract_options!.symbolize_keys!)
4
+ def define_new(builder, &block)
5
+ define_method("new_#{builder.name}") do |*args|
6
+ Generator.new(builder.klass, block).call(self, args.extract_options!.symbolize_keys!)
7
7
  end
8
8
  end
9
9
 
10
10
  # Defines the create_* method
11
- def define_create(name)
12
- define_method("create_#{name}") do |*args|
13
- model = send("new_#{name}", *args)
11
+ def define_create(builder)
12
+ define_method("create_#{builder.name}") do |*args|
13
+ model = send("new_#{builder.name}", *args)
14
14
  model.save!
15
15
  model
16
16
  end
17
17
  end
18
18
 
19
19
  # Defines the valid_*_attributes method
20
- def define_valid_attributes(name)
21
- define_method("valid_#{name}_attributes") do |*args|
22
- valid_attributes = send("new_#{name}", *args).attributes
20
+ def define_valid_attributes(builder)
21
+ define_method("valid_#{builder.name}_attributes") do |*args|
22
+ valid_attributes = send("new_#{builder.name}", *args).attributes
23
23
  valid_attributes.delete_if { |key, value| value.nil? }
24
24
  valid_attributes.stringify_keys!
25
25
  valid_attributes.make_indifferent!
@@ -2,28 +2,27 @@ module Fixjour
2
2
  def self.included(klass)
3
3
  klass.extend(RedundancyChecker)
4
4
  end
5
-
5
+
6
6
  # Uses method_added hook to make sure no redundant builder methods
7
7
  # get defined after a builder has already created them. For example,
8
8
  # if you have a Comment builder, this hook will ensure that any attempt
9
9
  # to define a #new_comment method will raise an exception.
10
10
  module RedundancyChecker
11
11
  BUILDER_METHOD_PATTERN = /^(new|create|valid)_(\w+)(_attributes)?$/
12
-
12
+
13
13
  def method_added(sym)
14
14
  name = sym.to_s
15
-
16
15
  if klass_name = get_klass_name(name)
17
- if Fixjour.builder_defined?(klass_name)
16
+ if Fixjour.builder_defined?(klass_name.underscore)
18
17
  raise RedundantBuilder.new("You already defined a builder for #{inspect}")
19
18
  end
20
19
  end
21
20
  end
22
-
21
+
23
22
  def get_klass_name(name)
24
23
  if match = name.match(BUILDER_METHOD_PATTERN)
25
24
  match[2].classify.gsub(/Attribute$/, '')
26
25
  end
27
26
  end
28
27
  end
29
- end
28
+ end
@@ -6,8 +6,9 @@ module Fixjour
6
6
  # * The new_* methods return new records
7
7
  # * The creation methods return objects of the proper type
8
8
  def verify!
9
- builders.each do |klass|
10
- result = new_record(klass)
9
+ builders.each do |builder|
10
+ klass = builder.klass
11
+ result = new_record(builder)
11
12
 
12
13
  unless result.valid?
13
14
  error(klass, InvalidBuilder, "returns an invalid object: #{result.errors.inspect}")
@@ -27,22 +28,22 @@ module Fixjour
27
28
  rescue => e
28
29
  error(klass, UnsavableBuilder, "raises #{e.inspect} when saved to the database")
29
30
  end
30
-
31
- unless new_record(klass).valid?
31
+
32
+ unless new_record(builder).valid?
32
33
  msg = ""
33
34
  msg << "returns invalid an invalid object after another object has been saved.\n"
34
35
  msg << "This could be caused by a validates_uniqueness_of validation in your model.\n"
35
36
  msg << "Use something like the faker gem to alleviate this issue."
36
37
  error(klass, DangerousBuilder, msg)
37
38
  end
38
-
39
+
39
40
  raise ActiveRecord::Rollback
40
41
  end
41
42
  end
42
43
  end
43
44
 
44
45
  def new_record(klass)
45
- evaluator.send("new_#{name_for(klass)}")
46
+ evaluator.send("new_#{klass.name}")
46
47
  end
47
48
 
48
49
  private
@@ -51,4 +52,4 @@ module Fixjour
51
52
  raise exception.new("The builder for #{klass} #{msg} ")
52
53
  end
53
54
  end
54
- end
55
+ end
data/lib/fixjour.rb CHANGED
@@ -12,6 +12,7 @@ require 'fixjour/errors'
12
12
  require 'fixjour/generator'
13
13
  require 'fixjour/definitions'
14
14
  require 'fixjour/counter'
15
+ require 'fixjour/builder'
15
16
  require 'fixjour/builders'
16
17
  require 'fixjour/deprecation'
17
18
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fixjour
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pat Nakajima
@@ -35,6 +35,7 @@ files:
35
35
  - lib/core_ext/hash.rb
36
36
  - lib/core_ext/object.rb
37
37
  - lib/fixjour
38
+ - lib/fixjour/builder.rb
38
39
  - lib/fixjour/builders.rb
39
40
  - lib/fixjour/counter.rb
40
41
  - lib/fixjour/definitions.rb