forked from mislav/hub
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
rewrite
hub fork
tests as cukes running against a live server
- Loading branch information
Showing
8 changed files
with
267 additions
and
74 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,5 +3,7 @@ source 'https://rubygems.org' | |
gem 'ronn' | ||
gem 'aruba' | ||
gem 'cucumber' | ||
gem 'sinatra' | ||
gem 'thin' | ||
|
||
gemspec |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
Feature: hub fork | ||
Background: | ||
Given I am in "dotfiles" git repo | ||
And the "origin" remote has url "git://github.com/evilchelu/dotfiles.git" | ||
And I am "mislav" on github.com with OAuth token "OTOKEN" | ||
|
||
Scenario: Fork the repository | ||
Given the GitHub API server: | ||
""" | ||
before { halt 401 unless request.env['HTTP_AUTHORIZATION'] == 'token OTOKEN' } | ||
get('/repos/evilchelu/dotfiles', :host_name => 'api.github.com') { '' } | ||
post('/repos/evilchelu/dotfiles/forks', :host_name => 'api.github.com') { '' } | ||
""" | ||
When I successfully run `hub fork` | ||
Then the output should contain exactly "new remote: mislav\n" | ||
And "git remote add -f mislav git@github.com:mislav/dotfiles.git" should be run | ||
And the url for "mislav" should be "git@github.com:mislav/dotfiles.git" | ||
|
||
Scenario: --no-remote | ||
Given the GitHub API server: | ||
""" | ||
get('/repos/evilchelu/dotfiles') { '' } | ||
post('/repos/evilchelu/dotfiles/forks') { '' } | ||
""" | ||
When I successfully run `hub fork --no-remote` | ||
Then there should be no output | ||
And there should be no "mislav" remote | ||
|
||
Scenario: Fork failed | ||
Given the GitHub API server: | ||
""" | ||
get('/repos/evilchelu/dotfiles') { '' } | ||
post('/repos/evilchelu/dotfiles/forks') { halt 500 } | ||
""" | ||
When I run `hub fork` | ||
Then the exit status should be 1 | ||
And the stderr should contain exactly: | ||
""" | ||
Error creating fork: Internal Server Error (HTTP 500)\n | ||
""" | ||
And there should be no "mislav" remote | ||
|
||
Scenario: Fork already exists | ||
Given the GitHub API server: | ||
""" | ||
get('/repos/evilchelu/dotfiles') { '' } | ||
get('/repos/mislav/dotfiles') { '' } | ||
""" | ||
When I run `hub fork` | ||
Then the exit status should be 1 | ||
And the stderr should contain exactly: | ||
""" | ||
Error creating fork: mislav/dotfiles already exists on github.com\n | ||
""" | ||
And there should be no "mislav" remote | ||
|
||
Scenario: Invalid OAuth token | ||
Given the GitHub API server: | ||
""" | ||
before { halt 401 unless request.env['HTTP_AUTHORIZATION'] == 'token OTOKEN' } | ||
get('/repos/evilchelu/dotfiles') { '' } | ||
""" | ||
And I am "mislav" on github.com with OAuth token "WRONGTOKEN" | ||
When I run `hub fork` | ||
Then the exit status should be 1 | ||
And the stderr should contain exactly: | ||
""" | ||
Error creating fork: Unauthorized (HTTP 401)\n | ||
""" | ||
|
||
Scenario: HTTPS is preferred | ||
Given the GitHub API server: | ||
""" | ||
get('/repos/evilchelu/dotfiles') { '' } | ||
post('/repos/evilchelu/dotfiles/forks') { '' } | ||
""" | ||
And HTTPS is preferred | ||
When I successfully run `hub fork` | ||
Then the output should contain exactly "new remote: mislav\n" | ||
And the url for "mislav" should be "https://github.com/mislav/dotfiles.git" | ||
|
||
Scenario: Not in repo | ||
Given the current dir is not a repo | ||
When I run `hub fork` | ||
Then the exit status should be 1 | ||
And the stderr should contain "fatal: Not a git repository" | ||
|
||
Scenario: Unknown host | ||
Given the "origin" remote has url "git@git.my.org:evilchelu/dotfiles.git" | ||
When I run `hub fork` | ||
Then the exit status should be 1 | ||
And the stderr should contain exactly: | ||
""" | ||
Error: repository under 'origin' remote is not a GitHub project\n | ||
""" | ||
|
||
Scenario: Enterprise fork | ||
Given the GitHub API server: | ||
""" | ||
before { halt 401 unless request.env['HTTP_AUTHORIZATION'] == 'token FITOKEN' } | ||
get('/repos/evilchelu/dotfiles', :host_name => 'git.my.org') { '' } | ||
post('/repos/evilchelu/dotfiles/forks', :host_name => 'git.my.org') { '' } | ||
""" | ||
And the "origin" remote has url "git@git.my.org:evilchelu/dotfiles.git" | ||
And I am "mislav" on git.my.org with OAuth token "FITOKEN" | ||
And "git.my.org" is a whitelisted Enterprise host | ||
When I successfully run `hub fork` | ||
Then the url for "mislav" should be "git@git.my.org:mislav/dotfiles.git" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
# based on <github.com/jnicklas/capybara/blob/ab62b27/lib/capybara/server.rb> | ||
require 'net/http' | ||
|
||
module Hub | ||
class LocalServer | ||
class Identify < Struct.new(:app) | ||
def call(env) | ||
if env["PATH_INFO"] == "/__identify__" | ||
[200, {}, [app.object_id.to_s]] | ||
else | ||
app.call(env) | ||
end | ||
end | ||
end | ||
|
||
def self.ports | ||
@ports ||= {} | ||
end | ||
|
||
def self.run_handler(app, port, &block) | ||
begin | ||
require 'rack/handler/thin' | ||
Thin::Logging.silent = true | ||
Rack::Handler::Thin.run(app, :Port => port, &block) | ||
rescue LoadError | ||
require 'rack/handler/webrick' | ||
Rack::Handler::WEBrick.run(app, :Port => port, :AccessLog => [], :Logger => WEBrick::Log::new(nil, 0), &block) | ||
end | ||
end | ||
|
||
def self.start_sinatra(&block) | ||
require 'sinatra/base' | ||
klass = Class.new(Sinatra::Base) | ||
klass.set :environment, :test | ||
klass.disable :protection | ||
klass.class_eval(&block) | ||
|
||
new(klass.new).start | ||
end | ||
|
||
attr_reader :app, :host, :port | ||
attr_accessor :server | ||
|
||
def initialize(app, host = '127.0.0.1') | ||
@app = app | ||
@host = host | ||
@server = nil | ||
@server_thread = nil | ||
end | ||
|
||
def responsive? | ||
return false if @server_thread && @server_thread.join(0) | ||
|
||
res = Net::HTTP.start(host, port) { |http| http.get('/__identify__') } | ||
|
||
res.is_a?(Net::HTTPSuccess) and res.body == app.object_id.to_s | ||
rescue Errno::ECONNREFUSED, Errno::EBADF | ||
return false | ||
end | ||
|
||
def start | ||
@port = self.class.ports[app.object_id] | ||
|
||
if not @port or not responsive? | ||
@port = find_available_port | ||
self.class.ports[app.object_id] = @port | ||
|
||
@server_thread = Thread.new do | ||
self.class.run_handler(Identify.new(app), @port) { |server| | ||
self.server = server | ||
} | ||
end | ||
|
||
Timeout.timeout(60) { @server_thread.join(0.1) until responsive? } | ||
end | ||
rescue TimeoutError | ||
raise "Rack application timed out during boot" | ||
else | ||
self | ||
end | ||
|
||
def stop | ||
server.respond_to?(:stop!) ? server.stop! : server.stop | ||
@server_thread.join | ||
end | ||
|
||
private | ||
|
||
def find_available_port | ||
server = TCPServer.new('127.0.0.1', 0) | ||
server.addr[1] | ||
ensure | ||
server.close if server | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.