savon_spec 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.
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
+