skink 0.2.0 → 0.3.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.
@@ -1,9 +1,12 @@
1
1
  require 'skink'
2
+ require 'skink/client/utils'
2
3
 
3
4
  module Skink
4
5
  module Client
5
6
 
6
7
  class Base
8
+ include Utils
9
+
7
10
  def with_header(name, value)
8
11
  raise NotImplementedError
9
12
  end
@@ -56,31 +59,9 @@ class Base
56
59
  if name.match(/with_(\w+)_header/)
57
60
  with_header(normalize_header_name($1), *args)
58
61
  else
59
- super
62
+ super(name, *args)
60
63
  end
61
64
  end
62
-
63
- private
64
- def normalize_header_name(name)
65
- # c.f http://en.wikipedia.org/wiki/List_of_HTTP_header_fields
66
-
67
- case name
68
- # special cases
69
- when /^content_md5$/i
70
- return "Content-MD5"
71
- when /^te$/i
72
- return "TE"
73
- when /^dnt$/i
74
- return "DNT"
75
- when /^etag$/i
76
- return "ETag"
77
- when /^www_authenticate$/i
78
- return "WWW-Authenticate"
79
- end
80
-
81
- # otherwise this should work
82
- name.split("_").map(&:capitalize).join("-")
83
- end
84
65
  end
85
66
 
86
67
  end
@@ -1,7 +1,14 @@
1
+ require 'skink/client/utils'
2
+
3
+ require 'nokogiri'
4
+ require 'jsonpath'
5
+
1
6
  module Skink
2
7
  module Client
3
8
 
4
9
  class Response
10
+ include Utils
11
+
5
12
  def status_code
6
13
  raise NotImplementedError
7
14
  end
@@ -10,9 +17,76 @@ class Response
10
17
  raise NotImplementedError
11
18
  end
12
19
 
20
+ def find_header header
21
+ case header
22
+ when String
23
+ headers[headers.keys.detect {|key| key.match(/^#{header}$/i)}] rescue nil
24
+ when Symbol
25
+ headers[headers.keys.detect {|key| key.match(/^#{header.to_s.gsub('_', '-')}$/i)}] rescue nil
26
+ end
27
+ end
28
+
29
+ def has_header? header
30
+ if find_header(header)
31
+ true
32
+ elsif header.respond_to? :keys
33
+ header.all? do |key, value|
34
+ value === find_header(key)
35
+ end
36
+ else
37
+ false
38
+ end
39
+ end
40
+
13
41
  def body
14
42
  raise NotImplementedError
15
43
  end
44
+
45
+ def xml_doc
46
+ @xml_doc ||= Nokogiri::XML.parse body
47
+ end
48
+
49
+ def xpath path
50
+ xml_doc.xpath path
51
+ end
52
+
53
+ def has_xpath? path, value = nil
54
+ elems = xpath(path)
55
+ if value
56
+ block = ->(elem) {value === elem.to_s}
57
+ else
58
+ block = nil
59
+ end
60
+
61
+ elems.any?(&block)
62
+ end
63
+
64
+ def json_doc
65
+ @json_doc ||= MultiJson.load body
66
+ end
67
+
68
+ def jsonpath path
69
+ JsonPath.new(path).on json_doc
70
+ end
71
+
72
+ def has_jsonpath? path, value = nil
73
+ elems = jsonpath(path)
74
+ if value
75
+ block = ->(elem) {value === elem}
76
+ else
77
+ block = nil
78
+ end
79
+
80
+ elems.any?(&block)
81
+ end
82
+
83
+ def method_missing(name, *args)
84
+ if name.match(/has_(\w+)_header\?/)
85
+ headers[normalize_header_name($1)] === args.first
86
+ else
87
+ super
88
+ end
89
+ end
16
90
  end
17
91
 
18
92
  end
@@ -0,0 +1,28 @@
1
+ module Skink
2
+ module Client
3
+
4
+ module Utils
5
+ def normalize_header_name(name)
6
+ # c.f http://en.wikipedia.org/wiki/List_of_HTTP_header_fields
7
+
8
+ case name
9
+ # special cases
10
+ when /^content_md5$/i
11
+ return "Content-MD5"
12
+ when /^te$/i
13
+ return "TE"
14
+ when /^dnt$/i
15
+ return "DNT"
16
+ when /^etag$/i
17
+ return "ETag"
18
+ when /^www_authenticate$/i
19
+ return "WWW-Authenticate"
20
+ end
21
+
22
+ # otherwise this should work
23
+ name.split("_").map(&:capitalize).join("-")
24
+ end
25
+ end
26
+
27
+ end
28
+ end
data/lib/skink/dsl.rb CHANGED
@@ -41,7 +41,11 @@ module Skink
41
41
 
42
42
  Skink::Client::Base.instance_methods(false).each do |method|
43
43
  define_method method do |*args, &block|
44
- Skink.client.send method, *args, &block
44
+ begin
45
+ Skink.client.send method, *args, &block
46
+ rescue NoMethodError
47
+ super(*args) if method == :method_missing
48
+ end
45
49
  end
46
50
  end
47
51
  end
@@ -13,6 +13,10 @@ class RackTestResponse < Client::Response
13
13
  native_response.status
14
14
  end
15
15
 
16
+ def has_status_code? code
17
+ native_response.status == code
18
+ end
19
+
16
20
  def headers
17
21
  native_response.header
18
22
  end
@@ -13,8 +13,12 @@ class ResourcefulResponse < Client::Response
13
13
  native_response.code
14
14
  end
15
15
 
16
+ def has_status_code? code
17
+ native_response.code == code
18
+ end
19
+
16
20
  def headers
17
- native_response.headers
21
+ native_response.headers.to_hash
18
22
  end
19
23
 
20
24
  def body
data/lib/skink/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Skink
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
data/skink.gemspec CHANGED
@@ -14,6 +14,8 @@ Gem::Specification.new do |gem|
14
14
 
15
15
  gem.add_dependency "rack-test"
16
16
  gem.add_dependency "openlogic-resourceful"
17
+ gem.add_dependency "nokogiri"
18
+ gem.add_dependency "jsonpath"
17
19
 
18
20
  gem.add_development_dependency "rspec"
19
21
  gem.add_development_dependency "sinatra"
@@ -3,13 +3,13 @@ require_relative './spec_helper'
3
3
  shared_examples "a REST API test language" do
4
4
  it "is able to test a HEAD" do
5
5
  head "/"
6
- response.status_code.should == 200
6
+ response.should have_status_code 200
7
7
  response.body.size.should == 0
8
8
  end
9
9
 
10
10
  it "is able to test a GET" do
11
11
  get "/"
12
- response.status_code.should == 200
12
+ response.should have_status_code 200
13
13
  response.body.should == "Hello, world!"
14
14
  end
15
15
 
@@ -17,7 +17,7 @@ shared_examples "a REST API test language" do
17
17
  body = "<ping/>"
18
18
  with_content_type_header "application/xml"
19
19
  post "/", body
20
- response.status_code.should == 200
20
+ response.should have_status_code 200
21
21
  response.body.should == body
22
22
  end
23
23
 
@@ -25,39 +25,70 @@ shared_examples "a REST API test language" do
25
25
  body = "{\"ping\": \"hello\"}"
26
26
  with_content_type_header "application/json"
27
27
  put "/", body
28
- response.status_code.should == 200
28
+ response.should have_status_code 200
29
29
  response.body.should == body
30
30
  end
31
31
 
32
32
  it "is able to test a DELETE" do
33
33
  delete "/"
34
- response.status_code.should == 200
34
+ response.should have_status_code 200
35
35
  response.body.should == "Deleted"
36
36
  end
37
37
 
38
38
  it "is able to test a request with additional headers" do
39
39
  with_accept_header "application/json"
40
40
  get "/foo"
41
- response.status_code.should == 200
41
+ response.should have_status_code 200
42
42
  response.body.should == "{\"foo\": 42}"
43
43
  end
44
44
 
45
45
  it "is able to test requests which require basic authentication" do
46
46
  with_basic_auth "admin", "admin"
47
47
  get "/protected"
48
- response.status_code.should == 200
48
+ response.should have_status_code 200
49
49
  response.body.should == "Welcome, authenticated client."
50
50
  end
51
51
 
52
52
  it "is able to test requests which require basic authentication for specified realm" do
53
53
  get "/protected"
54
- response.status_code.should == 401
54
+ response.should have_status_code 401
55
55
 
56
56
  with_basic_auth "admin", "admin", "Restricted Area"
57
57
  get "/protected"
58
- response.status_code.should == 200
58
+ response.should have_status_code 200
59
59
  response.body.should == "Welcome, authenticated client."
60
60
  end
61
+
62
+ it "is able to test the presence of specified response headers" do
63
+ with_accept_header "application/json"
64
+ get "/json_doc"
65
+ response.should have_header(:content_type)
66
+ response.should have_header("Content-Type")
67
+ response.should_not have_header("This-Is-Not-A-Header-Name")
68
+ end
69
+
70
+ it "is able to test the value of specified response headers" do
71
+ with_accept_header "application/xml"
72
+ get "/xml_doc"
73
+ response.should have_header(content_type: %r{charset})
74
+ response.should_not have_header(content_type: %r{json})
75
+ end
76
+
77
+ it "is able to test for the presence of elements in the response body" do
78
+ with_accept_header "application/xml"
79
+ get "/xml_doc"
80
+ response.should have_xpath "//foo/foo"
81
+ response.should_not have_xpath "//bar/foo"
82
+ response.should have_xpath "//foo", /Some/
83
+ response.should_not have_xpath "//foo", /bar/
84
+
85
+ with_accept_header "application/json"
86
+ get "/json_doc"
87
+ response.should have_jsonpath "root.foo.foo"
88
+ response.should_not have_jsonpath "shazbot.mcgillicuddy"
89
+ response.should have_jsonpath "root.foo.foo", /ow/
90
+ response.should_not have_jsonpath "root.foo.foo", /oo/
91
+ end
61
92
  end
62
93
 
63
94
  describe Skink::DSL do
data/spec/test_server.rb CHANGED
@@ -38,3 +38,11 @@ get '/protected' do
38
38
  protected!
39
39
  "Welcome, authenticated client."
40
40
  end
41
+
42
+ get '/xml_doc', :provides => :xml do
43
+ "<root><foo attr=\"true\">Some text<foo/></foo></root>"
44
+ end
45
+
46
+ get '/json_doc', :provides => :json do
47
+ '{"root": {"foo": {"foo": "howdy"}}}'
48
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: skink
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-14 00:00:00.000000000 Z
12
+ date: 2012-09-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack-test
@@ -43,6 +43,38 @@ dependencies:
43
43
  - - ! '>='
44
44
  - !ruby/object:Gem::Version
45
45
  version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: nokogiri
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: jsonpath
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
46
78
  - !ruby/object:Gem::Dependency
47
79
  name: rspec
48
80
  requirement: !ruby/object:Gem::Requirement
@@ -90,6 +122,7 @@ files:
90
122
  - lib/skink.rb
91
123
  - lib/skink/client/base.rb
92
124
  - lib/skink/client/response.rb
125
+ - lib/skink/client/utils.rb
93
126
  - lib/skink/dsl.rb
94
127
  - lib/skink/integrations/rails.rb
95
128
  - lib/skink/integrations/rspec.rb