initial commit, starting work on features

This commit is contained in:
John Bintz 2012-01-19 15:59:05 -05:00
commit 5e36e4e8c9
23 changed files with 428 additions and 0 deletions

17
.gitignore vendored Normal file
View File

@ -0,0 +1,17 @@
*.gem
*.rbc
.bundle
.config
.yardoc
Gemfile.lock
InstalledFiles
_yardoc
coverage
doc/
lib/bundler/man
pkg
rdoc
spec/reports
test/tmp
test/version_tmp
tmp

8
Gemfile Normal file
View File

@ -0,0 +1,8 @@
source 'https://rubygems.org'
# Specify your gem's dependencies in flowerbox-delivery.gemspec
gemspec
gem 'guard'
gem 'guard-rspec'
gem 'guard-cucumber'

25
Guardfile Normal file
View File

@ -0,0 +1,25 @@
# A sample Guardfile
# More info at https://github.com/guard/guard#readme
guard 'rspec', :version => 2 do
watch(%r{^spec/.+_spec\.rb$})
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
watch('spec/spec_helper.rb') { "spec" }
# Rails example
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
watch('config/routes.rb') { "spec/routing" }
watch('app/controllers/application_controller.rb') { "spec/controllers" }
# Capybara request specs
watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
end
guard 'cucumber', :cli => '-f pretty' do
watch(%r{^features/.+\.feature$})
watch(%r{^features/support/.+$}) { 'features' }
watch(%r{^features/step_definitions/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' }
end

22
LICENSE Normal file
View File

@ -0,0 +1,22 @@
Copyright (c) 2012 John Bintz
MIT License
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.

35
README.md Normal file
View File

@ -0,0 +1,35 @@
# Flowerbox Delivery
Fresh cut code testing flowers, delivered straight to your door!
This component of Flowerbox uses Sprockets to compile your test suite's code into a nice package,
then delivers it to a runner in two ways:
* Straight on the filesystem, the absolute fastest way to run your tests
* Through a Rack server, so you can teest things that need a real HTTP url, like history and WebWorkers
## Installation
Add this line to your application's Gemfile:
gem 'flowerbox-delivery'
And then execute:
$ bundle
Or install it yourself as:
$ gem install flowerbox-delivery
## Usage
TODO: Write usage instructions here
## Contributing
1. Fork it
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Added some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request

2
Rakefile Normal file
View File

@ -0,0 +1,2 @@
#!/usr/bin/env rake
require "bundler/gem_tasks"

2
config/cucumber.yml Normal file
View File

@ -0,0 +1,2 @@
default: -r features

View File

@ -0,0 +1,27 @@
Feature: Start Server
Scenario: With no conflicting port, start a random port server
Given I have a server with the default configuration
And the server will start on the random port "12345"
When I start the server
Then the server should have started on port "12345", interface "127.0.0.1"
Scenario: With a conflicting port, start a random port server
Given I have a server with the default configuration
And the server will start on the random ports "12345,23456"
And I have an existing service running on port "12345"
When I start the server
Then the server should have started on port "23456", interface "127.0.0.1"
Scenario: Specify a port for starting the server
Given I have a server with the configuration:
| port | 12345 |
When I start the server
Then the server should have started on port "12345", interface "127.0.0.1"
Scenario: Specify an adapter and port for starting
Given I have a server with the configuration:
| port | 12345 |
| interface | 0.0.0.0 |
When I start the server
Then the server should have started on port "12345", interface "127.0.0.1"

View File

@ -0,0 +1,15 @@
require 'thread'
require 'rack'
Given /^I have an existing service running on port "([^"]*)"$/ do |port|
@running_server = Thread.new do
Rack::Handler::WEBrick.run(lambda { |env| [ 200, {}, [] ] }, :Port => port) { |server|
Thread.current[:server] = server
}
end
while !@running_server[:server]
sleep 0.1
end
end

View File

@ -0,0 +1,9 @@
Given /^I have a server with the configuration:$/ do |table|
options = {}
table.rows_hash.each do |key, value|
options[key.to_sym] = value
end
@server = Flowerbox::Delivery::Server.new(options)
end

View File

@ -0,0 +1,3 @@
Given /^I have a server with the default configuration$/ do
@server = Flowerbox::Delivery::Server.new
end

View File

@ -0,0 +1,6 @@
Given /^the server will start on the random ports? "([^"]*)"$/ do |ports|
ports = ports.split(',').collect(&:to_i)
@server.stubs(:random_port).returns(*ports)
end

View File

