bluff 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,8 @@
1
+ ## Jan 12 2012 - v0.0.4
2
+
3
+ * Bluff calls are stricter now to give us more control in the bluff definitions. A bluff call accepts a single hash argument and default block values can no longer be defined in the block signatures.
4
+ * Added initial DSL support for **requires()**, **default()**, and **defaults()**
5
+
1
6
  ## Jan 11 2012 - v0.0.3
2
7
 
3
8
  * Added architecture for multiple backend/orm support (only activerecord provided so far)
data/README.md CHANGED
@@ -1,20 +1,20 @@
1
- = bluff
1
+ # bluff
2
2
 
3
3
  * https://github.com/islandr/bluff
4
4
 
5
- == DESCRIPTION:
5
+ ## DESCRIPTION:
6
6
 
7
7
  A single source of lies for all your testing needs.
8
8
 
9
- == FEATURES/PROBLEMS:
9
+ ## FEATURES/PROBLEMS:
10
10
 
11
11
  * TODO
12
12
 
13
- == CONTRIBUTING:
13
+ ## CONTRIBUTING:
14
14
 
15
15
  Pull requests are welcome! See the DEVELOPERS section at the bottom of this page for more information.
16
16
 
17
- == SYNOPSIS:
17
+ ## OVERVIEW:
18
18
 
19
19
  My original intentions for bluff are focused on rails/activerecord but I'm open
20
20
  to other libraries if it doesn't pollute the API.
@@ -24,14 +24,14 @@ and to do so via an API that feels natural to rails/activerecord users. I favor
24
24
  a slightly more wordy API for defining bluffs that offers the full power and flexibility
25
25
  of Ruby over a cute DSL that limits customization.
26
26
 
27
- === MODEL AND DATA BLUFFS
27
+ ### MODEL AND DATA BLUFFS
28
28
 
29
- Bluff comes with a small set of predefined data bluffs (see lib/bluff/bluffs/data_bluffs.rb)
29
+ Bluff comes with a small set of predefined data bluffs (see `lib/bluff/bluffs/data_bluffs.rb`)
30
30
  but its easy to add your own.
31
31
 
32
32
  The standard practice is to define your bluffs within spec/bluffs. If you are
33
- bluffing a model, name the file *_model_\_bluff.rb*. If you need to bluff custom
34
- data, do so in *data_bluffs.rb*.
33
+ bluffing a model, name the file **_model_\_bluff.rb**. If you need to bluff custom
34
+ data, do so in **data_bluffs.rb**.
35
35
 
36
36
  A bluff is a bluff, whether it's just a piece of data or a full blown model. All bluffs
37
37
  share the same namespace (the root namespace is the *only* namespace) so choose your bluff
@@ -52,14 +52,45 @@ Bluff.for(:name) { Faker::Name.name } # Call via Bluff.name
52
52
  Bluff.for(:company_name) { Faker::Company.name }
53
53
  ```
54
54
 
55
- ==== CALLING YOUR BLUFFS
55
+ #### HELPERS
56
+
57
+ There is a very tiny DSL built into Bluff to help you out. Three methods are available:
58
+ `requires()`, `default()`, and `defaults()`.
59
+
60
+ **requires(:attribute, :attribute, ...)** takes a list of required attributes. If any of those attributes were not
61
+ provided an ArgumentError will be thrown.
62
+
63
+ **default(:attribute, :value)** takes an attribute and a default value. If the attribute was not previously defined
64
+ it will be assigned the given value. If you have multiple defaults to set, use the hash version instead **defaults({:attribute => :value, :attribute => value, ...})**
65
+
66
+ Here's an example of how you might put these two little guys to work:
67
+
68
+ ```
69
+ Bluff.for(:workspace) do |attributes|
70
+ requires(:account)
71
+
72
+ defaults({
73
+ :name => Bluff.name
74
+ })
75
+
76
+ User.new(attributes).tap do |user|
77
+ # sometimes it's easier to define the default values down here instead
78
+ user.email ||= Bluff.email({:name => user.name})
79
+ end
80
+ end
81
+ ```
82
+
83
+ Feel free to use them or huck em to the curb and just work directly with the attributes hash.
84
+
85
+ #### CALLING YOUR BLUFFS
86
+
56
87
  ```
57
88
  User.bluff # returns an unsaved instance -- could also use Bluff.user
58
89
  User.bluff! # returns a saved instance -- could also use Bluff.user!
