savon_spec 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,9 @@
1
+ .DS_Store
2
+ .yardoc
3
+ doc
4
+ coverage
5
+ tmp
6
+ *~
7
+ *.gem
8
+ .bundle
9
+ Gemfile.lock
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source :rubygems
2
+ gemspec
data/README.md ADDED
@@ -0,0 +1,114 @@
1
+ Savon::Spec
2
+ ===========
3
+
4
+ Savon testing library
5
+
6
+ Installation
7
+ ------------
8
+
9
+ Savon::Spec is available through [Rubygems](http://rubygems.org/gems/savon_spec) and can be installed via:
10
+
11
+ $ gem install savon_spec
12
+
13
+ Dependencies
14
+ ------------
15
+
16
+ Currently, the dependencies are very strict. Savon::Spec is meant to be used with:
17
+
18
+ * [Savon](http://rubygems.org/gems/savon) ~> 0.8.0.beta.3
19
+ * [RSpec](http://rubygems.org/gems/rspec) ~> 2.0.0
20
+ * [Mocha](http://rubygems.org/gems/mocha) ~> 0.9.8
21
+
22
+ Note to self: the required versions for RSpec and Mocha could probably be lower.
23
+
24
+ Getting started
25
+ ---------------
26
+
27
+ ### Macros
28
+
29
+ Include the `Savon::Spec::Macros` module:
30
+
31
+ RSpec.configure do |config|
32
+ config.include Savon::Spec::Macros
33
+ end
34
+
35
+ ### Mock
36
+
37
+ By including the macros, you have access to the `savon` method in your specs. It returns a `Savon::Spec::Mock` instance to set up your expectations. It's based on Mocha and comes with similiar methods:
38
+
39
+ #expects(soap_action) # mocks SOAP request to a given SOAP action
40
+ #stubs(soap_action) # stubs SOAP requests to a given SOAP action
41
+ #with(soap_body) # expects Savon to send a given SOAP body
42
+ #returns(response) # returns the given response
43
+
44
+ ### Fixtures
45
+
46
+ Savon::Spec works best with SOAP response fixtures (simple XML files) and a conventional folder structure:
47
+
48
+ ~ spec
49
+ ~ fixtures
50
+ ~ get_user
51
+ - single_user.xml
52
+ - multiple_users.xml
53
+ + models
54
+ + controllers
55
+ + helpers
56
+ + views
57
+
58
+ When used inside a Rails 3 application, Savon::Spec uses the command `Rails.root.join("spec", "fixtures")` to locate your fixture directory. In any other case, you have to manually set the fixture path via:
59
+
60
+ Savon::Spec::Fixture.path = File.expand_path("../fixtures", __FILE__)
61
+
62
+ The directories inside the fixture directory should map to SOAP actions and the XML fixtures inside those directories should describe the SOAP response. Please take a look at the following examples to better understand this convention.
63
+
64
+ Some examples
65
+ -------------
66
+
67
+ # user.rb
68
+
69
+ class User
70
+
71
+ def self.all
72
+ response = client.request :get_all_users
73
+ response.to_hash.map { |user_hash| new user_hash }
74
+ end
75
+
76
+ def self.find(user_id)
77
+ response = client.request :get_user do
78
+ soap.body = { :id => user_id }
79
+ end
80
+
81
+ new response.to_hash
82
+ end
83
+
84
+ end
85
+
86
+ # user_spec.rb
87
+
88
+ describe User do
89
+
90
+ describe ".all" do
91
+ before do
92
+ savon.expects(:get_all_users).returns(:multiple_users)
93
+ end
94
+
95
+ it "should return an Array of Users" do
96
+ User.all.each { |user| user.should be_a(User) }
97
+ end
98
+
99
+ it "should return exactly 7 Users" do
100
+ User.all.should have(7).items
101
+ end
102
+ end
103
+
104
+ describe ".find" do
105
+ before do
106
+ savon.expects(:get_user).with(:id => 1).returns(:single_user)
107
+ end
108
+
109
+ it "should return a User for a given :id" do
110
+ User.find(1).should be_a(User)
111
+ end
112
+ end
113
+
114
+ end
data/Rakefile ADDED
@@ -0,0 +1,39 @@
1
+ require "rake"
2
+
3
+ begin
4
+ require "yard"
5
+
6
+ YARD::Rake::YardocTask.new do |t|
7
+ t.files = ["README.md", "lib/**/*.rb"]
8
+ end
9
+ rescue LoadError
10
+ desc message = %{"gem install yard" to generate documentation}
11
+ task("yard") { abort message }
12
+ end
13
+
14
+ begin
15
+ require "metric_fu"
16
+
17
+ MetricFu::Configuration.run do |c|
18
+ c.metrics = [:churn, :flog, :flay, :reek, :roodi, :saikuro] # :rcov seems to be broken
19
+ c.graphs = [:flog, :flay, :reek, :roodi]
20
+ c.flay = { :dirs_to_flay => ["lib"], :minimum_score => 20 }
21
+ c.rcov[:rcov_opts] << "-Ilib -Ispec"
22
+ end
23
+ rescue LoadError
24
+ desc message = %{"gem install metric_fu" to generate metrics}
25
+ task("metrics:all") { abort message }
26
+ end
27
+
28
+ begin
29
+ require "rspec/core/rake_task"
30
+
31
+ RSpec::Core::RakeTask.new do |t|
32
+ t.rspec_opts = %w(-fd -c)
33
+ end
34
+ rescue LoadError
35
+ desc message = %{"gem install rspec" to run the specs}
36
+ task(:spec) { abort message }
37
+ end
38
+
39
+ task :default => :spec
@@ -0,0 +1 @@
1
+ Autotest.add_discovery { "rspec2" }
@@ -0,0 +1,42 @@
1
+ module Savon
2
+ module Spec
3
+
4
+ # = Savon::Spec::Fixture
5
+ #
6
+ # Loads SOAP response fixtures.
7
+ class Fixture
8
+ class << self
9
+
10
+ def path
11
+ @path ||= Rails.root.join("spec", "fixtures").to_s if defined? Rails
12
+
13
+ raise ArgumentError, "Savon::Spec::Fixture.path needs to be specified" unless @path
14
+ @path
15
+ end
16
+
17
+ attr_writer :path
18
+
19
+ def load(*args)
20
+ file = args.map { |arg| arg.to_s.snakecase }.join("/")
21
+ fixtures[file] ||= load_file file
22
+ end
23
+
24
+ alias [] load
25
+
26
+ private
27
+
28
+ def fixtures
29
+ @fixtures ||= {}
30
+ end
31
+
32
+ def load_file(file)
33
+ full_path = File.expand_path File.join(path, "#{file}.xml")
34
+ raise ArgumentError, "Unable to load: #{full_path}" unless File.exist? full_path
35
+
36
+ File.read full_path
37
+ end
38
+
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,17 @@
1
+ require "savon/spec/mock"
2
+
3
+ module Savon
4
+ module Spec
5
+
6
+ # = Savon::Spec::Macros
7
+ #
8
+ # Include this module into your RSpec tests to mock/stub Savon SOAP requests.
9
+ module Macros
10
+
11
+ def savon
12
+ Savon::Spec::Mock.new
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,67 @@
1
+ require "savon/spec/fixture"
2
+
3
+ module Savon
4
+ module Spec
5
+
6
+ # = Savon::Spec::Mock
7
+ #
8
+ # Mocks/stubs SOAP requests executed by Savon.
9
+ class Mock
10
+
11
+ # Mocks SOAP requests to a given <tt>soap_action</tt>.
12
+ def expects(soap_action)
13
+ setup :expects, soap_action
14
+ self
15
+ end
16
+
17
+ # Stubs SOAP requests to a given <tt>soap_action</tt>.
18
+ def stubs(soap_action)
19
+ setup :stubs, soap_action
20
+ self
21
+ end
22
+
23
+ # Expects a given SOAP body Hash to be used.
24
+ def with(soap_body)
25
+ Savon::SOAP::XML.any_instance.expects(:body=).with(soap_body) if mock_method == :expects
26
+ self
27
+ end
28
+
29
+ # Sets up HTTPI to return a given +response+.
30
+ def returns(response = nil)
31
+ http = { :code => 200, :headers => {}, :body => "" }
32
+
33
+ case response
34
+ when Symbol then http[:body] = Fixture[soap_action, response]
35
+ when Hash then http.merge! response
36
+ when String then http[:body] = response
37
+ end
38
+
39
+ httpi_mock.returns HTTPI::Response.new(http[:code], http[:headers], http[:body])
40
+ self
41
+ end
42
+
43
+ private
44
+
45
+ def setup(mock_method, soap_action)
46
+ self.mock_method = mock_method
47
+ self.soap_action = soap_action
48
+ self.httpi_mock = new_httpi_mock
49
+ end
50
+
51
+ attr_accessor :mock_method
52
+
53
+ def soap_action=(soap_action)
54
+ @soap_action = soap_action.kind_of?(Symbol) ? soap_action.to_s.lower_camelcase : soap_action
55
+ end
56
+
57
+ attr_reader :soap_action
58
+
59
+ def new_httpi_mock
60
+ HTTPI.send(mock_method, :post).with { |http| http.body.include? soap_action }
61
+ end
62
+
63
+ attr_accessor :httpi_mock
64
+
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,7 @@
1
+ module Savon
2
+ module Spec
3
+
4
+ VERSION = "0.1.0"
5
+
6
+ end
7
+ end
data/lib/savon/spec.rb ADDED
@@ -0,0 +1,10 @@
1
+ require "savon"
2
+ require "rspec"
3
+ require "mocha"
4
+
5
+ RSpec.configure do |config|
6
+ config.mock_with :mocha
7
+ end
8
+
9
+ require "savon/spec/version"
10
+ require "savon/spec/macros"
data/lib/savon_spec.rb ADDED
@@ -0,0 +1 @@
1
+ require "savon/spec"
@@ -0,0 +1,26 @@
1
+ lib = File.expand_path("../lib/", __FILE__)
2
+ $:.unshift lib unless $:.include?(lib)
3
+
4
+ require "savon/spec/version"
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "savon_spec"
8
+ s.version = Savon::Spec::VERSION
9
+ s.authors = "Daniel Harrington"
10
+ s.email = "me@rubiii.com"
11
+ s.homepage = "http://github.com/rubiii/#{s.name}"
12
+ s.summary = "Savon testing library"
13
+ s.description = "Test helpers for the Savon SOAP library."
14
+
15
+ s.rubyforge_project = s.name
16
+
17
+ s.add_dependency "savon", "~> 0.8.0.beta.3"
18
+ s.add_dependency "rspec", "~> 2.0.0"
19
+ s.add_dependency "mocha", "~> 0.9.8"
20
+
21
+ s.add_development_dependency "httpclient", "~> 2.1.5"
22
+ s.add_development_dependency "webmock", "~> 1.4.0"
23
+
24
+ s.files = `git ls-files`.split("\n")
25
+ s.require_path = "lib"
26
+ end
@@ -0,0 +1,10 @@
1
+ <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
2
+ <soap:Body>
3
+ <ns2:getUserResponse xmlns:ns2="http://users.example.com/">
4
+ <return>
5
+ <name>Kent</name>
6
+ <email>kent@example.com</email>
7
+ </return>
8
+ </ns2:getUserResponse>
9
+ </soap:Body>
10
+ </soap:Envelope>
@@ -0,0 +1,45 @@
1
+ require "spec_helper"
2
+
3
+ describe Savon::Spec::Fixture do
4
+
5
+ describe ".path" do
6
+ it "should return a specified path" do
7
+ Savon::Spec::Fixture.path = "/Users/rubiii/my_app/spec/fixtures"
8
+ Savon::Spec::Fixture.path.should == "/Users/rubiii/my_app/spec/fixtures"
9
+
10
+ Savon::Spec::Fixture.path = nil # reset to default
11
+ end
12
+
13
+ it "should raise an ArgumentError if accessed before specified" do
14
+ lambda { Savon::Spec::Fixture.path }.should raise_error(ArgumentError)
15
+ end
16
+
17
+ it "should default to spec/fixtures if used in a Rails app" do
18
+ Rails = Class.new
19
+ Rails.expects(:root).returns(Pathname.new("/Users/rubiii/another_app"))
20
+
21
+ Savon::Spec::Fixture.path.should == "/Users/rubiii/another_app/spec/fixtures"
22
+
23
+ Object.send(:remove_const, "Rails")
24
+ end
25
+ end
26
+
27
+ describe ".load" do
28
+ around do |example|
29
+ Savon::Spec::Fixture.path = "spec/fixtures"
30
+ example.run
31
+ Savon::Spec::Fixture.path = nil # reset to default
32
+ end
33
+
34
+ it "should return a fixture for the given arguments" do
35
+ fixture = Savon::Spec::Fixture.load :get_user, :success
36
+ fixture.should == File.read("spec/fixtures/get_user/success.xml")
37
+ end
38
+
39
+ it "should memoize the fixtures" do
40
+ Savon::Spec::Fixture.load(:get_user, :success).
41
+ should equal(Savon::Spec::Fixture.load(:get_user, :success))
42
+ end
43
+ end
44
+
45
+ end
@@ -0,0 +1,12 @@
1
+ require "spec_helper"
2
+
3
+ describe Savon::Spec::Macros do
4
+ include Savon::Spec::Macros
5
+
6
+ describe "#savon" do
7
+ it "should return a Savon::Spec::Mock instance" do
8
+ savon.should be_a(Savon::Spec::Mock)
9
+ end
10
+ end
11
+
12
+ end
@@ -0,0 +1,166 @@
1
+ require "spec_helper"
2
+
3
+ Savon.configure do |config|
4
+ config.log = false
5
+ end
6
+
7
+ describe Savon::Spec::Mock do
8
+ include Savon::Spec::Macros
9
+
10
+ let :client do
11
+ Savon::Client.new do
12
+ wsdl.endpoint = "http://example.com"
13
+ wsdl.namespace = "http://users.example.com"
14
+ end
15
+ end
16
+
17
+ describe "#expects" do
18
+ before { savon.expects(:get_user).returns }
19
+
20
+ it "should set up HTTPI to mock POST requests for a given SOAP action" do
21
+ client.request :get_user
22
+ end
23
+
24
+ context "without a request to mock" do
25
+ around do |example|
26
+ begin
27
+ example.run
28
+ rescue Mocha::ExpectationError => e
29
+ e.message.should include("expected exactly once, not yet invoked: HTTPI.post")
30
+ end
31
+ end
32
+
33
+ it "should fail" do
34
+ end
35
+ end
36
+ end
37
+
38
+ describe "#expects and #with" do
39
+ before { savon.expects(:get_user).with(:id => 1).returns }
40
+
41
+ it "should expect Savon to send a given SOAP body" do
42
+ client.request :get_user do
43
+ soap.body = { :id => 1 }
44
+ end
45
+ end
46
+
47
+ context "with a request without SOAP body" do
48
+ around do |example|
49
+ begin
50
+ example.run
51
+ rescue Mocha::ExpectationError => e
52
+ e.message.should include("expected exactly once, not yet invoked: #<AnyInstance:Savon::SOAP::XML>.body=(:id => 1)")
53
+ end
54
+ end
55
+
56
+ it "should fail" do
57
+ client.request :get_user
58
+ end
59
+ end
60
+ end
61
+
62
+ describe "#stubs" do
63
+ before { savon.stubs(:get_user).returns }
64
+
65
+ it "should set up HTTPI to stub POST requests for a given SOAP action" do
66
+ client.request :get_user
67
+ end
68
+
69
+ it "should not complain about requests not being executed" do
70
+ # no request
71
+ end
72
+ end
73
+
74
+ describe "#stubs and #with" do
75
+ before { savon.stubs(:get_user).with(:id => 1).returns }
76
+
77
+ it "should not expect Savon to send a given SOAP body" do
78
+ client.request :get_user
79
+ end
80
+ end
81
+
82
+ describe "#returns" do
83
+ context "without arguments" do
84
+ let(:response) { client.request :get_user }
85
+
86
+ before { savon.expects(:get_user).returns }
87
+
88
+ it "should return a response code of 200" do
89
+ response.http.code.should == 200
90
+ end
91
+
92
+ it "should not return any response headers" do
93
+ response.http.headers.should == {}
94
+ end
95
+
96
+ it "should return an empty response body" do
97
+ response.http.body.should == ""
98
+ end
99
+ end
100
+
101
+ context "with a String" do
102
+ let(:response) { client.request :get_user }
103
+
104
+ before { savon.expects(:get_user).returns("<soap>response</soap>") }
105
+
106
+ it "should return a response code of 200" do
107
+ response.http.code.should == 200
108
+ end
109
+
110
+ it "should not return any response headers" do
111
+ response.http.headers.should == {}
112
+ end
113
+
114
+ it "should return the given response body" do
115
+ response.http.body.should == "<soap>response</soap>"
116
+ end
117
+ end
118
+
119
+ context "with a Symbol" do
120
+ let(:response) { client.request :get_user }
121
+
122
+ around do |example|
123
+ Savon::Spec::Fixture.path = "spec/fixtures"
124
+ savon.expects(:get_user).returns(:success)
125
+
126
+ example.run
127
+
128
+ Savon::Spec::Fixture.path = nil # reset to default
129
+ end
130
+
131
+ it "should return a response code of 200" do
132
+ response.http.code.should == 200
133
+ end
134
+
135
+ it "should not return any response headers" do
136
+ response.http.headers.should == {}
137
+ end
138
+
139
+ it "should return the :success fixture for the :get_user action" do
140
+ response.http.body.should == File.read("spec/fixtures/get_user/success.xml")
141
+ end
142
+ end
143
+
144
+ context "with a Hash" do
145
+ let(:response) { client.request :get_user }
146
+
147
+ before do
148
+ @hash = { :code => 201, :headers => { "Set-Cookie" => "ID=1; Max-Age=3600;" }, :body => "<with>cookie</with>" }
149
+ savon.expects(:get_user).returns(@hash)
150
+ end
151
+
152
+ it "should return the given response code" do
153
+ response.http.code.should == @hash[:code]
154
+ end
155
+
156
+ it "should return the given response headers" do
157
+ response.http.headers.should == @hash[:headers]
158
+ end
159
+
160
+ it "should return the given response body" do
161
+ response.http.body.should == @hash[:body]
162
+ end
163
+ end
164
+ end
165
+
166
+ end
@@ -0,0 +1,4 @@
1
+ require "bundler"
2
+ Bundler.require(:default, :development)
3
+
4
+ require "savon_spec"
metadata ADDED
@@ -0,0 +1,165 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: savon_spec
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Daniel Harrington
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-11-06 00:00:00 +01:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: savon
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 62196261
30
+ segments:
31
+ - 0
32
+ - 8
33
+ - 0
34
+ - beta
35
+ - 3
36
+ version: 0.8.0.beta.3
37
+ type: :runtime
38
+ version_requirements: *id001
39
+ - !ruby/object:Gem::Dependency
40
+ name: rspec
41
+ prerelease: false
42
+ requirement: &id002 !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ hash: 15
48
+ segments:
49
+ - 2
50
+ - 0
51
+ - 0
52
+ version: 2.0.0
53
+ type: :runtime
54
+ version_requirements: *id002
55
+ - !ruby/object:Gem::Dependency
56
+ name: mocha
57
+ prerelease: false
58
+ requirement: &id003 !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ~>
62
+ - !ruby/object:Gem::Version
63
+ hash: 43
64
+ segments:
65
+ - 0
66
+ - 9
67
+ - 8
68
+ version: 0.9.8
69
+ type: :runtime
70
+ version_requirements: *id003
71
+ - !ruby/object:Gem::Dependency
72
+ name: httpclient
73
+ prerelease: false
74
+ requirement: &id004 !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ~>
78
+ - !ruby/object:Gem::Version
79
+ hash: 1
80
+ segments:
81
+ - 2
82
+ - 1
83
+ - 5
84
+ version: 2.1.5
85
+ type: :development
86
+ version_requirements: *id004
87
+ - !ruby/object:Gem::Dependency
88
+ name: webmock
89
+ prerelease: false
90
+ requirement: &id005 !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ~>
94
+ - !ruby/object:Gem::Version
95
+ hash: 7
96
+ segments:
97
+ - 1
98
+ - 4
99
+ - 0
100
+ version: 1.4.0
101
+ type: :development
102
+ version_requirements: *id005
103
+ description: Test helpers for the Savon SOAP library.
104
+ email: me@rubiii.com
105
+ executables: []
106
+
107
+ extensions: []
108
+
109
+ extra_rdoc_files: []
110
+
111
+ files:
112
+ - .gitignore
113
+ - .rspec
114
+ - Gemfile
115
+ - README.md
116
+ - Rakefile
117
+ - autotest/discover.rb
118
+ - lib/savon/spec.rb
119
+ - lib/savon/spec/fixture.rb
120
+ - lib/savon/spec/macros.rb
121
+ - lib/savon/spec/mock.rb
122
+ - lib/savon/spec/version.rb
123
+ - lib/savon_spec.rb
124
+ - savon_spec.gemspec
125
+ - spec/fixtures/get_user/success.xml
126
+ - spec/savon/spec/fixture_spec.rb
127
+ - spec/savon/spec/macros_spec.rb
128
+ - spec/savon/spec/mock_spec.rb
129
+ - spec/spec_helper.rb
130
+ has_rdoc: true
131
+ homepage: http://github.com/rubiii/savon_spec
132
+ licenses: []
133
+
134
+ post_install_message:
135
+ rdoc_options: []
136
+
137
+ require_paths:
138
+ - lib
139
+ required_ruby_version: !ruby/object:Gem::Requirement
140
+ none: false
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ hash: 3
145
+ segments:
146
+ - 0
147
+ version: "0"
148
+ required_rubygems_version: !ruby/object:Gem::Requirement
149
+ none: false
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ hash: 3
154
+ segments:
155
+ - 0
156
+ version: "0"
157
+ requirements: []
158
+
159
+ rubyforge_project: savon_spec
160
+ rubygems_version: 1.3.7
161
+ signing_key:
162
+ specification_version: 3
163
+ summary: Savon testing library
164
+ test_files: []
165
+