@ -0,0 +1,7 @@
require 'net/http'
Then /^the server should have started on port "([^"]*)", interface "([^"]*)"$/ do |port, interface|
socket = TCPSocket.new(interface, port.to_i)
socket.close
end

View File

@ -0,0 +1,4 @@
When /^I start the server$/ do
@server.start
end

26
features/support/env.rb Normal file
View File

@ -0,0 +1,26 @@
require 'flowerbox-delivery'
require 'mocha'
World(Mocha::API)
Before do
mocha_setup
end
After do
begin
mocha_verify
ensure
mocha_teardown
end
if @running_server
@running_server[:server].shutdown
@running_server = nil
sleep 0.1
end
@server.stop if @server
end

View File

@ -0,0 +1,26 @@
# -*- encoding: utf-8 -*-
require File.expand_path('../lib/flowerbox/delivery/version', __FILE__)
Gem::Specification.new do |gem|
gem.authors = ["John Bintz"]
gem.email = ["john@coswellproductions.com"]
gem.description = %q{TODO: Write a gem description}
gem.summary = %q{TODO: Write a gem summary}
gem.homepage = ""
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
gem.files = `git ls-files`.split("\n")
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
gem.name = "flowerbox-delivery"
gem.require_paths = ["lib"]
gem.version = Flowerbox::Delivery::VERSION
gem.add_development_dependency 'cucumber'
gem.add_development_dependency 'rspec'
gem.add_development_dependency 'jquery-rails', '~> 1.0.0'
gem.add_development_dependency 'mocha'
gem.add_runtime_dependency 'rack'
gem.add_runtime_dependency 'sprockets'
gem.add_runtime_dependency 'coffee-script'
end

View File

@ -0,0 +1,2 @@
require "flowerbox/delivery"

View File

@ -0,0 +1,5 @@
module Flowerbox
module Delivery
VERSION = "0.0.1"
end
end

View File

@ -0,0 +1,6 @@
module Flowerbox
module Delivery
autoload :Server, 'flowerbox/delivery/server'
end
end

View File

@ -0,0 +1,97 @@
require 'rack'
require 'net/http'
require 'socket'
module Flowerbox
module Delivery
class Server
attr_reader :options
def initialize(options = {})
@options = options || {}
end
def start
@server_thread = Thread.new do
Rack::Handler::WEBrick.run(lambda { |env| [ 200, {}, [] ] }, :Port => port, :Host => interface) { |server|
Thread.current[:server] = server
}
end
while !@server_thread[:server]
sleep 0.1
end
end
def stop
if @server_thread
@server_thread[:server].shutdown
wait_for_server_to_stop
end
end
def interface
options[:interface] || '0.0.0.0'
end
def port
return @port if @port ||= options[:port]
attempts = 100
begin
attempts -= 1
current_port = random_port
begin
socket = TCPSocket.new(interface, current_port)
socket.close
rescue Errno::ECONNREFUSED => e
@port = current_port
end
end while !@port and attempts > 0
raise StandardError.new("can't start server") if attempts == 0
@port
end
private
def wait_for_server_to_start
while true do
begin
connect_interface = '127.0.0.1' if interface == '0.0.0.0'
TCPSocket.new(connect_interface, port)
break
rescue Errno::ECONNREFUSED => e
end
sleep 0.1
end
end
def wait_for_server_to_stop
while true do
begin
connect_interface = '127.0.0.1' if interface == '0.0.0.0'
socket = TCPSocket.new(connect_interface, port)
socket.close
rescue Errno::ECONNREFUSED => e
return
end
sleep 0.1
end
end
def random_port
25000 + Kernel.rand(1000)
end
end
end
end

View File

@ -0,0 +1,6 @@
module Flowerbox
module Delivery
VERSION = "0.0.1"
end
end

View File

@ -0,0 +1,72 @@
require 'spec_helper'
require 'socket'
require 'thread'
describe Flowerbox::Delivery::Server do
let(:server) { described_class.new(options) }
let(:options) { nil }
subject { server }
describe '#initialize' do
let(:options) { { :port => port, :interface => interface } }
let(:port) { 'port' }
let(:interface) { 'interface' }
its(:port) { should == port }
its(:interface) { should == interface }
end
describe '#start' do
let(:port) { 12345 }
let(:interface) { '127.0.0.1' }
before do
server.stubs(:port).returns(port)
server.stubs(:interface).returns(interface)
end
it 'should start a Rack server' do
server.start
TCPSocket.new(server.interface, server.port)
end
end
describe '#interface' do
subject { server.interface }
it { should == '0.0.0.0' }
end
describe '#port' do
let(:interface) { '127.0.0.1' }
before do
server.stubs(:interface).returns(interface)
end
subject { server.port }
context 'no running service' do
before do
Kernel.stubs(:rand).returns(0)
end
it { should == 25000 }
end
context 'running service' do
before do
@server = Thread.new do
TCPServer.new(interface, 25000)
end
server.stubs(:random_port).returns(25000, 25001)
end
it { should == 25001 }
end
end
end

6
spec/spec_helper.rb Normal file
View File

@ -0,0 +1,6 @@
require 'flowerbox-delivery'
require 'mocha'
RSpec.configure do |c|
c.mock_with :mocha
end