59
- User.bluff({:name => 'Ryan'}) # supply overrides in the attributes hash
90
+ User.bluff({:name => 'Ryan'}) # supply overrides/defaults in the attributes hash
60
91
  ```
61
92
 
62
- === METHOD BLUFFS (MOCKS / STUBS)
93
+ ### METHOD BLUFFS (MOCKS / STUBS)
63
94
 
64
95
  All objects and classes are given a `bluff()` method, which is
65
96
  used for bluffing both models and methods. If given a symbol, the
@@ -76,12 +107,12 @@ user.bluff(:name).as(:value)
76
107
  The mocking abilities of bluff are no more than a thin wrapper around
77
108
  rspec-mocks. Calling `Bluff.mock('account')` is identical to calling `double('account')`
78
109
 
79
- == REQUIREMENTS:
110
+ ## REQUIREMENTS:
80
111
 
81
112
  * rspec-mocks
82
113
  * faker
83
114
 
84
- == INSTALL:
115
+ ## INSTALL:
85
116
 
86
117
  * `gem install bluff`
87
118
  * or simply add bluff to your Gemfile and run `bundle install`
@@ -92,7 +123,7 @@ group :test do
92
123
  end
93
124
  ```
94
125
 
95
- == FURTHER READING:
126
+ ## FURTHER READING:
96
127
 
97
128
  http://faker.rubyforge.org/
98
129
 
@@ -100,7 +131,7 @@ https://www.relishapp.com/rspec/rspec-mocks/
100
131
  https://www.relishapp.com/rspec/rspec-mocks/docs/method-stubs/stub-on-any-instance-of-a-class
101
132
  https://www.relishapp.com/rspec/rspec-mocks/docs/outside-rspec/configure-any-test-framework-to-use-rspec-mocks
102
133
 
103
- == DEVELOPERS:
134
+ ## DEVELOPERS:
104
135
 
105
136
  After checking out the source, run:
106
137
 
@@ -108,7 +139,7 @@ After checking out the source, run:
108
139
 
109
140
  This task will install any missing dependencies and run the tests/specs.
110
141
 
111
- == LICENSE:
142
+ ## LICENSE:
112
143
 
113
144
  (The MIT License)
114
145
 
@@ -2,8 +2,8 @@ require 'faker'
2
2
 
3
3
  # people
4
4
  Bluff.for(:name) { Faker::Name.name }
5
- Bluff.for(:username) {|name = nil| (name ||= Bluff.name).parameterize }
6
- Bluff.for(:email) {|name = nil| Faker::Internet.email(name) }
5
+ Bluff.for(:username) { (params[:name] ||= Bluff.name).parameterize }
6
+ Bluff.for(:email) { Faker::Internet.email( params[:name] || Bluff.name ) }
7
7
 
8
8
  # companies
9
9
  Bluff.for(:company_name) { Faker::Company.name }
@@ -12,5 +12,5 @@ Bluff.for(:company_name) { Faker::Company.name }
12
12
  Bluff.for(:domain) { Faker::Internet.domain_name }
13
13
 
14
14
  # words
15
- Bluff.for(:words) {|count = 3| Faker::Lorem.words(count) }
15
+ Bluff.for(:words) { Faker::Lorem.words(params[:count] || 3) }
16
16
  Bluff.for(:phrase) { Faker::Company.bs }
@@ -1,12 +1,72 @@
1
+ require 'active_support/core_ext/object/blank'
2
+ require 'active_support/core_ext/array/wrap'
3
+ require 'active_support/core_ext/array/conversions'
4
+ require 'active_support/core_ext/hash/indifferent_access'
5
+
1
6
  require 'bluff/support/backend'
7
+ require 'bluff/support/backend/active_record'
2
8
 
3
9
  module Bluff
4
10
  module Builder
11
+ class Definition
12
+ def initialize(target, attributes = {})
13
+ @target = target
14
+ @attributes = attributes
15
+
16
+ if @attributes.is_a?(Hash)
17
+ @attributes = @attributes.with_indifferent_access
18
+ else
19
+ raise ArgumentError, 'Bluff argument must be a single hash'
20
+ end
21
+ end
22
+
23
+ def attributes
24
+ @attributes
25
+ end
26
+
27
+ def attributes=(hash)
28
+ @attributes = hash
29
+ end
30
+
31
+ # can use whatever fits the situation
32
+ alias :params :attributes
33
+ alias :params= :attributes=
34
+
35
+ def execute(&block)
36
+ self.instance_exec(@attributes, &block)
37
+ end
38
+
39
+ def requires(attributes)
40
+ missing = []
41
+
42
+ Array.wrap(attributes).each do |attribute|
43
+ missing << attribute unless provided?(attribute)
44
+ end
45
+
46
+ raise ArgumentError, "#{missing.to_sentence} cannot be bluffed for #{@target}" unless missing.empty?
47
+ end
48
+
49
+ def default(attribute, value)
50
+ @attributes[attribute] = value if @attributes[attribute].blank?
51
+ end
52
+
53
+ def defaults(hash)
54
+ hash.each {|key, value| default(key, value)}
55
+ end
56
+
57
+ private
58
+ # returns true if attributes contains attribute or attribute_id
59
+ def provided?(attribute)
60
+ @attributes.is_a?(Hash) && !(@attributes[attribute].blank? && @attributes["#{attribute}_id"].blank?)
61
+ end
62
+ end
63
+
5
64
  module ClassMethods
