fixjour 0.1.5 → 0.1.6

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.
@@ -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