Skip to content

Instantly share code, notes, and snippets.

@ess
Created July 20, 2010 01:32
Show Gist options
  • Save ess/482313 to your computer and use it in GitHub Desktop.
Save ess/482313 to your computer and use it in GitHub Desktop.
Embedded elements for a write-up on cucumber and rspec for bash testing
#!/bin/bash
FIZZBUZZLIB="${FIZZBUZZLIB:-/usr/local/lib/fizzbuzz}"
source "${FIZZBUZZLIB}/fizzbuzz.inc.sh"
fizzbuzz $1
When /^I say "([^\"]*)"$/ do |number|
@procinfo = ShellRunner.run( "FIZZBUZZLIB=\"#{FIZZBUZZLIB}\" #{FIZZBUZZ} #{number}" )
end
Then /^I should see "([^\"]*)"$/ do |response|
@procinfo[:output].should include("#{response}")
end
# Set up some paths
BINDIR = File.expand_path('../../../bin', __FILE__)
VENDORDIR = File.expand_path('../../../vendor', __FILE__)
FIZZBUZZLIB = "#{BINDIR}/../lib"
# Set up our Bash script reference
FIZZBUZZ = "#{BINDIR}/fizzbuzz.sh"
# Do up the general environment
$LOAD_PATH.unshift "#{VENDORDIR}/lib"
require 'shellrunner'
Feature: user passes a number
The user passes a number that is greater-than 0 to fizzbuzz on the
command-line. Fizzbuzz then responds with "Fizz" if the number is
a multiple of 3, "Buzz" if the number is a multiple of 5, "FizzBuzz"
if the number is a multiple of both 3 and 5, or the number itself
otherwise.
Scenario Outline: pass a number
When I say "<number>"
Then I should see "<response>"
Scenarios: response is "Fizz"
| number | response |
| 3 | Fizz |
| 6 | Fizz |
| 9 | Fizz |
| 12 | Fizz |
| 18 | Fizz |
Scenarios: response is "Buzz"
| number | response |
| 5 | Buzz |
| 10 | Buzz |
| 20 | Buzz |
| 25 | Buzz |
| 35 | Buzz |
Scenarios: response is "FizzBuzz"
| number | response |
| 15 | FizzBuzz |
| 30 | FizzBuzz |
| 45 | FizzBuzz |
| 60 | FizzBuzz |
| 75 | FizzBuzz |
Scenarios: response is the input number
| number | response |
| 14 | 14 |
| 29 | 29 |
| 44 | 44 |
| 59 | 59 |
| 94 | 94 |
fizzbuzz
-bin
-features
-support
-step_definitions
-lib
-spec
-fizzbuzz
-vendor
-lib
-bin
fizz() {
[ $(( $1 % 3 )) -eq 0 ]
}
buzz() {
[ $(( $1 % 5 )) -eq 0 ]
}
fizzbuzz() {
local fb=''
fizz "${1}" && fb="Fizz"
buzz "${1}" && fb="${fb}Buzz"
[ -n "${fb}" ] && echo "${fb}" || echo "${1}"
}
require 'spec_helper'
module Fizzbuzz
def fizz
end
describe "#fizz" do
context "number is a multiple of 3" do
it "has an exit code of 0 for true" do
@procinfo = ShellRunner.run("#{DOMETHOD} #{FIZZBUZZLIB}/fizzbuzz.inc.sh fizz 3")
@procinfo[:exitstatus].should ==(0)
end
end
context "number is not a multiple of 3" do
it "has an exit code of 1 for false" do
@procinfo = ShellRunner.run("#{DOMETHOD} #{FIZZBUZZLIB}/fizzbuzz.inc.sh fizz 1")
@procinfo[:exitstatus].should ==(1)
end
end
end
def buzz
end
describe "#buzz" do
context "number is a multiple of 5" do
it "has an exit code of 0 for true" do
@procinfo = ShellRunner.run("#{DOMETHOD} #{FIZZBUZZLIB}/fizzbuzz.inc.sh buzz 5")
@procinfo[:exitstatus].should ==(0)
end
end
context "number is not a multiple of 5" do
it "has an exit code of 1 for false" do
@procinfo = ShellRunner.run("#{DOMETHOD} #{FIZZBUZZLIB}/fizzbuzz.inc.sh buzz 1")
@procinfo[:exitstatus].should ==(1)
end
end
end
def fizzbuzz
end
describe "#fizzbuzz" do
context "number is a multiple of 3 but not 5" do
it "outputs 'Fizz'" do
@procinfo = ShellRunner.run("#{DOMETHOD} #{FIZZBUZZLIB}/fizzbuzz.inc.sh fizzbuzz 3")
@procinfo[:output].should include("Fizz")
end
end
context "number is a multiple of 5 but not 3" do
it "outputs 'Buzz'" do
@procinfo = ShellRunner.run("#{DOMETHOD} #{FIZZBUZZLIB}/fizzbuzz.inc.sh fizzbuzz 5")
@procinfo[:output].should include("Buzz")
end
end
context "number is a multiple of both 3 and 5" do
it "outputs 'FizzBuzz'" do
@procinfo = ShellRunner.run("#{DOMETHOD} #{FIZZBUZZLIB}/fizzbuzz.inc.sh fizzbuzz 15")
@procinfo[:output].should include("FizzBuzz")
end
end
context "number is a multiple of neither 3 nor 5" do
it "echoes the provided number" do
@procinfo = ShellRunner.run("#{DOMETHOD} #{FIZZBUZZLIB}/fizzbuzz.inc.sh fizzbuzz 1")
@procinfo[:output].should include("1")
end
end
end
end
VENDORDIR = File.expand_path('../../vendor', __FILE__)
FIZZBUZZLIB = "#{VENDORDIR}/../lib"
DOMETHOD = "#{VENDORDIR}/bin/domethod.sh"
$LOAD_PATH.unshift "#{VENDORDIR}/lib"
require 'shellrunner'
#!/bin/bash -
#===============================================================================
#
# FILE: domethod.sh
#
# USAGE: ./domethod.sh library_to_test method arg1 arg2 ... argN
#
# DESCRIPTION: A quick-n-dirty evaluator to provide the ability to use rspec
#
#===============================================================================
die() {
echo -e "Error: ${1}" >&2
exit 255
}
method_exists() {
[ "$( declare -F "${1}" )" == "${1}" ]
}
TESTLIB="${1}" && shift
METHOD="${1}" && shift
source "${TESTLIB}"
method_exists "${METHOD}" || die "Method '${METHOD}' does not exist."
"${METHOD}" "${@}"
require 'open4'
class ShellRunner
attr_reader :output, :error, :exitstatus, :command
def initialize( command )
@command = command
@output = Array.new
@error = Array.new
@exitstatus=-1
end
def run
pid, stdin, stdout, stderr = Open4::popen4 "#{ @command }"
status = Process::waitpid2(pid)[1]
@exitstatus = ( status.to_i / 256 )
@output += io_to_a(stdout)
@error += io_to_a(stderr)
self.to_h
end
def to_h
{
:exitstatus => @exitstatus,
:output => @output,
:error => @error
}
end
def self.run(command)
self.new(command).run
end
private
def io_to_a(io)
io.readlines.collect { |x| x.chomp }
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment