rspec-hal 1.1.0 → 1.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9463991d7f7b862e2979e8f110458daa8a005f8f
4
- data.tar.gz: a28bf60caeb1602ea86ee49bf70cfbb87e6a14bf
3
+ metadata.gz: 56ffc8c99f84bb144a2dc97705eb0499a2bb1cd7
4
+ data.tar.gz: 8983c9abffc8c5980330c950d268914b3a01eebe
5
5
  SHA512:
6
- metadata.gz: 459b268f52a050327e80253dbffd0d9172f2c7ecf81b2687eb2953fcc0f7281dd4eea58efbf74e4d32ccd14731e18a099abf4231bb76e9713a5fae00e3dc0ae0
7
- data.tar.gz: e48f6a959f34e8db673a2db0995b3c2cd5cde16f2e9b73c9bde3f76a42f119ca57d628df284dabd21ec3ffadfe6ba1548a9c4b99b78d7793a304ea411a1994f3
6
+ metadata.gz: 345a34323d5c89748d3355cba81016e3bc1c2657828073ea51a9133bb89ccd51d34062efb817f8114328f49aaf3208f80659b1fa9cfddf0fa585ad56e1bd6e15
7
+ data.tar.gz: d71388e4b12afda7a66e7a5311579a6b8c47611a1a979a5bb9655423583a37806e0e6eef5f914eda53d970e40b0e119932494237aacf69c72552662bd5262dc7
data/README.md CHANGED
@@ -10,15 +10,15 @@ Provides matchers and convenience methods for verifying HAL documents.
10
10
  Include the matchers by adding this to your spec_helper
11
11
 
12
12
  ```ruby
13
- RSpec.configuration.include RSpec::Hal::Matchers::Documents
13
+ RSpec.configuration.include RSpec::Hal::Matchers
14
14
  ```
15
15
 
