Skip to content

Commit

Permalink
Reflecting name preference in Despo's changes. CLI project creation s…
Browse files Browse the repository at this point in the history
…till has problems.
  • Loading branch information
antonymarcano committed Apr 20, 2011
2 parents a563432 + abf0565 commit e634ef4
Show file tree
Hide file tree
Showing 7 changed files with 245 additions and 36 deletions.
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Copyright (c) 2010 RiverGlide

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

59 changes: 25 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Cuke Salad
# Cuke Salad

_Cucumber, washed and ready to eat for Friction-free ATDD/BDD_

Expand All @@ -9,7 +9,6 @@ e-mail feedback to <[email protected]>

* Support more step structures - such as tables as input
* Move beyond current examples by documenting CukeSalad with Cucumber
* Make available as a gem
* Remembering data between steps
* Multiple role/actor scenarios

Expand All @@ -21,7 +20,7 @@ With CukeSalad you don't need to write step-definitions.

Of course, you still have to write some code - but only the code that expresses:

* the roles and the actions they can perform
* the roles and the actions they can perform
* the tasks and the actions involved in completing that task

## Goals->Tasks->Actions
Expand All @@ -37,30 +36,22 @@ Let's see how this works with a simple example...

## Install

gem install bundler
gem update --system
git clone [email protected]:RiverGlide/CukeNarrative.git
bundle install
gem install cukesalad

## Let's Get started

Create a new project outside of the CukeSalad directory structure, e.g.:
Create a new project Calculator:

mkdir ~/projects/Calculator
cd ~/projects/Calculator
cukesalad new Calculator

Inside the root of that project...
Or configure an existing project by running the following command inside the project directory

cukesalad configure

mkdir features
mkdir features/support
mkdir features/lib/default/roles
mkdir features/lib/default/tasks

In idiomatic Cucumber style, we use `features/support/env.rb` to require _CukeSalad_ and
define the location of our project's _roles_ and _tasks_ e.g.:

$:.unshift(File.dirname(__FILE__) + '/../../../../lib') #where to find CukeSalad

require 'cukesalad'
begin require 'rspec/expectations'; rescue LoadError; require 'spec/expectations'; end

Expand All @@ -69,7 +60,7 @@ all .rb files beneath the project's `features/` directory.

## Write Features

In `features/`, let's create our first feature file - `A_PlaceToStart.feature`:
In `features/`, let's create our first feature file - `a_place_to_start.feature`:

Feature: A Place To Start
As Callie, a calculating individual
Expand All @@ -88,12 +79,12 @@ Let's take a moment to understand this scenario:
When I attempt to <do some task>
Then I should <ask some question> '<expected answer>'

To get this working, we don't need to write any steps.
To get this working, we don't need to write any steps.
Just explain how to do the _task_ using a class...

## Create Tasks

Explaining how to do a _task_ is easy:
Explaining how to do a _task_ is easy:
Create a new file, `features/lib/tasks/switch_on_the_calculator.rb`

Remember the step `When I attempt to switch on the calculator`
Expand All @@ -116,7 +107,7 @@ this example, we need to explain how the `CalculatingIndividual` _role_ works...

Remember the step `Given I am a Calculating Individual`?

We explain a _role_ by creating a new file
We explain a _role_ by creating a new file
called `features/lib/roles/calculating_individual.rb`

module CalculatingIndividual
Expand All @@ -128,13 +119,13 @@ called `features/lib/roles/calculating_individual.rb`
def look_at_the_display
@calculator.display
end
end
end

You'll need a class called Calculator on the load path of course, but that's it.

From your project folder, run (_note: '%' is our command prompt_)

% cucumber
% cucumber

We now have our first passing Feature, without creating a single step definition!

Expand All @@ -148,9 +139,9 @@ Let's try another scenario...
When I attempt to add: the number '10' to the number '10'
Then I should see the answer '20'

Notice that we've reused 'switch on the calculator'.
Notice that we've reused 'switch on the calculator'.

The new _When_ step has a slightly different layout.
The new _When_ step has a slightly different layout.
Let's examine that for a second... Notice the ':' (colon) after <do something> and the name-value pairs:

When I attempt to <do something>: <name> '<value>' <name> '<value>'
Expand All @@ -171,9 +162,9 @@ Notice how the `value_of` lines use symbols that correspond to the wording `'the
There is some 'syntactic sugar' that we can use to dress this up a little and make it read nicer... a simple attribute mapping:

in_order_to "Add", the_number: :first_number, to_the_number: :second_number do
enter the :first_number
enter the :first_number
press :plus
enter the :second_number
enter the :second_number
press :equals
end

Expand Down Expand Up @@ -214,10 +205,10 @@ Now all we need to do is modify our `calculating_individual.rb` to receive those

Now, you can run cucumber again:

% cucumber
% cucumber

There's no need to write `step_definitions`...
Simply express the _roles_ and the _tasks_ in clear,
There's no need to write `step_definitions`...
Simply express the _roles_ and the _tasks_ in clear,
concise, easy to read classes.

After adding some more scenarios and tasks and an alternative "Calculating Individual" (see below for why), our finished Calculator directory structure looks like this...
Expand Down Expand Up @@ -251,14 +242,14 @@ After adding some more scenarios and tasks and an alternative "Calculating Indiv
│   └── web_calculator.rb
└── spec
├── calculator_spec.rb
└── web_calculator_spec.rb
└── web_calculator_spec.rb

Take a look around the examples and the code to see how it all works. We hope you enjoy reading as much as we enjoyed writing it.
Take a look around the examples and the code to see how it all works. We hope you enjoy reading as much as we enjoyed writing it.

## Alternative Roles

As our features _describe the value of a calculator application and not its
implementation_, we have the opportunity to reuse them.
As our features _describe the value of a calculator application and not its
implementation_, we have the opportunity to reuse them.

In the Calculator example, we create a new _role_ in
`./features/lib/alternative/roles/calculating_web_user.rb`, which we can swap
Expand Down
4 changes: 3 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Jeweler::Tasks.new do |gem|
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
gem.name = "cukesalad"
gem.homepage = "https://github.com/RiverGlide/CukeSalad"
gem.platform = Gem::Platform::RUBY
gem.license = "MIT"
gem.summary = %Q{Friction Free BDD/ATDD with cucumber}
gem.description = %Q{CukeSalad allows you to focus on the tasks at hand - expressing examples, the roles involved in those examples and the tasks that those roles need to perform with the product under development.}
Expand All @@ -23,7 +24,8 @@ Jeweler::Tasks.new do |gem|
# The following two lines need to be commented out in order to gain access to the version rake tasks
gem_version = File.exist?('VERSION') ? File.read('VERSION') : ""
gem.version = gem_version

gem.executables = ["cukesalad"]
gem.files.include 'lib/cukesalad/cli.rb'
end

Jeweler::RubygemsDotOrgTasks.new
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.1.0
0.2.0
28 changes: 28 additions & 0 deletions bin/cukesalad
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env ruby

require 'optparse'
require 'cukesalad/cli'

OptionParser.new do |opts|
opts.banner = "Usage: cukesalad [new | configure] project_name"

begin
opts.parse!(ARGV)
rescue OptionParser::ParseError => e
warn e.message
puts opts
exit 1
end
end

if ARGV.empty?
abort "Usage: cukesalad new <project name>\nOr: cukesalad configure"
elsif ARGV.first == 'new'
project = ARGV[1]
puts "Creating project #{project}..."
CukeSalad::CLI.create_new_project project
puts "Done!"
elsif ARGV.first == 'configure'
CukeSalad::CLI.configure_existing_project
puts "Done!"
end
68 changes: 68 additions & 0 deletions cukesalad/cli.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
require 'aruba/api'
module CukeSalad
class CLI

def self.create_new_project project
structure = Structure.new
structure.setup project
end

def self.configure_existing_project project=nil
`cd #{project}` if project
structure = Structure.new
structure.setup_cucumber_with_cukesalad
end

class Structure
include Aruba::Api

def initialize
set_aruba_path_to_current
end

def setup project
create_and_navigate_to project
setup_cucumber_with_cukesalad
end

def setup_cucumber_with_cukesalad
create_dir_structure
configure
end

private
def set_aruba_path_to_current
@dirs = ["./"]
end

def create_dir_structure
create_cucumber_structure
create_cukesalad_structure
end

def create_cucumber_structure
create_and_navigate_to "features"
create_dir "support"
end

def create_cukesalad_structure
create_and_navigate_to "lib"
create_and_navigate_to "default"
create_dir "roles"
create_dir "tasks"
cd "../../../"
end

def configure
cd "features/support"
content = "require 'cukesalad'\n begin require 'rspec/expectations'; rescue LoadError; require 'spec/expectations'; end"
append_to_file "env.rb",content
end

def create_and_navigate_to directory
create_dir directory
cd directory
end
end
end
end
Loading

0 comments on commit e634ef4

Please sign in to comment.