contractinator 0.1.1 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 82f22e805bf00d746ae493dcc5883c3b45ebca24
4
- data.tar.gz: 26d67acb7d34eb94747b4c29e61540d8c40b4a64
3
+ metadata.gz: 69be59e1842cf4087e1ee9456c6d141d9852ef0d
4
+ data.tar.gz: 468e293c29177cdec380a0263726eff3b8f2b8a0
5
5
  SHA512:
6
- metadata.gz: dd252cb859d7fd464cce2beac517242a8e3cdb0a9218bb0fece97d2062e4812005483718d75e58f90f54f3e03bfd96b01151a8599e6c6e949076e1e7a4f3af1a
7
- data.tar.gz: 829da3795a63aa5c3417b701bd94c67f20ea2e43b216d2feeff7ad51b6a3c212c41ab97c18cdca1ca0fb8ce39ec1d5ffbfb8e9046d88aa646033d0919f6ffbb2
6
+ metadata.gz: 3666016479f67cf80c348b634ce2bf35ae44c1a2a6008594d204fc260ad7dd524b685a950c970584cef5fb2d542564c5277570e5d97a2bed0ab56eeae6e3e135
7
+ data.tar.gz: 1dfa070f7b1799d6cf9fd24d8be034751a4d8b16f8206db4f7ac2630108a615d4cd463675b458c000b77c497fd835c77ad12ab18c84135d37f1da2170db25136
data/README.md CHANGED
@@ -1,9 +1,5 @@
1
1
  # Contractinator
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/contractinator`. To experiment with that code, run `bin/console` for an interactive prompt.
4
-
5
- TODO: Delete this and the text above, and describe your gem
6
-
7
3
  ## Installation
8
4
 
9
5
  Add this line to your application's Gemfile:
@@ -19,10 +15,100 @@ And then execute:
19
15
  Or install it yourself as:
20
16
 
21
17
  $ gem install contractinator
18
+
19
+ Then inform RSpec that you'd like to use contractinator by adding something like the following to your spec_helper.rb
20
+
21
+ ```
22
+ require 'contractinator'
23
+
24
+ RSpec.configure do |config|
25
+ config.include Contractinator::ContractHelpers
26
+
27
+ # By default contractinator extends rspec's test doubles.
28
+ # You don't have to use rspec's doubles TODO: explain how
29
+ # to use other mocks.
30
+ config.mock_with :rspec
31
+
32
+ # After the suite is done, warn the user about all the
33
+ # unbalanced contracts.
34
+ config.after(:suite) do
35
+ puts
36
+ puts Contractinator::Contract.messages
37
+ puts
38
+ puts "#{Contractinator::Contract.fulfilled_set.count} fulfilled contracts"
39
+ end
40
+ end
41
+ ```
22
42
 
23
43
  ## Usage
24
44
 
25
- TODO: Write usage instructions here
45
+ ### Creating a Contract
46
+ There are several ways to document a provider's behavior. The easiest is to use the `stipulate` and `agree` matchers.
47
+
48
+ In the spec for a consumer, for example a rails controller, you might have
49
+
50
+ ```
51
+ it 'assigns a new entry' do
52
+ stipulate(Entry).must receive(:new).and_return(entry)
53
+ get :new
54
+ expect(response).to be_success
55
+ expect(assigns[:entry]).to eq(entry)
56
+ end
57
+ ```
58
+
59
+ This sets the expectation that Entry.new will be called, and stubs it out to return `entry`. Now you should get a warning in your rspec output that looks like this:
60
+
61
+ ```
62
+ unfulfilled contract 'Entry.new -> entry'
63
+ at spec/controllers/entries_controller_spec.rb:45:in `block (3 levels) in <top (required)>'
64
+ ```
65
+
66
+ The next step is to make sure that contract is fulfilled by something. So we'll switch over to the model spec
67
+
68
+ ```
69
+ describe '.new' do
70
+ it { agree(Entry, :new).will be_a(Entry) }
71
+ end
72
+ ```
73
+
74
+ This calls new on Entry and asserts that it is_a Entry, and fulfills a contract of the form `Entry.new -> entry`. Since this matches the one from above, your spec output won't show the unmatched on anymore, but will increment the fulfilled contracts message.
75
+
76
+ ### Less straight-forward contracts
77
+ Not every contract in an application is so easy to specify. For example, a view spec which assigns a local variable has an agreement with a controller to assign that variable. Some other matchers available:
78
+
79
+ ```
80
+ assign_contract('entries#new', :entry, entry)
81
+ flash_contract('entries#create', :notice, 'Great Success!') if flash_enabled
82
+ ```
83
+
84
+ In these two cases, the method both does the side effect (assigning a variable for a view spec or setting a flash message), and also creates a matching contract. There isn't a corresponding fulfillment matcher for anything else yet, so you have to fulfill them manually. I do this like so, in my controller spec:
85
+
86
+ ```
87
+ describe 'get :new' do
88
+ it { fulfills 'entries#new assign @entry' }
89
+ it do
90
+ # actual test which reflects this fulfillment
91
+ end
92
+ end
93
+ ```
94
+
95
+ ### Free-form contracts
96
+ Sometimes I think of things that need a contract that I have no matchers for, and all I really want is a smart comment. I'm using this for a routing contract relationship now. In that case, you can do this:
97
+
98
+ ```
99
+ # this is a contract that might be created
100
+ # by a link in a view spec for example
101
+ Contractinator::Contract.require("get / routes")
102
+
103
+ ```
104
+
105
+ And fulfill it with
106
+
107
+ ```
108
+ it { fulfills('get / routes') }
109
+ ```
110
+
111
+ All that matters for the contract to be fulfilled is that the string matches, so in this case contractinator is almost acting as merely a smart comment.
26
112
 
27
113
  ## Development
28
114
 
@@ -8,6 +8,10 @@ module Contractinator
8
8
  ContractAdapter.new(dbl, self)
9
9
  end
10
10
 
11
+ def contract(string)
12
+ Contractinator::Contract.require(string)
13
+ end
14
+
11
15
  def inject_contract(controller, name, dbl)
12
16
  dbl_name = fmt_dbl(dbl).to_s.classify
13
17
  Contractinator::Contract.require(
@@ -1,3 +1,3 @@
1
1
  module Contractinator
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.3"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: contractinator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ehren Murdick