irumugam 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use 1.9.3@irumugam --create
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.2
4
+ - 1.9.3
5
+ - jruby-19mode
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in interestest.gemspec
4
+ gemspec
@@ -0,0 +1,67 @@
1
+ # Irumugam
2
+
3
+ [![Build Status](https://secure.travis-ci.org/vagmi/irumugam.png?branch=master)](http://travis-ci.org/vagmi/irumugam)
4
+
5
+ Irumugam - The two faced framework helps you setup a DSL for describing services. The one face helps you test the services using RSpec while the other runs it as a mock for consuming them.
6
+
7
+ To include irumugam in your project, add it to your `Gemfile`
8
+
9
+ gem 'irumugam'
10
+
11
+ ## Usage
12
+
13
+ To you can describe a service this way using irumugam
14
+
15
+ # service.rb
16
+ include Irumugam
17
+
18
+ describe_service "My Glorious Service" do
19
+ host "http://testserver"
20
+ end_point "/cart-service"
21
+
22
+ before(:each) do
23
+ #do setup stuff
24
+ @test_order = FactoryGirl.create(:order)
25
+ end
26
+
27
+ after(:each) do
28
+ DatabaseCleaner.clean
29
+ end
30
+
31
+ get "/orders" do
32
+ status 200
33
+ body [FactoryGirl.attributes_for(:order)].to_json
34
+ end
35
+
36
+ get "/orders/1" do
37
+ status 200
38
+ json {id:42, name: "Some Name", quantity: 500}, :ignore=>[:id]
39
+ end
40
+
41
+ put "/orders/:id", :body=>{:description=>"asdf"}, :type=>:json do
42
+ status 200
43
+ path_object { @test_order.attributes }
44
+ json {id: 42, description: "asdf", count: 50}, :ignore=>[:id]
45
+ end
46
+ end
47
+
48
+ register_with_rspec!
49
+
50
+ You can now run this as a spec as.
51
+
52
+ $ rspec service.rb
53
+
54
+ You can also run this as a mock server by wiring it with config.ru
55
+
56
+ # config.ru
57
+ require './service.rb'
58
+
59
+ run Irumugam::Server.new
60
+
61
+ You can run the server with a rack compatible server like `thin`.
62
+
63
+ $ thin -R config.ru start
64
+
65
+ You can then access the mock service with the following.
66
+
67
+ $ curl http://localhost:3000/cart-service/orders/1
@@ -0,0 +1,5 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+ RSpec::Core::RakeTask.new(:test)
4
+
5
+ task :default=>:test
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "irumugam/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "irumugam"
7
+ s.version = Irumugam::VERSION
8
+ s.authors = ["Shakir Shakiel", "Vagmi Mudumbai", "Lokesh D"]
9
+ s.email = ["shakiras@thoughtworks.com", "vagmimud@thoughtworks.com", "lokeshd@thoughtworks.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Describe service contracts that act both as a spec and a mock}
12
+ s.description = %q{Describe service contracts that act both as a spec and a mock}
13
+
14
+ s.rubyforge_project = "irumugam"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_development_dependency "webmock"
22
+ s.add_development_dependency "factory_girl"
23
+ s.add_development_dependency "rack-test"
24
+ s.add_development_dependency "rake"
25
+ s.add_runtime_dependency "rspec"
26
+ s.add_runtime_dependency "rack"
27
+ s.add_runtime_dependency "httparty"
28
+ s.add_runtime_dependency "json"
29
+ s.add_runtime_dependency "activesupport"
30
+ end
@@ -0,0 +1,20 @@
1
+ require 'json'
2
+ require 'httparty'
3
+ require 'rack'
4
+ require 'active_support/core_ext/hash/keys'
5
+
6
+ require "irumugam/version"
7
+ require "irumugam/contract"
8
+ require "irumugam/service"
9
+ require "irumugam/service_registry"
10
+ require "irumugam/spec_writer"
11
+ require "irumugam/server"
12
+
13
+ module Irumugam
14
+ def describe_service(*args, &block)
15
+ ServiceRegistry.desc(*args,&block)
16
+ end
17
+ def register_with_rspec!
18
+ SpecWriter.create_example_groups
19
+ end
20
+ end
@@ -0,0 +1,74 @@
1
+ module Irumugam
2
+ class Contract
3
+ attr_accessor :method, :path, :service, :accept,:block, :contract_status, :contract_body, :test_host, :params, :contract_json, :contract_json_ignore, :request_body, :request_type, :path_object_block
4
+ def initialize(options={})
5
+ @method = options[:method]
6
+ @path = options[:path]
7
+ @test_host = options[:test_host]
8
+ @params = options[:params]
9
+ @request_body = options[:body]
10
+ @request_type = options[:type]
11
+ @accept = options[:accept]
12
+ @service = options[:service]
13
+ instance_eval &(options[:block])
14
+ end
15
+
16
+ def status(val)
17
+ @contract_status = val
18
+ end
19
+
20
+ def body(val)
21
+ @contract_body = val
22
+ end
23
+
24
+ def json(val,options={})
25
+ @contract_json = val
26
+ @contract_json_ignore = options.delete(:ignore) || []
27
+ end
28
+
29
+ def path_object(&po_block)
30
+ @path_object_block = po_block
31
+ end
32
+
33
+ def json_for_spec
34
+ prepare_response(contract_json)
35
+ end
36
+
37
+ def prepare_response(response)
38
+ response = JSON.parse(response) if response.is_a?(String)
39
+ spec_json = response.clone
40
+ spec_json.map{ |hsh| process_hash(hsh) } if spec_json.is_a?(Array)
41
+ process_hash(spec_json) if spec_json.is_a?(Hash)
42
+ spec_json
43
+ end
44
+ def path_match?(request)
45
+ match_pattern = /(\:\w+)/
46
+ replace_pattern = /(\w+)/
47
+ path_patterns = self.path.split("/").map { |part|
48
+ part.index(":") ? Regexp.new(part.gsub(match_pattern, replace_pattern.source)) : /#{part}/
49
+ }
50
+ return false unless request.path.split("/").count==path_patterns.count
51
+ path_patterns.each_index do |idx|
52
+ return false unless path_patterns[idx]=~request.path.split("/")[idx]
53
+ end
54
+ true
55
+ end
56
+ def matches?(request, req_body)
57
+ return false if !req_body.empty? ^ !self.request_body.nil?
58
+ request_json = JSON.parse(req_body) if (!req_body.empty? && request.content_type=="application/json")
59
+ result = path_match?(request) &&
60
+ request.request_method==self.method &&
61
+ request.params==self.params &&
62
+ (request_json.nil? ? true : (request_json == self.request_body.stringify_keys))
63
+ result
64
+ end
65
+
66
+
67
+ private
68
+ def process_hash(hsh)
69
+ hsh.stringify_keys!
70
+ self.contract_json_ignore.map(&:to_s).each { |key| hsh.delete(key) }
71
+ hsh
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,11 @@
1
+ module Irumugam
2
+ class Server
3
+ def call(env)
4
+ request = Rack::Request.new(env)
5
+ contract = ServiceRegistry.find(request)
6
+ body = contract.contract_body if contract.contract_body
7
+ body ||= contract.contract_json.to_json
8
+ [contract.contract_status, {}, body]
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,42 @@
1
+ module Irumugam
2
+ class Service
3
+ attr_accessor :name, :block, :rest_end_point, :paths, :test_host, :before_blocks, :after_blocks
4
+ def initialize(name, service_block)
5
+ @name, @block = name, service_block
6
+ @before_blocks = {}
7
+ @after_blocks = {}
8
+ @paths = ServiceRegistry.instance.paths
9
+ instance_eval &service_block
10
+ end
11
+ def before(type=:each, &before_block)
12
+ before_blocks[type] = before_block
13
+ end
14
+ def after(type=:each, &after_block)
15
+ after_blocks[type] = after_block
16
+ end
17
+ def end_point(name)
18
+ @rest_end_point = name
19
+ end
20
+ def host(val)
21
+ @test_host=val
22
+ end
23
+ ["GET", "POST", "PUT", "DELETE"].each do |verb|
24
+ define_method(verb.downcase) do |path, options={}, &block|
25
+ http_method(verb, @rest_end_point+path, options, block)
26
+ end
27
+ end
28
+
29
+ def http_method(method,path,options,contract_block)
30
+ defaults = {:accept=>"application/json",
31
+ :method=>method,
32
+ :path=>path,
33
+ :test_host => @test_host,
34
+ :params=>{},
35
+ :block=>contract_block,
36
+ :service=>self}
37
+ defaults.merge!(options)
38
+ paths[path] ||= []
39
+ paths[path] << Contract.new(defaults)
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,38 @@
1
+ require 'singleton'
2
+ module Irumugam
3
+ class ServiceRegistry
4
+ include Singleton
5
+ attr_accessor :services, :paths
6
+
7
+ def initialize
8
+ @paths ||= {}
9
+ @services ||= {}
10
+ end
11
+
12
+ def cleanup!
13
+ @paths = {}
14
+ @services = {}
15
+ end
16
+
17
+ def find(request)
18
+ req_body = request.body.read
19
+ paths.values.flatten.select { |c| c.matches?(request, req_body) }.first
20
+ end
21
+
22
+ def paths_for(service_name)
23
+ paths.values.flatten.select { |c| c.service.name==service_name }
24
+ end
25
+
26
+ def self.cleanup!
27
+ instance.cleanup!
28
+ end
29
+
30
+ def self.desc(name,&block)
31
+ instance.services[name] = Service.new(name, block)
32
+ end
33
+
34
+ def self.find(request)
35
+ instance.find(request)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,52 @@
1
+ require 'rspec'
2
+ module Irumugam
3
+
4
+ module RequestMethods
5
+ def perform_request(options)
6
+ path_object = options.delete(:path_object)
7
+ if(path_object)
8
+ path_object.each do |k,v|
9
+ self.path.gsub!(":#{k}",v.to_s)
10
+ end
11
+ end
12
+ options[:query]=self.params if self.params
13
+ if self.request_body
14
+ if self.request_type == :json
15
+ options[:body]=self.request_body.to_json
16
+ options[:headers]={"Content-Type"=>"application/json"}
17
+ else
18
+ options[:body]=self.request_body
19
+ end
20
+ end
21
+ response = HTTParty.send(self.method.downcase.to_sym,self.test_host + self.path, options)
22
+ end
23
+ end
24
+
25
+ Contract.class_eval { include RequestMethods }
26
+
27
+ class SpecWriter
28
+ def self.create_example_groups
29
+ ServiceRegistry.instance.services.values.each do |service|
30
+
31
+ eg = RSpec::Core::ExampleGroup.describe("#{service.name} specs") do
32
+ before :all, &(service.before_blocks[:all]) if service.before_blocks[:all]
33
+ before :each, &(service.before_blocks[:each]) if service.before_blocks[:each]
34
+ after :all, &(service.after_blocks[:all]) if service.after_blocks[:all]
35
+ after :each, &(service.after_blocks[:each]) if service.after_blocks[:each]
36
+
37
+ ServiceRegistry.instance.paths_for(service.name).each do |contract|
38
+ it "#{contract.method} #{contract.path} should return with #{contract.contract_status}" do
39
+ path_object = self.instance_eval(&contract.path_object_block) if contract.path_object_block
40
+ response = contract.perform_request(:path_object=>path_object)
41
+ response.code.should==contract.contract_status
42
+ contract.prepare_response(response.body).should == contract.json_for_spec if contract.contract_json
43
+ response.body.should == contract.contract_body if contract.contract_body
44
+ end
45
+ end
46
+ end
47
+ eg.register
48
+
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,3 @@
1
+ module Irumugam
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,38 @@
1
+ require 'helper/spec_helper'
2
+
3
+ describe Service do
4
+ before(:each) do
5
+ json_hash = {id: 42, name: "Varadha", email: "varadha@thoughtworks.com" }
6
+ @expected_hash = json_hash.stringify_keys
7
+ @expected_hash.delete("id")
8
+
9
+ array_with_symbols_block = Proc.new {
10
+ status 200
11
+ json [json_hash], :ignore=>[:id]
12
+ }
13
+ array_with_strings_block = Proc.new {
14
+ status 200
15
+ json [json_hash.stringify_keys], :ignore=>[:id]
16
+ }
17
+ object_with_symbols_block = Proc.new {
18
+ status 200
19
+ json json_hash, :ignore=>[:id]
20
+ }
21
+ object_with_strings_block = Proc.new {
22
+ status 200
23
+ json json_hash.stringify_keys, :ignore=>[:id]
24
+ }
25
+
26
+ @array_symbols_contract = Contract.new({block: array_with_symbols_block})
27
+ @array_strings_contract = Contract.new({block: array_with_strings_block})
28
+ @object_symbols_contract = Contract.new({block: object_with_symbols_block})
29
+ @object_strings_contract = Contract.new({block: object_with_strings_block})
30
+ end
31
+
32
+ it "json_spec should delete ignored attributes" do
33
+ @array_symbols_contract.json_for_spec.should == [@expected_hash]
34
+ @array_strings_contract.json_for_spec.should == [@expected_hash]
35
+ @object_symbols_contract.json_for_spec.should == @expected_hash
36
+ @object_strings_contract.json_for_spec.should == @expected_hash
37
+ end
38
+ end
@@ -0,0 +1,49 @@
1
+ require File.expand_path("../../../lib/irumugam",__FILE__)
2
+ require 'factory_girl'
3
+ require 'webmock/rspec'
4
+ require 'rack/test'
5
+ include Rack::Test::Methods
6
+ include ::Irumugam
7
+
8
+ FactoryGirl.define do
9
+ factory :user, :class=>Object do
10
+ name "Some Name"
11
+ email "someemail@example.com"
12
+ end
13
+ end
14
+
15
+ def get_reporter(formatter)
16
+ RSpec::Core::Reporter.new(formatter)
17
+ end
18
+
19
+ def sandboxed(&block)
20
+ @orig_config = RSpec.configuration
21
+ @orig_world = RSpec.world
22
+ new_config = RSpec::Core::Configuration.new
23
+ new_world = RSpec::Core::World.new(new_config)
24
+ RSpec.instance_variable_set(:@configuration, new_config)
25
+ RSpec.instance_variable_set(:@world, new_world)
26
+ object = Object.new
27
+ object.extend(RSpec::Core::SharedExampleGroup)
28
+ (class << RSpec::Core::ExampleGroup; self; end).class_eval do
29
+ alias_method :orig_run, :run
30
+ def run(reporter=nil)
31
+ @orig_mock_space = RSpec::Mocks::space
32
+ RSpec::Mocks::space = RSpec::Mocks::Space.new
33
+ orig_run(reporter || NullObject.new)
34
+ ensure
35
+ RSpec::Mocks::space = @orig_mock_space
36
+ end
37
+ end
38
+
39
+ object.instance_eval(&block)
40
+ ensure
41
+ (class << RSpec::Core::ExampleGroup; self; end).class_eval do
42
+ remove_method :run
43
+ alias_method :run, :orig_run
44
+ remove_method :orig_run
45
+ end
46
+
47
+ RSpec.instance_variable_set(:@configuration, @orig_config)
48
+ RSpec.instance_variable_set(:@world, @orig_world)
49
+ end
@@ -0,0 +1,48 @@
1
+ require 'helper/spec_helper'
2
+
3
+ describe Server do
4
+ def app
5
+ Server.new
6
+ end
7
+ before do
8
+ ServiceRegistry.cleanup!
9
+ varadha = {name: "Varadha", email:"varadha@thoughtworks.com"}
10
+ @varadha = varadha
11
+ describe_service "My Glorious Service" do
12
+ host "http://testservice"
13
+ end_point "/glorious_service"
14
+ get "/users" do
15
+ status 200
16
+ json [FactoryGirl.attributes_for(:user)]
17
+ end
18
+ get "/users/:id" do
19
+ status 200
20
+ body ({name: "Some Other Name", email: "email@example.com"}).to_json
21
+ end
22
+ post "/users.json", :body=>{name: "vagmi", email: "vagmi@thoughtworks.com"}, :type=>:json do
23
+ status 201
24
+ json({name: "vagmi", email: "vagmi@thoughtworks.com"}.merge(:id=>23), :ignore=>[:id])
25
+ end
26
+ post "/users.json", :body=>{name: "Varadha", email:"varadha@thoughtworks.com"}, :type=>:json do
27
+ status 201
28
+ json(varadha.merge(:id=>23), :ignore=>[:id])
29
+ end
30
+ end
31
+
32
+ end
33
+ it "should serve rack requests" do
34
+ get "/glorious_service/users"
35
+ last_response.ok?.should be_true
36
+ last_response.body.should == [FactoryGirl.attributes_for(:user)].to_json
37
+ end
38
+ it "should serve post requests with a matching body" do
39
+ post "/glorious_service/users.json", @varadha.to_json, {'CONTENT_TYPE'=>'application/json'}
40
+ last_response.status.should == 201
41
+ JSON.parse(last_response.body).should == @varadha.stringify_keys.merge("id"=>23)
42
+ end
43
+ it "should serve a non-json request" do
44
+ get "/glorious_service/users/1"
45
+ last_response.ok?.should be_true
46
+ last_response.body.should == ({name: "Some Other Name", email: "email@example.com"}).to_json
47
+ end
48
+ end
@@ -0,0 +1,27 @@
1
+ require 'helper/spec_helper'
2
+
3
+ describe ServiceRegistry do
4
+ before(:each) do
5
+ ServiceRegistry.cleanup!
6
+ ServiceRegistry.desc "Auth Service" do
7
+ end_point "/mount_point"
8
+ host "http://testhost"
9
+ get "/path" do
10
+ #expectations
11
+ end
12
+ get "/some_other/path" do
13
+ end
14
+ end
15
+ end
16
+ it "should have a service called Auth Service" do
17
+ service = ServiceRegistry.instance.services["Auth Service"]
18
+ service.should_not be_nil
19
+ service.test_host.should == "http://testhost"
20
+ service.rest_end_point.should == "/mount_point"
21
+ end
22
+ it "should find a contract given a url pattern" do
23
+ contract = ServiceRegistry.find(Rack::Request.new(Rack::MockRequest.env_for("http://testhost/mount_point/path")))
24
+ contract.should_not be_nil
25
+ contract.path.should == "/mount_point/path"
26
+ end
27
+ end
@@ -0,0 +1,56 @@
1
+ require 'helper/spec_helper'
2
+
3
+ describe Service do
4
+ before(:each) do
5
+ ServiceRegistry.cleanup!
6
+ @block = Proc.new {
7
+ end_point "/end_point"
8
+ before(:each) do
9
+ DB.create_record
10
+ end
11
+ before(:all) do
12
+ DB.create_record
13
+ end
14
+ after(:all) do
15
+ DB.create_record
16
+ end
17
+
18
+ after(:each) do
19
+ DB.create_record
20
+ end
21
+ }
22
+ @service = Service.new("Test Service",@block)
23
+ end
24
+ it "should add contracts" do
25
+ @service.get "/users" do
26
+ status 200
27
+ body ({msg: "Hello world"}.to_json)
28
+ end
29
+ @service.post "/users" do
30
+ status 200
31
+ body ({msg: "Hello world"}.to_json)
32
+ end
33
+ @service.put "/users" do
34
+ status 200
35
+ body ({msg: "Hello world"}.to_json)
36
+ end
37
+ @service.delete "/users" do
38
+ status 200
39
+ body ({msg: "Hello world"}.to_json)
40
+ end
41
+ @service.paths["/end_point/users"].count.should==4
42
+ @service.paths["/end_point/users"].map(&:method).should =~ ["GET", "POST", "PUT", "DELETE"]
43
+ end
44
+ it "should have set the before and after hooks" do
45
+ @service.before_blocks[:each].should_not be_nil
46
+ @service.before_blocks[:all].should_not be_nil
47
+ @service.after_blocks[:each].should_not be_nil
48
+ @service.after_blocks[:all].should_not be_nil
49
+ end
50
+ it "should accept json in the contract content" do
51
+ @service.get "/users.json" do
52
+ status 200
53
+ json [{:name=>"name"}], :ignore=>[:id]
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,89 @@
1
+ require 'helper/spec_helper'
2
+ describe SpecWriter do
3
+ before do
4
+ varadha = {name: "Varadha", email: "varadha@thoughtworks.com"}
5
+ stub_request(:get,"http://testservice/glorious_service/users").with(:query=>{}).to_return(:body=>[FactoryGirl.attributes_for(:user)].to_json)
6
+ stub_request(:get,"http://testservice/glorious_service/users/1").with(:query=>{}).to_return(:body=>FactoryGirl.attributes_for(:user).to_json)
7
+ stub_request(:get,"http://testservice/glorious_service/users/1.json").with(:query=>{}).to_return(:body=>FactoryGirl.attributes_for(:user).to_json)
8
+ stub_request(:post,"http://testservice/glorious_service/users.json").with(:query=>{},:body=>varadha).to_return(:body=>varadha.merge({"id"=>22}).to_json, :status=>201)
9
+ stub_request(:put,"http://testservice/glorious_service/users/42.json").with(:query=>{},:body=>varadha).to_return(:body=>varadha.merge({"id"=>42}).to_json, :status=>201)
10
+ $test_object = dup()
11
+ $test_object.should_receive(:teardown).exactly(6).times
12
+ $test_object.should_receive(:setup).exactly(6).times
13
+ $test_object.should_receive(:setup_once).once
14
+ $test_object.should_receive(:teardown_once).once
15
+
16
+ ServiceRegistry.cleanup!
17
+
18
+ describe_service "My Glorious Service" do
19
+ host "http://testservice"
20
+ end_point "/glorious_service"
21
+
22
+ before :all do
23
+ $test_object.setup_once
24
+ end
25
+
26
+ after :all do
27
+ $test_object.teardown_once
28
+ end
29
+
30
+ before(:each) do
31
+ $test_object.setup
32
+ @path_object = {:id=>42}
33
+ end
34
+
35
+ after(:each) do
36
+ $test_object.teardown
37
+ end
38
+
39
+ get "/users" do
40
+ status 200
41
+ json [FactoryGirl.attributes_for(:user)]
42
+ end
43
+
44
+ get "/users/1.json" do
45
+ status 200
46
+ json({id: 43, name: "Some Name", email: "someemail@example.com"}, :ignore=>[:id])
47
+ end
48
+
49
+ get "/users/1.json" do
50
+ status 200
51
+ json({"id" => 42, "name"=>"Some Name", "email"=>"someemail@example.com"}, :ignore=>["id"])
52
+ end
53
+
54
+ post "/users.json", :body=>varadha, :type=>:json do
55
+ status 201
56
+ json varadha.merge(:id=>42), :ignore=>[:id]
57
+ end
58
+
59
+ put "/users/:id.json", :body=>varadha, :type=>:json do
60
+ status 201
61
+ json varadha.merge(:id=>42), :ignore=>[:id]
62
+ path_object { @path_object }
63
+ end
64
+
65
+ get "/users/1" do
66
+ status 200
67
+ body ({name: "Some Other Name", email: "email@example.com"}).to_json
68
+ end
69
+
70
+
71
+ end
72
+ end
73
+
74
+ it "should define specs for the above services" do
75
+ sandboxed do
76
+ formatter = RSpec::Core::Formatters::BaseFormatter.new(nil)
77
+ reporter = get_reporter(formatter)
78
+ register_with_rspec!
79
+ RSpec.world.example_groups.count.should == 1
80
+ RSpec.world.example_groups.first.run(reporter)
81
+ #formatter.failed_examples.each do |fe|
82
+ #puts fe.metadata[:description_args]
83
+ #puts fe.metadata[:execution_result]
84
+ #end
85
+ formatter.examples.count.should == 6
86
+ formatter.failed_examples.count.should == 1
87
+ end
88
+ end
89
+ end
metadata ADDED
@@ -0,0 +1,225 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: irumugam
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Shakir Shakiel
9
+ - Vagmi Mudumbai
10
+ - Lokesh D
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+ date: 2012-07-31 00:00:00.000000000 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: webmock
18
+ requirement: !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ! '>='
22
+ - !ruby/object:Gem::Version
23
+ version: '0'
24
+ type: :development
25
+ prerelease: false
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ none: false
28
+ requirements:
29
+ - - ! '>='
30
+ - !ruby/object:Gem::Version
31
+ version: '0'
32
+ - !ruby/object:Gem::Dependency
33
+ name: factory_girl
34
+ requirement: !ruby/object:Gem::Requirement
35
+ none: false
36
+ requirements:
37
+ - - ! '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ - !ruby/object:Gem::Dependency
49
+ name: rack-test
50
+ requirement: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ! '>='
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ - !ruby/object:Gem::Dependency
65
+ name: rake
66
+ requirement: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ! '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ type: :development
73
+ prerelease: false
74
+ version_requirements: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ! '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ - !ruby/object:Gem::Dependency
81
+ name: rspec
82
+ requirement: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :runtime
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ - !ruby/object:Gem::Dependency
97
+ name: rack
98
+ requirement: !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ! '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ - !ruby/object:Gem::Dependency
113
+ name: httparty
114
+ requirement: !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ! '>='
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ type: :runtime
121
+ prerelease: false
122
+ version_requirements: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ! '>='
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ - !ruby/object:Gem::Dependency
129
+ name: json
130
+ requirement: !ruby/object:Gem::Requirement
131
+ none: false
132
+ requirements:
133
+ - - ! '>='
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ type: :runtime
137
+ prerelease: false
138
+ version_requirements: !ruby/object:Gem::Requirement
139
+ none: false
140
+ requirements:
141
+ - - ! '>='
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ - !ruby/object:Gem::Dependency
145
+ name: activesupport
146
+ requirement: !ruby/object:Gem::Requirement
147
+ none: false
148
+ requirements:
149
+ - - ! '>='
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ type: :runtime
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ none: false
156
+ requirements:
157
+ - - ! '>='
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ description: Describe service contracts that act both as a spec and a mock
161
+ email:
162
+ - shakiras@thoughtworks.com
163
+ - vagmimud@thoughtworks.com
164
+ - lokeshd@thoughtworks.com
165
+ executables: []
166
+ extensions: []
167
+ extra_rdoc_files: []
168
+ files:
169
+ - .gitignore
170
+ - .rvmrc
171
+ - .travis.yml
172
+ - Gemfile
173
+ - README.md
174
+ - Rakefile
175
+ - irumugam.gemspec
176
+ - lib/irumugam.rb
177
+ - lib/irumugam/contract.rb
178
+ - lib/irumugam/server.rb
179
+ - lib/irumugam/service.rb
180
+ - lib/irumugam/service_registry.rb
181
+ - lib/irumugam/spec_writer.rb
182
+ - lib/irumugam/version.rb
183
+ - spec/contract_spec.rb
184
+ - spec/helper/spec_helper.rb
185
+ - spec/server_spec.rb
186
+ - spec/service_registry_spec.rb
187
+ - spec/service_spec.rb
188
+ - spec/spec_writer_spec.rb
189
+ homepage: ''
190
+ licenses: []
191
+ post_install_message:
192
+ rdoc_options: []
193
+ require_paths:
194
+ - lib
195
+ required_ruby_version: !ruby/object:Gem::Requirement
196
+ none: false
197
+ requirements:
198
+ - - ! '>='
199
+ - !ruby/object:Gem::Version
200
+ version: '0'
201
+ segments:
202
+ - 0
203
+ hash: 1712470912957311514
204
+ required_rubygems_version: !ruby/object:Gem::Requirement
205
+ none: false
206
+ requirements:
207
+ - - ! '>='
208
+ - !ruby/object:Gem::Version
209
+ version: '0'
210
+ segments:
211
+ - 0
212
+ hash: 1712470912957311514
213
+ requirements: []
214
+ rubyforge_project: irumugam
215
+ rubygems_version: 1.8.24
216
+ signing_key:
217
+ specification_version: 3
218
+ summary: Describe service contracts that act both as a spec and a mock
219
+ test_files:
220
+ - spec/contract_spec.rb
221
+ - spec/helper/spec_helper.rb
222
+ - spec/server_spec.rb
223
+ - spec/service_registry_spec.rb
224
+ - spec/service_spec.rb
225
+ - spec/spec_writer_spec.rb