16
- (Don't forget to `require rspec-hal` if you are not using bundler.)
16
+ (Don't forget to `require "rspec-hal"` if you are not using bundler.)
17
17
 
18
18
  If you are using rspec-rails and want only include the matchers for views do this
19
19
 
20
20
  ```ruby
21
- RSpec.configuration.include RSpec::Hal::Matchers::Documents, type: 'view'
21
+ RSpec.configuration.include RSpec::Hal::Matchers, type: 'view'
22
22
  ```
23
23
 
24
24
  Once you have the matchers included you can use it like this
@@ -0,0 +1,87 @@
1
+ module RSpec
2
+ module Hal
3
+ module Matchers
4
+
5
+ # Example
6
+ #
7
+ # expect(doc).to have_templated_relation("search")
8
+ # expect(doc).to have_templated_relation("search", matching("{?q}"))
9
+ #
10
+ class TemplatedRelationMatcher
11
+ def initialize(link_rel, expected=nil)
12
+ @link_rel = link_rel
13
+ @expected = expected
14
+ end
15
+
16
+ def matches?(jsonish)
17
+ repr = parse(jsonish)
18
+
19
+ repr.raw_related_hrefs(link_rel){[]}
20
+ .select{|it| it.respond_to? :expand}
21
+ .select{|it| expected === it }
22
+ .any?
23
+ .tap do |outcome|
24
+ @outcome = if outcome
25
+ :pass
26
+ elsif repr.raw_related_hrefs(link_rel){[]}.any?
27
+ :no_templates
28
+ else
29
+ :no_relations
30
+ end
31
+ end
32
+ end
33
+
34
+ def failure_message
35
+ but_clause = if outcome == :no_templates
36
+ "found only non-templated links"
37
+ else
38
+ "found none"
39
+ end
40
+ expected_clause = if expected != NullMatcher && expected.respond_to?(:description)
41
+ expected.description
42
+ elsif expected != NullMatcher
43
+ "matching #{expected}"
44
+ else
45
+ "to exist"
46
+ end
47
+
48
+ "Expected templated `#{link_rel}` link #{expected_clause} but #{but_clause}"
49
+ end
50
+ alias_method :failure_message_for_should, :failure_message
51
+
52
+ def failure_message_when_negated
53
+ "Expected `#{link_rel}` link to be absent or not templated"
54
+ end
55
+ alias_method :failure_message_for_should_not, :failure_message_when_negated
56
+
57
+ def description
58
+ "have templated #{link_rel} link"
59
+ end
60
+
61
+ protected
62
+
63
+ attr_reader :link_rel, :outcome
64
+
65
+ NullMatcher = ->(_url_template){ true }
66
+
67
+ def expected
68
+ @expected ||= NullMatcher
69
+ end
70
+
71
+ def parse(jsonish)
72
+ json = if jsonish.kind_of? String
73
+ jsonish
74
+
75
+ elsif jsonish.respond_to? :to_hal
76
+ jsonish.to_hal
77
+
78
+ else jsonish.respond_to? :to_json
79
+ jsonish.to_json
80
+ end
81
+
82
+ HalClient::Representation.new(parsed_json: MultiJson.load(json))
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -4,6 +4,17 @@ require 'hal-client'
4
4
  module RSpec
5
5
  module Hal
6
6
  module Matchers
7
+ require "rspec/hal/matchers/templated_relation_matcher"
8
+
9
+ # Examples
10
+ #
11
+ # expect(doc).to have_templated_relation("search")
12
+ # expect(doc).to have_templated_relation("search", matching("{?q}"))
13
+ #
14
+ def have_templated_relation(*args)
15
+ TemplatedRelationMatcher.new(*args)
16
+ end
17
+
7
18
  module Document
8
19
  extend RSpec::Matchers::DSL
9
20
 
@@ -147,6 +158,8 @@ module RSpec
147
158
 
148
159
  end
149
160
  end
161
+
162
+ include Document
150
163
  end
151
164
  end
152
165
  end
@@ -1,5 +1,5 @@
1
1
  module RSpec
2
2
  module Hal
3
- VERSION = "1.1.0"
3
+ VERSION = "1.2.0"
4
4
  end
5
5
  end
data/rspec-hal.gemspec CHANGED
@@ -21,6 +21,5 @@ Gem::Specification.new do |spec|
21
21
  spec.add_development_dependency "rake", "~> 10.1"
22
22
 
23
23
  spec.add_runtime_dependency "rspec", ">= 2.0", "< 4.0.0.pre"
24
- spec.add_runtime_dependency "hal-client", "~> 2.2
25
- "
24
+ spec.add_runtime_dependency "hal-client", "~> 2.4"
26
25
  end
@@ -0,0 +1,108 @@
1
+ require_relative "../../../spec_helper"
2
+
3
+ describe RSpec::Hal::Matchers::TemplatedRelationMatcher do
4
+ describe "creation" do
5
+ specify { expect{ described_class.new(a_link_rel) }.not_to raise_error }
6
+ specify { expect{ described_class.new(a_link_rel, any_template_str_matcher) }.not_to raise_error }
7
+ specify { expect{ described_class.new(a_link_rel, /hello/) }.not_to raise_error }
8
+ end
9
+
10
+ subject(:matcher) { described_class.new(a_link_rel) }
11
+
12
+ specify{ expect(matcher.matches?(json_str_w_link)).to be }
13
+ specify{ expect(matcher.matches?(json_str_wo_link)).not_to be }
14
+
15
+ specify{ expect(matcher.matches?(parsed_json_w_link)).to be }
16
+ specify{ expect(matcher.matches?(parsed_json_wo_link)).not_to be }
17
+
18
+ specify{ expect(matcher.matches?(to_halable_w_link)).to be }
19
+ specify{ expect(matcher.matches?(to_halable_wo_link)).not_to be }
20
+
21
+ specify{ expect(matcher.matches?(json_str_w_nontemplate_link)).not_to be }
22
+
23
+ specify { expect(matcher.description).to match "have templated #{a_link_rel} link" }
24
+
25
+ context "failed due to missing relation matcher" do
26
+ before do
27
+ matcher.matches? json_str_wo_link
28
+ end
29
+
30
+ specify { expect(matcher.failure_message)
31
+ .to match "Expected templated `#{a_link_rel}` link to exist but found none" }
32
+ specify { expect(matcher.failure_message_for_should)
33
+ .to match matcher.failure_message }
34
+ end
35
+
36
+ context "failed due to unexpected existing relation" do
37
+ before do
38
+ matcher.matches? json_str_w_link
39
+ end
40
+
41
+ specify { expect(matcher.failure_message_when_negated)
42
+ .to match "Expected `#{a_link_rel}` link to be absent or not templated" }
43
+ specify { expect(matcher.failure_message_for_should_not)
44
+ .to match matcher.failure_message_when_negated }
45
+ end
46
+
47
+ context "failed due existing non-templated relation" do
48
+ before do
49
+ matcher.matches? json_str_w_nontemplate_link
50
+ end
51
+
52
+ specify { expect(matcher.failure_message)
53
+ .to match "Expected templated `#{a_link_rel}` link to exist but found only non-templated links" }
54
+ end
55
+
56
+ context "failed due to sub-matcher failure matcher" do
57
+ subject(:matcher) { described_class.new(a_link_rel, matching("absent")) }
58
+ before do
59
+ matcher.matches? json_str_wo_link
60
+ end
61
+
62
+ specify { expect(matcher.failure_message)
63
+ .to match %(Expected templated `#{a_link_rel}` link matching "absent" but found none) }
64
+ end
65
+
66
+
67
+ # Background
68
+ # ---
69
+
70
+ let(:json_str_w_link) { <<-HAL }
71
+ { "_links": {
72
+ "search": {"href": "http://example.com/s{?q}", "templated": true}
73
+ }}
74
+ HAL
75
+
76
+ let(:json_str_wo_link) { <<-HAL }
77
+ { "_links": {
78
+ }}
79
+ HAL
80
+
81
+ let(:json_str_w_nontemplate_link) { <<-HAL }
82
+ { "_links": {
83
+ "search": {"href": "http://example.com/s{?q}", "templated": false}
84
+ }}
85
+ HAL
86
+
87
+
88
+ let(:parsed_json_w_link) { MultiJson.load json_str_w_link }
89
+ let(:parsed_json_wo_link) { MultiJson.load json_str_wo_link }
90
+
91
+ let(:to_halable_w_link) { halable.new json_str_w_link}
92
+ let(:to_halable_wo_link) { halable.new json_str_wo_link }
93
+
94
+ let(:halable) { Class.new do
95
+ def initialize(json)
96
+ @json = json
97
+ end
98
+
99
+ def to_hal
100
+ return @json
101
+ end
102
+ end }
103
+
104
+ let(:a_link_rel) { "search" }
105
+ let(:any_template_str_matcher) { matching_template_str_matcher }
106
+ let(:matching_template_str_matcher) { match "example.com" }
107
+ let(:nonmatching_template_str_matcher) { match "hello" }
108
+ end
@@ -1,6 +1,27 @@
1
1
  require_relative "../../spec_helper"
2
2
  require "rspec/version"
3
3
 
4
+ describe RSpec::Hal::Matchers do
5
+ subject { Class.new do
6
+ include RSpec::Hal::Matchers
7
+ end.new }
8
+
9
+ specify { expect(subject.be_hal).to be_a_matcher }
10
+ specify { expect(subject.be_hal_collection).to be_a_matcher }
11
+ specify { expect(subject.have_property("name")).to be_a_matcher }
12
+ specify { expect(subject.have_templated_relation("search")).to be_a_matcher }
13
+ specify { expect(subject.have_relation("search")).to be_a_matcher }
14
+
15
+ # Background/Support
16
+ # ---
17
+
18
+ matcher :be_a_matcher do
19
+ match do |actual|
20
+ respond_to?(:matches?) && respond_to?(:failure_message)
21
+ end
22
+ end
23
+ end
24
+
4
25
  describe RSpec::Hal::Matchers::Document do
5
26
  describe "be_hal" do
6
27
  subject(:matcher) { be_hal }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-hal
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-28 00:00:00.000000000 Z
11
+ date: 2014-04-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -64,14 +64,14 @@ dependencies:
64
64
  requirements:
65
65
  - - "~>"
66
66
  - !ruby/object:Gem::Version
67
- version: '2.2'
67
+ version: '2.4'
68
68
  type: :runtime
69
69
  prerelease: false
70
70
  version_requirements: !ruby/object:Gem::Requirement
71
71
  requirements:
72
72
  - - "~>"
73
73
  - !ruby/object:Gem::Version
74
- version: '2.2'
74
+ version: '2.4'
75
75
  description:
76
76
  email:
77
77
  - pezra@barelyenough.org
@@ -88,8 +88,10 @@ files:
88
88
  - lib/rspec-hal.rb
89
89
  - lib/rspec/hal.rb
90
90
  - lib/rspec/hal/matchers.rb
91
+ - lib/rspec/hal/matchers/templated_relation_matcher.rb
91
92
  - lib/rspec/hal/version.rb
92
93
  - rspec-hal.gemspec
94
+ - spec/rspec/hal/matchers/templated_relation_matcher_spec.rb
93
95
  - spec/rspec/hal/matchers_spec.rb
94
96
  - spec/spec_helper.rb
95
97
  homepage: http://github.com/pezra/rspec-hal
@@ -117,5 +119,6 @@ signing_key:
117
119
  specification_version: 4
118
120
  summary: Matchers and helpers for specing HAL documents.
119
121
  test_files:
122
+ - spec/rspec/hal/matchers/templated_relation_matcher_spec.rb
120
123
  - spec/rspec/hal/matchers_spec.rb
121
124
  - spec/spec_helper.rb