6
- # def insist(field)
7
- # raise ArgumentError, "#{field} cannot be bluffed for #{target}"
8
- # end
9
-
65
+ # bluffs for all!
66
+ # Object.define_singleton_method :bluff do puts 'bluff on class'; end # defines class method
67
+ # Object.send :define_method, :bluff do puts 'bluff on instance'; end # defines instance method
68
+ # can pass lambda
69
+
10
70
  # options: class_name
11
71
  def for(field, options = {}, &block)
12
72
  options = {:bang => true}.merge(options)
@@ -22,13 +82,12 @@ module Bluff
22
82
  end
23
83
 
24
84
  def define_bluff(field, &block)
25
- define_singleton_method(field) do |*args|
85
+ define_singleton_method(field) do |*arguments|
26
86
  bluffed_object = nil
27
87
 
28
88
  config.max_attempts.times do
29
- bluffed_object = block.call(*args)
89
+ bluffed_object = Definition.new(field, *arguments).execute(&block) #DSL.instance_exec(*args, &block)
30
90
  break if !bluffed_object.respond_to?(:valid?) || bluffed_object.valid?
31
- puts "!!!! FAILED BLUFF -- REATTEMPTING"
32
91
  end
33
92
 
34
93
  bluffed_object
@@ -36,8 +95,8 @@ module Bluff
36
95
  end
37
96
 
38
97
  def define_bluff_bang(field)
39
- define_singleton_method "#{field}!" do |*args|
40
- send(field, *args).tap do |record|
98
+ define_singleton_method "#{field}!" do |*arguments|
99
+ send(field, *arguments).tap do |record|
41
100
  Bluff::Support::Backend.save!(record, field)
42
101
  end
43
102
  end
@@ -46,19 +105,43 @@ module Bluff
46
105
  def extend_target(field, options)
47
106
  class_name = options[:class_name] || field.to_s.camelize
48
107
 
49
- if Kernel.const_defined?(class_name)
50
- klass = Kernel.const_get(class_name)
108
+ # need to find a way to autoload existing classes that haven't been loaded yet
109
+ begin
110
+ klass = class_name.constantize
111
+ rescue NameError
112
+ # alright if it doesn't exist
113
+ end
51
114
 
115
+ if klass
52
116
  # just forward the calls back to Bluff
53
- klass.define_singleton_method :bluff do |*args|
54
- Bluff.send(field, *args)
117
+ bluff = lambda {|*args| Bluff.send(field, *args)}
118
+ bluff_bang = lambda {|*args| Bluff.send("#{field}!", *args)}
119
+
120
+ klass.singleton_class.instance_eval do
121
+ # define_method(:bluff) {|*args| dsl.instance_exec(*args, &bluff) }
122
+ # define_method(:bluff!) {|*args| dsl.instance_exec(*args, &bluff_bang) } if options[:bang]
123
+ #
124
+ define_method(:bluff) {|*args| bluff.call(*args) }
125
+ define_method(:bluff!) {|*args| bluff_bang.call(*args) } if options[:bang]
55
126
  end
127
+
128
+ # puts "def bluff(*args); Bluff.send(:#{field}, *args); end"
129
+ # klass.instance_eval { "def bluff(*args); Bluff.send(:#{field}, *args); end" }
130
+ #
131
+ # .instance_eval { "def bluff(*args); Bluff.send(:account, *args); end" }
132
+ # klass.define_singleton_method :bluff do |*args|
133
+ # Bluff.send(field, *args)
134
+ # end
135
+
136
+ #puts "bluff method is #{klass.bluff}"
56
137
 
57
- if options[:bang]
58
- klass.define_singleton_method :bluff! do |*args|
59
- Bluff.send("#{field}!", *args)
60
- end
61
- end
138
+ # if options[:bang]
139
+ # klass.define_singleton_method :bluff! do |*args|
140
+ # Bluff.send("#{field}!", *args)
141
+ # end
142
+ #
143
+ # #puts "bluff bang method is #{klass.bluff!}"
144
+ # end
62
145
  else
63
146
  # not a big deal. bluff might be data instead of a model.
