irumugam 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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