communist 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.swp
data/.rvmrc ADDED
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env bash
2
+
3
+ environment_id="ruby-1.9.3@communist"
4
+
5
+ #
6
+ # First we attempt to load the desired environment directly from the environment
7
+ # file. This is very fast and efficient compared to running through the entire
8
+ # CLI and selector. If you want feedback on which environment was used then
9
+ # insert the word 'use' after --create as this triggers verbose mode.
10
+ #
11
+ if [[ -d "${rvm_path:-$HOME/.rvm}/environments" \
12
+ && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
13
+ then
14
+ \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
15
+
16
+ if [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]]
17
+ then
18
+ . "${rvm_path:-$HOME/.rvm}/hooks/after_use"
19
+ fi
20
+ else
21
+ # If the environment file has not yet been created, use the RVM CLI to select.
22
+ if ! rvm --create "$environment_id"
23
+ then
24
+ echo "Failed to create RVM environment '${environment_id}'."
25
+ return 1
26
+ fi
27
+ fi
28
+
29
+ if [[ $- == *i* ]] # check for interactive shells
30
+ then
31
+ echo "Using: $(tput setaf 2)$GEM_HOME$(tput sgr0)" # show the user the ruby and gemset they are using in green
32
+ else
33
+ echo "Using: $GEM_HOME" # don't use colors in interactive shells
34
+ fi
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in communist.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Piotr Murach
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,62 @@
1
+ # Communist
2
+
3
+ The Manifesto:
4
+
5
+ >It is Communist prime role to serve community by providing Cucumber steps for
6
+ >testing external API calls from command line applications. To meet this aim
7
+ >the Communist employees Sinatra DSL for mocking server responses.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ gem 'communist'
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install communist
22
+
23
+ ## Usage
24
+
25
+ To get started include the following in your cucumber environment file:
26
+
27
+ ```ruby
28
+ # features/support/env.rb
29
+ require 'communist/cucumber'
30
+ ```
31
+
32
+ The gem uses `ENV['TEST_HOST']` variable to instrument requests. In your command line application add the following logic to switch between live and test requests:
33
+
34
+ ```ruby
35
+ if ENV['TEST_HOST']
36
+ @@api.endpoint = 'http://' + ENV['TEST_HOST']
37
+ end
38
+ ```
39
+
40
+ Finally, communist has few cucumber steps such as `Given ... server:` that help setting expectations such as:
41
+
42
+ ```ruby
43
+ Scenario: Get blob
44
+ Given the GitHub API server:
45
+ """
46
+ get('/repos/wycats/thor/git/blobs/59b23de9b91d') { status 200 }
47
+ """
48
+ When I run `ghub blob get wycats thor 59b23de9b91d`
49
+ Then the exit status should be 0
50
+ ```
51
+
52
+ ## Contributing
53
+
54
+ 1. Fork it
55
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
56
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
57
+ 4. Push to the branch (`git push origin my-new-feature`)
58
+ 5. Create new Pull Request
59
+
60
+ ## Copyright
61
+
62
+ Copyright (c) 2012 Piotr Murach. See LICENSE for further details.
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require "rspec/core/rake_task"
4
+
5
+ RSpec::Core::RakeTask.new(:spec) do |spec|
6
+ spec.pattern = FileList['spec/**/*_spec.rb']
7
+ end
8
+
9
+ task :default => [:spec]
data/communist.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/communist/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Piotr Murach"]
6
+ gem.email = [""]
7
+ gem.description = %q{Library for mocking CLI calls to external APIs}
8
+ gem.summary = %q{Library for mocking CLI calls to external APIs}
9
+ gem.homepage = ""
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "communist"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Communist::VERSION
17
+
18
+ gem.add_dependency 'rack'
19
+ gem.add_dependency 'sinatra'
20
+
21
+ gem.add_development_dependency 'rspec'
22
+ gem.add_development_dependency 'rake'
23
+ end
@@ -0,0 +1,17 @@
1
+ require 'communist/server'
2
+
3
+ Before do
4
+ ENV['TEST_HOST'] = '127.0.0.1:0'
5
+ end
6
+
7
+ After do
8
+ @server.stop if defined? @server and @server
9
+ end
10
+
11
+ Given /^the (.*) server:$/ do |name, endpoints|
12
+ @server = ::Communist::Server.run do
13
+ eval endpoints, binding
14
+ end
15
+
16
+ ENV['TEST_HOST'] = "127.0.0.1:#{@server.port}"
17
+ end
@@ -0,0 +1,112 @@
1
+ require 'socket'
2
+ require 'thread'
3
+ require 'sinatra/base'
4
+ require 'net/http'
5
+ require 'communist'
6
+
7
+ module Communist
8
+ class Server
9
+
10
+ class ServerError < StandardError; end
11
+
12
+ class Identify
13
+ def initialize(app)
14
+ @app = app
15
+ end
16
+
17
+ def call(env)
18
+ if env["PATH_INFO"] == "/__identify__"
19
+ [200, {}, [@app.object_id.to_s]]
20
+ else
21
+ @app.call(env)
22
+ end
23
+ end
24
+ end
25
+
26
+ class << self
27
+ def ports
28
+ @ports ||= {}
29
+ end
30
+ end
31
+
32
+ attr_reader :app, :port, :host
33
+
34
+ def initialize(app, options={})
35
+ @app = app
36
+ @host = options[:host]
37
+ @server_thread = nil
38
+ end
39
+
40
+ def host
41
+ "127.0.0.1"
42
+ end
43
+
44
+ def responsive?
45
+ return false if @server_thread && @server_thread.join(0)
46
+
47
+ res = Net::HTTP.start(host, @port) { |http| http.get('/__identify__') }
48
+
49
+ if res.is_a?(Net::HTTPSuccess) or res.is_a?(Net::HTTPRedirection)
50
+ return res.body == @app.object_id.to_s
51
+ end
52
+ rescue Errno::ECONNREFUSED, Errno::EBADF
53
+ return false
54
+ end
55
+
56
+ def start(&block)
57
+ if @app
58
+ @port = Server.ports[@app.object_id]
59
+
60
+ if not @port or not responsive?
61
+ @port = find_available_port
62
+ Server.ports[@pp.object_id] = @port
63
+
64
+ @server_thread = Thread.new do
65
+ Communist.run_default_server(Identify.new(app), @port) do |server|
66
+ Communist.server = server
67
+ end
68
+ end
69
+
70
+ Timeout.timeout(5) { @server_thread.join(0.1) until responsive? }
71
+ end
72
+ end
73
+ rescue TimeoutError
74
+ raise ServerError, "Rack application timed out during start"
75
+ else
76
+ self
77
+ end
78
+
79
+ def stop
80
+ Communist.server.respond_to?(:stop!) ? Communist.server.stop! : Communist.server.stop
81
+ @server_thread.join
82
+ end
83
+
84
+ def self.run(&block)
85
+ app = Sinatra.new do
86
+ set :environment, :test
87
+ disable :protection
88
+
89
+ self.class_eval(&block)
90
+
91
+ helpers do
92
+ def body(value=nil)
93
+ super
94
+ nil
95
+ end
96
+ end
97
+ end
98
+
99
+ new(app).start
100
+ end
101
+
102
+ private
103
+
104
+ def find_available_port
105
+ server = TCPServer.new('127.0.0.1', 0)
106
+ server.addr[Socket::Constants::SOCK_STREAM]
107
+ ensure
108
+ server.close if server
109
+ end
110
+
111
+ end # Server
112
+ end # Communist
@@ -0,0 +1,3 @@
1
+ module Communist
2
+ VERSION = "0.1.0"
3
+ end
data/lib/communist.rb ADDED
@@ -0,0 +1,49 @@
1
+ require 'communist/version'
2
+ require 'rack'
3
+
4
+ module Communist
5
+ class << self
6
+ attr_accessor :app_host
7
+ attr_accessor :default_host
8
+ attr_accessor :run_server
9
+ attr_accessor :app
10
+
11
+ # Possible options
12
+ #
13
+ def configure
14
+ yield self
15
+ end
16
+
17
+ def server=(instance)
18
+ @server = instance
19
+ end
20
+
21
+ def server(&block)
22
+ if block_given?
23
+ @server = block
24
+ else
25
+ @server
26
+ end
27
+ end
28
+
29
+ # By default run thin or fall back on webrick
30
+ #
31
+ def run_default_server(app, port, &block)
32
+ begin
33
+ require 'rack/handler/thin'
34
+ Thin::Logging.silent = true
35
+ Rack::Handler::Thin.run(app, :Port => port, &block)
36
+ rescue LoadError
37
+ require 'rack/handler/webrick'
38
+ Rack::Handler::WEBrick.run(app, :Port => port, :AccessLog => [], :Logger => WEBrick::Log::new(nil, 0), &block)
39
+ end
40
+ end
41
+
42
+ end
43
+
44
+ autoload :Server, 'communist/server'
45
+
46
+ end # Communist
47
+
48
+ Communist.configure do |config|
49
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+
3
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
5
+
6
+ require 'rspec'
7
+
8
+ RSpec.configure do |config|
9
+ config.order = :rand
10
+ end
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: communist
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Piotr Murach
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-07-14 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rack
16
+ requirement: &2152389780 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *2152389780
25
+ - !ruby/object:Gem::Dependency
26
+ name: sinatra
27
+ requirement: &2152389340 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *2152389340
36
+ - !ruby/object:Gem::Dependency
37
+ name: rspec
38
+ requirement: &2152388880 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *2152388880
47
+ - !ruby/object:Gem::Dependency
48
+ name: rake
49
+ requirement: &2152388400 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *2152388400
58
+ description: Library for mocking CLI calls to external APIs
59
+ email:
60
+ - ''
61
+ executables: []
62
+ extensions: []
63
+ extra_rdoc_files: []
64
+ files:
65
+ - .gitignore
66
+ - .rvmrc
67
+ - Gemfile
68
+ - LICENSE
69
+ - README.md
70
+ - Rakefile
71
+ - communist.gemspec
72
+ - lib/communist.rb
73
+ - lib/communist/cucumber.rb
74
+ - lib/communist/server.rb
75
+ - lib/communist/version.rb
76
+ - spec/spec_helper.rb
77
+ homepage: ''
78
+ licenses: []
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ! '>='
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ! '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubyforge_project:
97
+ rubygems_version: 1.8.10
98
+ signing_key:
99
+ specification_version: 3
100
+ summary: Library for mocking CLI calls to external APIs
101
+ test_files:
102
+ - spec/spec_helper.rb