backyard 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ pkg/*
2
+ *.gem
3
+
4
+ .bundle
5
+ .rvmrc
6
+ .yardoc/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in backyard.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,46 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ backyard (0.0.1)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ activerecord (2.3.10)
10
+ activesupport (= 2.3.10)
11
+ activesupport (2.3.10)
12
+ builder (3.0.0)
13
+ cucumber (0.10.0)
14
+ builder (>= 2.1.2)
15
+ diff-lcs (~> 1.1.2)
16
+ gherkin (~> 2.3.2)
17
+ json (~> 1.4.6)
18
+ term-ansicolor (~> 1.0.5)
19
+ diff-lcs (1.1.2)
20
+ factory_girl (1.3.2)
21
+ gherkin (2.3.3)
22
+ json (~> 1.4.6)
23
+ json (1.4.6)
24
+ rspec (2.4.0)
25
+ rspec-core (~> 2.4.0)
26
+ rspec-expectations (~> 2.4.0)
27
+ rspec-mocks (~> 2.4.0)
28
+ rspec-core (2.4.0)
29
+ rspec-expectations (2.4.0)
30
+ diff-lcs (~> 1.1.2)
31
+ rspec-mocks (2.4.0)
32
+ sqlite3 (1.3.3)
33
+ term-ansicolor (1.0.5)
34
+ yard (0.6.4)
35
+
36
+ PLATFORMS
37
+ ruby
38
+
39
+ DEPENDENCIES
40
+ activerecord
41
+ backyard!
42
+ cucumber
43
+ factory_girl
44
+ rspec
45
+ sqlite3
46
+ yard
data/History.txt ADDED
@@ -0,0 +1,16 @@
1
+ == In Git
2
+
3
+ === New Features
4
+
5
+ === Bugfixes
6
+
7
+ == 0.0.1 (24.01.2011)
8
+
9
+ === New Features
10
+ * define the attributes, which name your model [Yves Senn]
11
+ * define the name of your model with a block [Yves Senn]
12
+ * basic API for storing, accessing and building named models [Yves Senn]
13
+ * factory_girl support [Yves Senn]
14
+
15
+ === Bugfixes
16
+ * reload models before the return [Yves Senn]
data/README.md ADDED
@@ -0,0 +1,97 @@
1
+ # Backyard
2
+
3
+ this project is in a 'work in progress' state. The object creation currently only works with factory_girl.
4
+
5
+ ## Installation
6
+
7
+ in your Gemfile:
8
+
9
+ gem 'backyard'
10
+
11
+ to configure backyard, you need to create a backyard.rb file in your features/support directory:
12
+ require 'backyard/cucumber'
13
+
14
+ Backyard.configure do
15
+ # application specific configuration
16
+ name_attribute :username, :for => :user
17
+ name_attribute :title, :for => [:post, :comment]
18
+ end
19
+
20
+ ## Usage
21
+
22
+ Backyard provides a simple dsl to name the models in your cucumber scenarios.
23
+
24
+ put_model(:post, 'How to use Backyard') # create and store a new Post model named 'How to use Backyard'
25
+ put_model(:post, 'I am published', {:published => true}) # you can pass additional options for the factory
26
+
27
+ my_comment = Comment.first
28
+ put_model(my_comment, 'My Comment') # you can also store existing models
29
+
30
+ Backyard keeps track of your saved models and you can access them from all the step definitions:
31
+
32
+ get_model(:post, 'How to use Backyard') # returns the stored post instance
33
+
34
+ If you want to write step definitions, which do not care if the model you are referencing exists then you can use the `model´ method. It will check if the model with the given name exists and if not, it will create a new model for you.
35
+
36
+ model(:user, 'Tester') # this will return the user called 'Tester' if one has been crated, otherwise it will create a new model for you
37
+ model(:user, 'Gardener', {:approved => true}) # you can also pass additional attributes for the factories
38
+
39
+ ## Examples
40
+
41
+ The best way, to get an idea of backyard in action, is to peek inside the [cucumber features](https://github.com/senny/backyard/tree/master/features).
42
+
43
+ ## Configuration
44
+
45
+ Backyard needs to know how to name your models correctly. You can define the rules using the `Backyard.configure` method:
46
+
47
+ Backyard.configure do
48
+ name_attribute :title, :for => :article
49
+ end
50
+
51
+ # Examples
52
+ put_model(:article, 'Getting Started with Rails') # this creates an Article instance with the titel: 'Getting Started with Rails'
53
+ model(:article, 'Getting Started with Rails') # returns the article created above
54
+ model(:article, 'Upgrading to Rails 3') # since no article with the given name has been created it will create one.
55
+
56
+ There are situations when the name of your model is not as simple as setting an attribute. In these circumstances you can register a block to set the name of your model accordingly:
57
+
58
+ Backyard.configure do
59
+ name_for :owner do |name|
60
+ { :user => model(:user, name, {:username => name}) }
61
+ end
62
+ end
63
+
64
+ If all users in your system are named with the username attribute you could use the following configuration:
65
+
66
+ Backyard.configure do
67
+ name_attribute :username, :for => :user
68
+
69
+ name_for :owner do |name|
70
+ { :user => model(:user, name) }
71
+ end
72
+ end
73
+
74
+ # Examples
75
+ put_model(:user, 'John') # creates a User with username: 'John'
76
+ put_model(:owner, 'Jane') # creates a Owner with an associated User, which has the username: 'Jane'
77
+
78
+ This will still create Owner models with an associated user, where the username is set to the name of the created Owner model. This configuration has the advantage, that the username is also beeing set if you just create a User model.
79
+
80
+ ## Community
81
+
82
+ ### Got a question?
83
+
84
+ Just send me a message and I'll try to get to you as soon as possible.
85
+
86
+ ### Found a bug?
87
+
88
+ Please register a new issue.
89
+
90
+ ### Fixed something?
91
+
92
+ 1. Fork backyard
93
+ 2. Create a topic branch - `git checkout -b my_branch`
94
+ 3. Make your changes and update the History.txt file
95
+ 4. Push to your branch - `git push origin my_branch`
96
+ 5. Send me a pull-request for your topic branch
97
+ 6. That's it!
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
data/backyard.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "backyard/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "backyard"
7
+ s.version = Backyard::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Yves Senn"]
10
+ s.email = ["yves.senn@gmail.com"]
11
+ s.homepage = "http://rubygems.org/gems/backyard"
12
+ s.summary = %q{manage the models in your cucumbers with ease}
13
+ s.description = %q{backyard allows you to name the models in your cucumber scenarios.}
14
+
15
+ s.rubyforge_project = "backyard"
16
+
17
+ s.add_development_dependency "rspec"
18
+ s.add_development_dependency "cucumber"
19
+ s.add_development_dependency "factory_girl"
20
+ s.add_development_dependency "activerecord"
21
+ s.add_development_dependency "sqlite3"
22
+ s.add_development_dependency "yard"
23
+
24
+ s.files = `git ls-files`.split("\n")
25
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
26
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
27
+ s.require_paths = ["lib"]
28
+ end
data/cucumber.yml ADDED
@@ -0,0 +1,8 @@
1
+ <%
2
+ rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : ""
3
+ rerun_opts = rerun.to_s.strip.empty? ? "--format progress features" : "--format pretty #{rerun}"
4
+ std_opts = "--format progress features --strict --tags ~@wip"
5
+ %>
6
+ default: <%= std_opts %>
7
+ wip: --tags @wip:3 --wip features
8
+ rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip
@@ -0,0 +1,65 @@
1
+ Feature: backyard should work with FactoryGirl
2
+
3
+ Background:
4
+ Given I use the factory_girl adapter for backyard
5
+
6
+ Scenario: store and retrieve an object
7
+ When I store the user "John" in the backyard
8
+ Then the backyard should have 1 stored users
9
+ And the backyard should have a stored user named "John"
10
+
11
+ Scenario: store multiple objects
12
+ When I store the following users in the backyard:
13
+ | Name |
14
+ | John |
15
+ | Jane |
16
+ | Jackob |
17
+ Then the backyard should have 3 stored users
18
+ And the backyard should have a stored user named "John"
19
+ And the backyard should have a stored user named "Jane"
20
+ And the backyard should have a stored user named "Jackob"
21
+
22
+ Scenario: store associated models
23
+ When I store the following accounts in the backyard:
24
+ | Description | Owner |
25
+ | Taxes | John |
26
+ | John's Savings | John |
27
+ | Jane's Savings | Jane |
28
+ Then the backyard should have 2 stored users
29
+ And the backyard should have 3 stored accounts
30
+ And the account "Taxes" should be owned by "John"
31
+ And the account "John's Savings" should be owned by "John"
32
+ And the account "Jane's Savings" should be owned by "Jane"
33
+
34
+ Scenario: use the backyard name as model attribute
35
+ Given I have the following backyard configuration:
36
+ """
37
+ Backyard.configure do
38
+ name_attribute :description, :for => :account
39
+ end
40
+ """
41
+ When I store the account "Holidays" in the backyard
42
+ Then the account "Holidays" should have the description "Holidays"
43
+
44
+ Scenario: advanced configuration for model names
45
+ Given I have the following backyard configuration:
46
+ """
47
+ Backyard.configure do
48
+ name_for :user do |name|
49
+ {:username => name,
50
+ :email => "#{name.downcase.gsub(/\s/, '.')}@gmail.com"}
51
+ end
52
+ end
53
+ """
54
+ When I store the user "John Doe" in the backyard
55
+ Then the user "John Doe" should have the username "John Doe"
56
+ And the user "John Doe" should have the email "john.doe@gmail.com"
57
+
58
+ Scenario: the backyard is empty by default
59
+ Then the backyard should have 0 stored users
60
+ Then the backyard should have 0 stored accounts
61
+
62
+ Scenario: the backyard always returns updated models
63
+ When I store the user "John" in the backyard
64
+ And I set "John"'s username to "John the man" using a sql query
65
+ Then the user "John" should have the username "John the man"
@@ -0,0 +1,20 @@
1
+ When /I store the following accounts in the backyard:/ do |accounts_table|
2
+ accounts_table.hashes.each do |row|
3
+ attributes = {}
4
+
5
+ if row['Owner'].present?
6
+ model(:user, row['Owner'])
7
+ attributes[:owner] = model(:user, row['Owner'])
8
+ end
9
+
10
+ put_model(:account, row['Description'], attributes)
11
+ end
12
+ end
13
+
14
+ Then /^the account "([^"]*)" should be owned by "([^"]*)"$/ do |account_name, owner_name|
15
+ get_model(:account, account_name).owner.should == get_model(:user, owner_name)
16
+ end
17
+
18
+ Then /^the account "([^"]*)" should have the description "([^"]*)"$/ do |account_name, description|
19
+ get_model(:account, account_name).description.should == description
20
+ end
@@ -0,0 +1,25 @@
1
+ def backyard_model
2
+ '(user|account)s?'
3
+ end
4
+
5
+ Given /^I use the factory_girl adapter for backyard$/ do
6
+ require 'factory_girl'
7
+ Factory.find_definitions
8
+ Backyard.config.use_adapter :factory_girl
9
+ end
10
+
11
+ Given /^I have the following backyard configuration:$/ do |string|
12
+ eval(string)
13
+ end
14
+
15
+ When /^I store the #{backyard_model} "([^"]*)" in the backyard$/ do |model_type, model_name|
16
+ put_model(model_type, model_name)
17
+ end
18
+
19
+ Then /^the backyard should have (\d+) stored #{backyard_model}$/ do |amount, model_type|
20
+ get_models(model_type).should have(amount.to_i).item
21
+ end
22
+
23
+ Then /^the backyard should have a stored #{backyard_model} named "([^"]*)"$/ do |model_type, model_name|
24
+ get_model(model_type, model_name).should_not be_nil
25
+ end
@@ -0,0 +1,16 @@
1
+ When /^I store the following users in the backyard:$/ do |users_table|
2
+ users_table.hashes.each do |row|
3
+ attributes = {}
4
+ put_model(:user, row['Name'], attributes)
5
+ end
6
+ end
7
+
8
+ When /^I set "([^"]*)"'s username to "([^"]*)" using a sql query$/ do |user_name, new_username|
9
+ user = model(:user, user_name)
10
+ User.connection.execute("UPDATE users SET username = '#{new_username}' WHERE id = #{user.id}")
11
+ end
12
+
13
+ Then /^the user "([^"]*)" should have the (username|email) "([^"]*)"$/ do |user_name, attribute, value|
14
+ user = get_model(:user, user_name)
15
+ user.send(attribute).should == value
16
+ end
@@ -0,0 +1 @@
1
+ require 'backyard/cucumber'
@@ -0,0 +1,13 @@
1
+ require 'bundler'
2
+ begin
3
+ Bundler.setup(:default, :development)
4
+ rescue Bundler::BundlerError => e
5
+ $stderr.puts e.message
6
+ $stderr.puts "Run `bundle install` to install missing gems"
7
+ exit e.status_code
8
+ end
9
+
10
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib')
11
+ require 'backyard'
12
+
13
+ require 'rspec/expectations'
@@ -0,0 +1,13 @@
1
+ class Backyard::Adapter::FactoryGirl < Backyard::Adapter
2
+
3
+ def class_for_type(model_type)
4
+ factory = ::Factory.factories[model_type.to_sym]
5
+ raise ArgumentError, "no factory for: #{model_type}\ngot: #{::Factory.factories.keys}" unless factory
6
+ factory.build_class
7
+ end
8
+
9
+ def create(model_type, attributes)
10
+ Factory(model_type, attributes)
11
+ end
12
+
13
+ end
@@ -0,0 +1,17 @@
1
+ module Backyard
2
+ class Adapter
3
+
4
+ def class_for_type(model_type)
5
+ model_type.to_s.split('_').map!{ |w| w.capitalize }.join
6
+ end
7
+
8
+ def generate_model_name(model_type)
9
+ "#{model_type.to_s.capitalize} #{Time.now.to_f}"
10
+ end
11
+
12
+ def create(model_type, attributes)
13
+ raise NotImplementedError
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,51 @@
1
+ module Backyard
2
+ class Configuration
3
+
4
+ def initialize
5
+ @model_configuration ||= {}
6
+ end
7
+
8
+ def name_attribute(attribute, options = {})
9
+ raise "missing the :for options" unless options.has_key?(:for)
10
+ [*options[:for]].each do |model_type|
11
+ model = adapter_instance.class_for_type(model_type)
12
+ config_for(model).name_attributes << attribute
13
+ end
14
+ end
15
+
16
+ def name_for(*model_types, &block)
17
+ model_types.each do |model_type|
18
+ klass = adapter_instance.class_for_type(model_type)
19
+ config_for(klass).name_blocks << block
20
+ end
21
+ end
22
+
23
+ def use_adapter(adapter)
24
+ @adapter = adapter
25
+ end
26
+
27
+ def config_for(model_type)
28
+ @model_configuration[model_type] ||= Model.new
29
+ end
30
+
31
+ def adapter_instance
32
+ return @adapter_instance if @adapter_instance
33
+ @adapter ||= :factory_girl
34
+ require File.join('backyard', 'adapter', "#{@adapter}")
35
+ adapter_class = @adapter.to_s.split('_').map!{ |w| w.capitalize }.join
36
+ @adapter_instance = eval "Backyard::Adapter::#{adapter_class}.new"
37
+ end
38
+
39
+ class Model
40
+ attr_writer :name_attributes, :name_blocks
41
+ def name_attributes
42
+ @name_attributes ||= []
43
+ end
44
+
45
+ def name_blocks
46
+ @name_blocks ||= []
47
+ end
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,3 @@
1
+ require 'backyard'
2
+
3
+ World(Backyard::Session)
@@ -0,0 +1,24 @@
1
+ module Backyard
2
+ class ModelStore
3
+
4
+ def initialize
5
+ @store ||= {}
6
+ end
7
+
8
+ def put(name, object)
9
+ @store[object.class] ||= {}
10
+ @store[object.class][name] = object
11
+ end
12
+
13
+ def get(klass, name)
14
+ models = @store[klass]
15
+ unless models.nil?
16
+ models[name]
17
+ end
18
+ end
19
+
20
+ def get_collection(klass)
21
+ @store[klass] || []
22
+ end
23
+ end # END ModelStore
24
+ end # END Backyard
@@ -0,0 +1,110 @@
1
+ module Backyard
2
+ module Session
3
+
4
+ # Put a model in the backyard.
5
+ #
6
+ # @overload put_model(type, name, attributes)
7
+ # creates an instance from type 'type' and saved it under the
8
+ # passed name. The attributes are forwarded to the object creation
9
+ # @param [Symbol] type the type of object that should get created
10
+ # @param [String] name the name for the newly created object
11
+ # @param [Hash] attributes additional parameters for the object creation
12
+ # @overload put_model(object, name)
13
+ # stores the given object under 'name'
14
+ # @param [Object] object the object to store
15
+ # @param [String] name the name for the object
16
+ # @return [Object] the object, which was stored
17
+ def put_model(model_type, name = nil, attributes = {})
18
+ model_name = name.nil? ? adapter.generate_model_name(model_type) : name
19
+ obj = if model_type.is_a?(String) || model_type.is_a?(Symbol)
20
+ klass = class_for_type(model_type)
21
+ attributes = apply_model_config(klass, model_name).merge(attributes)
22
+ adapter.create(model_type, attributes)
23
+ else
24
+ model_type
25
+ end
26
+ model_store.put(model_name, obj)
27
+ end
28
+
29
+ # Retrieve a stored object from the backyard.
30
+ #
31
+ # @param [Symbol] type the type of the object to retrieve
32
+ # @param [String] name the name of the object to retrieve
33
+ # @return [Object, nil] the object with the given type and name
34
+ def get_model(model_type, name)
35
+ klass = class_for_type(model_type)
36
+ result = model_store.get(klass, name)
37
+ reload_model(result)
38
+ end
39
+
40
+ # Check if a model is stored in the backyard.
41
+ #
42
+ # @param [Symbol] type the type of the object
43
+ # @param [String] name the name of the object
44
+ # @return [true, false]
45
+ def model_exists?(model_type, name)
46
+ get_model(model_type, name) != nil
47
+ end
48
+
49
+ # This method is used when you don't care if you get an existing
50
+ # instance or if a new one is beeing created.
51
+ #
52
+ # @see #get_model
53
+ # @see #put_model
54
+ #
55
+ # @param [Symbol] model_type the type of the object
56
+ # @param [String] name the name of the object
57
+ # @return [Object] an object with the given type and name
58
+ def model(model_type, name, attributes = {})
59
+ if model_exists?(model_type, name)
60
+ get_model(model_type, name)
61
+ else
62
+ put_model(model_type, name, attributes)
63
+ end
64
+ end
65
+
66
+ # Retrieve all objects for a given type.
67
+ #
68
+ # @param [Symbol] type the type of the objects to retrieve
69
+ # @return [Array<Object>] an array of objects of the given type
70
+ def get_models(model_type)
71
+ model_store.get_collection class_for_type(model_type)
72
+ end
73
+
74
+ def model_store
75
+ @store ||= ModelStore.new
76
+ end
77
+
78
+ protected
79
+
80
+ def adapter
81
+ @adapter ||= Backyard.config.adapter_instance
82
+ end
83
+
84
+ def reload_model(model)
85
+ if model.respond_to?(:reload)
86
+ model.reload
87
+ else
88
+ model
89
+ end
90
+ end
91
+
92
+ def class_for_type(model_type)
93
+ klass = if model_type.kind_of?(Class)
94
+ model_type
95
+ else
96
+ adapter.class_for_type(model_type)
97
+ end
98
+ end
99
+
100
+ def apply_model_config(klass, model_name)
101
+ model_config = Backyard.config.config_for(klass)
102
+ name_attributes = model_config.name_attributes.map { |attribute| [attribute, model_name]}
103
+ block_attributes = model_config.name_blocks.inject({}) do |attrs, block|
104
+ attrs.merge(instance_exec model_name, &block)
105
+ end
106
+ Hash[name_attributes].merge(block_attributes)
107
+ end
108
+
109
+ end
110
+ end
@@ -0,0 +1,3 @@
1
+ module Backyard
2
+ VERSION = "0.0.1"
3
+ end
data/lib/backyard.rb ADDED
@@ -0,0 +1,16 @@
1
+ require 'backyard/configuration'
2
+ require 'backyard/adapter'
3
+ require 'backyard/model_store'
4
+ require 'backyard/session'
5
+
6
+ module Backyard
7
+ def self.configure(&block)
8
+ @config = Backyard::Configuration.new
9
+ @config.instance_eval(&block)
10
+ end
11
+
12
+ def self.config
13
+ @config ||= Backyard::Configuration.new
14
+ @config
15
+ end
16
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe Backyard::Adapter::FactoryGirl do
4
+
5
+ describe "#create" do
6
+ it "should delegate to factory_girl" do
7
+ subject.should_receive(:Factory).with(:entry, {:name => '123 Entry'})
8
+ subject.create :entry, {:name => '123 Entry'}
9
+ end
10
+ end
11
+
12
+ describe "#class_for_type" do
13
+ it "should work with a factory where the class is specified as text" do
14
+ subject.class_for_type(:my_string_factory).should == String
15
+ end
16
+
17
+ it "should work with a factory where the class is specified as an Object" do
18
+ subject.class_for_type(:my_hash_factory).should == Hash
19
+ end
20
+
21
+ it "should work with a factory where the class is guessed" do
22
+ subject.class_for_type(:array).should == Array
23
+ end
24
+
25
+ context "when no factory is defined" do
26
+ it "should raise an ArgumentError" do
27
+ lambda do
28
+ subject.class_for_type(:i_am_not_a_valid_factory)
29
+ end.should raise_error(ArgumentError)
30
+ end
31
+ end
32
+ end
33
+
34
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe Backyard::Adapter do
4
+
5
+ describe "#class_for_type" do
6
+ it "should transform the type into a CamelCase Class" do
7
+ subject.class_for_type(:user_session).should == 'UserSession'
8
+ end
9
+ end
10
+
11
+ describe "#create" do
12
+ it "should raise a NotImplementedError" do
13
+ lambda do
14
+ subject.create(:post, {})
15
+ end.should raise_error(NotImplementedError)
16
+ end
17
+ end
18
+
19
+ describe "#generate_model_name" do
20
+ it "should use the capitalized name as starting point" do
21
+ subject.generate_model_name(:user).should be_start_with('User ')
22
+ end
23
+
24
+ it "should always generate a unique name" do
25
+ (1..10).map { subject.generate_model_name(:article) }.uniq.should have(10).items
26
+ end
27
+ end
28
+
29
+ end
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+
3
+ describe Backyard::Configuration do
4
+
5
+ subject { Backyard::Configuration.new }
6
+
7
+ describe "#name_attribute" do
8
+ context "with single for key" do
9
+ it "should store the specified attribtues" do
10
+ subject.name_attribute :username, :for => :string
11
+ subject.config_for(String).name_attributes.should == [:username]
12
+ end
13
+ end
14
+
15
+ context "for multiple models" do
16
+ it "should store the specified attribtues" do
17
+ subject.name_attribute :title, :for => [:string, :array, :hash]
18
+ subject.config_for(Hash).name_attributes.should == [:title]
19
+ subject.config_for(Array).name_attributes.should == [:title]
20
+ subject.config_for(String).name_attributes.should == [:title]
21
+ end
22
+ end
23
+ end
24
+
25
+ describe "#name_for" do
26
+
27
+ context "with a single model" do
28
+ it "should store the block in the model config" do
29
+ my_block = lambda {|name| }
30
+ subject.name_for :array, &my_block
31
+ subject.config_for(Array).name_blocks.should include(my_block)
32
+ end
33
+ end
34
+
35
+ context "for multiple models" do
36
+ it "should store the block in the model config" do
37
+ my_block = lambda {|name| }
38
+ subject.name_for :array, :hash, &my_block
39
+ subject.config_for(Array).name_blocks.should include(my_block)
40
+ subject.config_for(Hash).name_blocks.should include(my_block)
41
+ end
42
+ end
43
+ end
44
+
45
+ describe "#use_adapter" do
46
+ it "should set the specified adapter" do
47
+ subject.use_adapter :factory_girl
48
+ subject.adapter_instance.should be_kind_of(Backyard::Adapter::FactoryGirl)
49
+ end
50
+ end
51
+
52
+ describe "#adapter_instance" do
53
+ describe "default: " do
54
+ it "should return the factory girl adapter" do
55
+ subject.adapter_instance.should be_kind_of(Backyard::Adapter::FactoryGirl)
56
+ end
57
+ end
58
+ end
59
+
60
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe Backyard::ModelStore do
4
+
5
+ subject { Backyard::ModelStore.new }
6
+
7
+ it "should store models" do
8
+ subject.put "John", [:i, :am, :john]
9
+ subject.get(Array, "John").should == [:i, :am, :john]
10
+ end
11
+
12
+ it "should store models with different types and the same name" do
13
+ subject.put "Jane", "This is Jane"
14
+ subject.put ["Jane"], %w(this is jane)
15
+ subject.get(String, 'Jane').should == "This is Jane"
16
+ end
17
+
18
+ describe "#get_collection" do
19
+ context "without models" do
20
+ it "should return an emtpy array" do
21
+ subject.get_collection(Hash).should == []
22
+ end
23
+ end
24
+
25
+ context "with models" do
26
+ before do
27
+ subject.put "John", "I am John"
28
+ subject.put "Jane", "I am Jane"
29
+ end
30
+
31
+ it "should return 2 items" do
32
+ subject.get_collection(String).should have(2).items
33
+ end
34
+
35
+
36
+ it "should return the models" do
37
+ subject.get_collection(String).should == {
38
+ 'John' =>'I am John',
39
+ 'Jane' => 'I am Jane'
40
+ }
41
+ end
42
+ end
43
+ end
44
+
45
+ end
@@ -0,0 +1,114 @@
1
+ require 'spec_helper'
2
+
3
+ describe Backyard::Session do
4
+
5
+ let(:model_store) { mock }
6
+ let(:adapter) { mock }
7
+
8
+ subject do
9
+ sessionClass = Class.new do
10
+ include Backyard::Session
11
+ end
12
+ session = sessionClass.new
13
+ session.stub(:adapter => adapter)
14
+ session.stub(:model_store => model_store)
15
+ session
16
+ end
17
+
18
+ describe "#get_model" do
19
+
20
+ it "should delegate to the model_store" do
21
+ adapter.should_receive(:class_for_type).with(:user).and_return(Struct)
22
+ model_store.should_receive(:get).with(Struct, 'Jeremy').and_return('I am Jeremy')
23
+ subject.get_model(:user, 'Jeremy').should == 'I am Jeremy'
24
+ end
25
+
26
+ context "with a reloadable model" do
27
+ it "should return the reloaded model" do
28
+ object = Array.new
29
+ object.should_receive(:reload).and_return(['I', 'am', 'reloaded'])
30
+
31
+ adapter.should_receive(:class_for_type).with(:array).and_return(Array)
32
+ model_store.should_receive(:get).with(Array, 'Reloadable Array').and_return(object)
33
+
34
+ subject.get_model(:array, 'Reloadable Array').should == ['I', 'am', 'reloaded']
35
+ end
36
+ end
37
+
38
+ end
39
+
40
+ describe "#get_models" do
41
+
42
+ it "should delegate to the model_store" do
43
+ adapter.should_receive(:class_for_type).with(:array).and_return(Array)
44
+ model_store.should_receive(:get_collection).with(Array).and_return([[1], [2]])
45
+ subject.get_models(:array).should == [[1], [2]]
46
+ end
47
+ end
48
+
49
+ describe "#put_model" do
50
+ context "with a name" do
51
+ context "with an attributes Hash" do
52
+ it "should delegate to the model_store" do
53
+ adapter.should_receive(:create).with(:post, {}).and_return('The Post')
54
+ adapter.should_receive(:class_for_type).with(:post).and_return(String)
55
+
56
+ model_store.should_receive(:put).with('First Post!', 'The Post')
57
+ subject.put_model(:post, 'First Post!')
58
+ end
59
+ end
60
+ end
61
+
62
+ context "without a name" do
63
+ it "should generate a name" do
64
+ adapter.should_receive(:create).with(:note, {}).and_return('The Note')
65
+ adapter.should_receive(:class_for_type).with(:note).and_return(String)
66
+ adapter.should_receive(:generate_model_name).with(:note).and_return { 'Note 123' }
67
+ model_store.should_receive(:put).with('Note 123', 'The Note')
68
+
69
+ subject.put_model(:note)
70
+ end
71
+ end
72
+
73
+ context "with an object" do
74
+ it "should store the object under the given name" do
75
+ model_store.should_receive(:put).with('Johnny', {:me => 'Johhny'})
76
+ subject.put_model({:me => 'Johhny'}, 'Johnny')
77
+ end
78
+ end
79
+ end
80
+
81
+ describe "#model_exists?" do
82
+ context "the model is present" do
83
+ it "should return true" do
84
+ subject.should_receive(:get_model).with(:user, 'James').and_return('This is James')
85
+ subject.model_exists?(:user, 'James').should be_true
86
+ end
87
+ end
88
+
89
+ context "the model does not exist" do
90
+ it "should return false" do
91
+ subject.should_receive(:get_model).with(:user, 'James').and_return(nil)
92
+ subject.model_exists?(:user, 'James').should be_false
93
+ end
94
+ end
95
+ end
96
+
97
+ describe "#model" do
98
+ context "the model with the given name exists" do
99
+ it "should return the existing model" do
100
+ subject.should_receive(:get_model).with(:note, 'welcome').twice.and_return('Hallo')
101
+ subject.model(:note, 'welcome').should == 'Hallo'
102
+ end
103
+ end
104
+
105
+ context "no model exists for the given name" do
106
+ it "should create a new model" do
107
+ subject.should_receive(:get_model).with(:note, 'see you').and_return(nil)
108
+ subject.should_receive(:put_model).with(:note, 'see you', {}).and_return('The Note')
109
+ subject.model(:note, 'see you').should == 'The Note'
110
+ end
111
+ end
112
+ end
113
+
114
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe Backyard do
4
+
5
+ describe ".configure" do
6
+ it "should eval the configuration block in the Backyard::Configuration scope" do
7
+ scope = nil
8
+ Backyard.configure do
9
+ scope = self
10
+ end
11
+ scope.should be_kind_of(Backyard::Configuration)
12
+ end
13
+ end
14
+
15
+ describe ".config" do
16
+ it "should return a Backyard::Configuration" do
17
+ Backyard.configure {}
18
+ Backyard.config.should be_kind_of(Backyard::Configuration)
19
+ end
20
+ end
21
+
22
+ end
data/spec/factories.rb ADDED
@@ -0,0 +1,15 @@
1
+ Factory.define :string do |f| end
2
+ Factory.define :array do |f| end
3
+ Factory.define :hash do |f| end
4
+ Factory.define :my_string_factory, :class => 'String' do |f| end
5
+ Factory.define :my_hash_factory, :class => Hash do |f| end
6
+
7
+ require File.join(File.dirname(__FILE__), 'models')
8
+
9
+ Factory.define :user do |f|
10
+ f.username 'John Doe'
11
+ end
12
+
13
+ Factory.define :account do |f|
14
+ f.description '<missing>'
15
+ end
@@ -0,0 +1,3 @@
1
+ class Account < ActiveRecord::Base
2
+ belongs_to :owner, :class_name => 'User'
3
+ end
@@ -0,0 +1,3 @@
1
+ class User < ActiveRecord::Base
2
+ has_many :accounts, :foreign_key => 'owner_id'
3
+ end
data/spec/models.rb ADDED
@@ -0,0 +1,21 @@
1
+ require 'active_record'
2
+
3
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3",
4
+ :database => ":memory:")
5
+ orig_stdout = $stdout
6
+ $stdout = File.new('/dev/null', 'w')
7
+ ActiveRecord::Schema.define do
8
+ create_table :users do |t|
9
+ t.string :username
10
+ t.string :email
11
+ end
12
+
13
+ create_table :accounts do |t|
14
+ t.string :description
15
+ t.integer :owner_id
16
+ end
17
+ end
18
+ $stdout = orig_stdout
19
+
20
+ require File.join(File.dirname(__FILE__), 'models', 'user')
21
+ require File.join(File.dirname(__FILE__), 'models', 'account')
@@ -0,0 +1,21 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'backyard')
2
+ require 'factory_girl'
3
+ require 'backyard/adapter/factory_girl'
4
+
5
+ Factory.find_definitions
6
+
7
+ RSpec.configure do |config|
8
+ # == Mock Framework
9
+ #
10
+ # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
11
+ #
12
+ # config.mock_with :mocha
13
+ # config.mock_with :flexmock
14
+ # config.mock_with :rr
15
+ config.mock_with :rspec
16
+
17
+ # If you're not using ActiveRecord, or you'd prefer not to run each of your
18
+ # examples within a transaction, comment the following line or assign false
19
+ # instead of true.
20
+ # config.use_transactional_fixtures = true
21
+ end
metadata ADDED
@@ -0,0 +1,190 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: backyard
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Yves Senn
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-01-24 00:00:00 +01:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rspec
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ type: :development
32
+ version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
34
+ name: cucumber
35
+ prerelease: false
36
+ requirement: &id002 !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ version: "0"
44
+ type: :development
45
+ version_requirements: *id002
46
+ - !ruby/object:Gem::Dependency
47
+ name: factory_girl
48
+ prerelease: false
49
+ requirement: &id003 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ segments:
55
+ - 0
56
+ version: "0"
57
+ type: :development
58
+ version_requirements: *id003
59
+ - !ruby/object:Gem::Dependency
60
+ name: activerecord
61
+ prerelease: false
62
+ requirement: &id004 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ segments:
68
+ - 0
69
+ version: "0"
70
+ type: :development
71
+ version_requirements: *id004
72
+ - !ruby/object:Gem::Dependency
73
+ name: sqlite3
74
+ prerelease: false
75
+ requirement: &id005 !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ segments:
81
+ - 0
82
+ version: "0"
83
+ type: :development
84
+ version_requirements: *id005
85
+ - !ruby/object:Gem::Dependency
86
+ name: yard
87
+ prerelease: false
88
+ requirement: &id006 !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ segments:
94
+ - 0
95
+ version: "0"
96
+ type: :development
97
+ version_requirements: *id006
98
+ description: backyard allows you to name the models in your cucumber scenarios.
99
+ email:
100
+ - yves.senn@gmail.com
101
+ executables: []
102
+
103
+ extensions: []
104
+
105
+ extra_rdoc_files: []
106
+
107
+ files:
108
+ - .gitignore
109
+ - Gemfile
110
+ - Gemfile.lock
111
+ - History.txt
112
+ - README.md
113
+ - Rakefile
114
+ - backyard.gemspec
115
+ - cucumber.yml
116
+ - features/backyard_with_factory_girl.feature
117
+ - features/step_definitions/backyard_account_steps.rb
118
+ - features/step_definitions/backyard_steps.rb
119
+ - features/step_definitions/backyard_user_steps.rb
120
+ - features/support/backyard.rb
121
+ - features/support/env.rb
122
+ - lib/backyard.rb
123
+ - lib/backyard/adapter.rb
124
+ - lib/backyard/adapter/factory_girl.rb
125
+ - lib/backyard/configuration.rb
126
+ - lib/backyard/cucumber.rb
127
+ - lib/backyard/model_store.rb
128
+ - lib/backyard/session.rb
129
+ - lib/backyard/version.rb
130
+ - spec/backyard/adapter/factory_girl_spec.rb
131
+ - spec/backyard/adapter_spec.rb
132
+ - spec/backyard/configuration_spec.rb
133
+ - spec/backyard/model_store_spec.rb
134
+ - spec/backyard/session_spec.rb
135
+ - spec/backyard_spec.rb
136
+ - spec/factories.rb
137
+ - spec/models.rb
138
+ - spec/models/account.rb
139
+ - spec/models/user.rb
140
+ - spec/spec_helper.rb
141
+ has_rdoc: true
142
+ homepage: http://rubygems.org/gems/backyard
143
+ licenses: []
144
+
145
+ post_install_message:
146
+ rdoc_options: []
147
+
148
+ require_paths:
149
+ - lib
150
+ required_ruby_version: !ruby/object:Gem::Requirement
151
+ none: false
152
+ requirements:
153
+ - - ">="
154
+ - !ruby/object:Gem::Version
155
+ segments:
156
+ - 0
157
+ version: "0"
158
+ required_rubygems_version: !ruby/object:Gem::Requirement
159
+ none: false
160
+ requirements:
161
+ - - ">="
162
+ - !ruby/object:Gem::Version
163
+ segments:
164
+ - 0
165
+ version: "0"
166
+ requirements: []
167
+
168
+ rubyforge_project: backyard
169
+ rubygems_version: 1.3.7
170
+ signing_key:
171
+ specification_version: 3
172
+ summary: manage the models in your cucumbers with ease
173
+ test_files:
174
+ - features/backyard_with_factory_girl.feature
175
+ - features/step_definitions/backyard_account_steps.rb
176
+ - features/step_definitions/backyard_steps.rb
177
+ - features/step_definitions/backyard_user_steps.rb
178
+ - features/support/backyard.rb
179
+ - features/support/env.rb
180
+ - spec/backyard/adapter/factory_girl_spec.rb
181
+ - spec/backyard/adapter_spec.rb
182
+ - spec/backyard/configuration_spec.rb
183
+ - spec/backyard/model_store_spec.rb
184
+ - spec/backyard/session_spec.rb
185
+ - spec/backyard_spec.rb
186
+ - spec/factories.rb
187
+ - spec/models.rb
188
+ - spec/models/account.rb
189
+ - spec/models/user.rb
190
+ - spec/spec_helper.rb