64
147
  # puts "Bluff class not found: #{class_name}"
@@ -1,4 +1,6 @@
1
- class ActiveRecord::Base
1
+ module ActiveRecord
2
+ class Base
3
+ end
2
4
  end
3
5
 
4
6
  module Bluff::Support::ActiveRecord
@@ -1,3 +1,3 @@
1
1
  module Bluff
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -9,6 +9,67 @@ describe Bluff do
9
9
  Bluff.foo.should eq('bar')
10
10
  end
11
11
  end
12
+
13
+ context 'when given additional arguments' do
14
+ it 'passes the arguments for use in the bluff' do
15
+ Bluff.for(:foo) {|attributes| attributes[:value]}
16
+ Bluff.foo({:value => 'override'}).should eq('override')
17
+ end
18
+ end
19
+
20
+ it 'executes within the DSL context' do
21
+ Bluff.for(:foo) { self.class.should == Bluff::Builder::Definition } # matchers not defined on self ??
22
+ Bluff.foo
23
+ end
24
+
25
+ describe 'block' do
26
+ # context 'when an argument is required' do
27
+ # Bluff.for(:foo) {|value| value}
28
+ #
29
+ # describe 'calling the bluff without an argument should raise an error' do
30
+ # Bluff.foo
31
+ # # lambda{ Bluff.foo }.should raise_error
32
+ # end
33
+ #
34
+ # describe 'calling the bluff with an argument should pass the argument to the block' do
35
+ # Bluff.foo(99).should eq(99)
36
+ # end
37
+ # end
38
+
39
+ describe 'DSL' do
40
+ describe '.requires' do
41
+ it 'raises an error if the required attribute is missing' do
42
+ Bluff.for(:foo) {|attributes| requires(:bar) }
43
+ lambda{ Bluff.foo }.should raise_error(ArgumentError, /bar cannot be bluffed for foo/)
44
+ end
45
+
46
+ it 'does nothing if the attribute is present' do
47
+ Bluff.for(:foo) {|attributes| requires(:bar) }
48
+ lambda{ Bluff.foo({:bar => :red}) }.should_not raise_error
49
+ end
50
+
51
+ it 'checks for the foreign key if the association is missing' do
52
+ Bluff.for(:foo) {|attributes| requires(:bar) }
53
+ lambda{ Bluff.foo({:bar_id => :red}) }.should_not raise_error
54
+ end
55
+ end
56
+
57
+ # attributes.requires(:).defaults(:)
58
+
59
+ describe '.default' do
60
+ it 'assigns the given value to the attributes hash if blank' do
61
+ Bluff.for(:foo) {|attributes|
62
+ default(:bar, :red)
63
+ attributes[:bar]
64
+ }
65
+
66
+ Bluff.foo.should eq(:red)
67
+ Bluff.foo({:bar => ''}).should eq(:red)
68
+ Bluff.foo({:bar => :blue}).should eq(:blue)
69
+ end
70
+ end
71
+ end
72
+ end
12
73
  end
13
74
 
14
75
  describe '.bluff' do
@@ -1,7 +1,7 @@
1
- RSpec::Matchers.define :bluff_for do |expected|
1
+ RSpec::Matchers.define :bluff_for do |bluff_target|
2
2
  match do
3
3
  begin
4
- Bluff.send(expected)
4
+ Bluff.send(bluff_target)
5
5
  rescue
6
6
  false
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bluff
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2012-01-12 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
16
- requirement: &2164883740 !ruby/object:Gem::Requirement
16
+ requirement: &2166846800 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '3.0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *2164883740
24
+ version_requirements: *2166846800
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &2164880180 !ruby/object:Gem::Requirement
27
+ requirement: &2166845760 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '2.8'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *2164880180
35
+ version_requirements: *2166845760
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: faker
38
- requirement: &2164878820 !ruby/object:Gem::Requirement
38
+ requirement: &2166844480 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,7 +43,7 @@ dependencies:
43
43
  version: '1.0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *2164878820
46
+ version_requirements: *2166844480
47
47
  description: ''
48
48
  email:
49
49
  - ryan.mohr@gmail.com
@@ -61,8 +61,8 @@ files:
61
61
  - lib/bluff/bluffs/data_bluffs.rb
62
62
  - lib/bluff/builder.rb
63
63
  - lib/bluff/configuration.rb
64
- - lib/bluff/support/active_record.rb
65
64
  - lib/bluff/support/backend.rb
65
+ - lib/bluff/support/backend/active_record.rb
66
66
  - lib/bluff/support/support.rb
67
67
  - lib/bluff/version.rb
68
68
  - spec/models/api_spec.rb