acfs 0.33.1.1.b285 → 0.34.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,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ZTc2ZGE4MDNiNjgwNWMzNTBkYzJjNzU1YmEzMjRhOGFkMjE0ZDQ4MQ==
5
- data.tar.gz: !binary |-
6
- NjM5MzYwYTAwMmIzZDVjY2IyZDk5NmVkZDA0MGZiZjg2NjdjNTRlNg==
2
+ SHA1:
3
+ metadata.gz: 79f96815f2139c2a96c6c79a311904567483e720
4
+ data.tar.gz: 0dd9f4379210854cda16b5e6e70868c8201d093d
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- ZmFlMzIwMDg0NGRmZjAwZDM0YmZjYTEzMTc4MzYxYTdiYjc1NTc4M2I1NGMy
10
- ZWVmYzc0YmNkNGM4OGZmMTBiYTFkOGQ5ODc4NDdlMDM0MjU1MTNhMTFkNTFk
11
- NTQxNGRlMDgyMGUwNzcxNmRlMmRkOGRlOGEwYjI5NmVlNWYyZTc=
12
- data.tar.gz: !binary |-
13
- ZTg2ZTRmZDQyOTg0MmI2MDRmNmNiMTRjY2MyYTlhNjdkMzdjNmViYjMwNzk3
14
- MmYxZGI3YjY5YmM2ZTU0NTg5YjAxODZhN2U5MzAyMTc4MjY1YWE5MTljM2I3
15
- OTA0ZWI1MmJiNmU1YzE5MDkxYjM2ODkwMWQ2ZDZlZTJlMjRjMTg=
6
+ metadata.gz: 4d39d8dcb64e34c8f9ed4962c417958f2de27a811a8caf039cec4ebf2c892fda5839fe17ebfef515e75eab8482bb13976a1c512ff938ef460e9cfd3a98b264ab
7
+ data.tar.gz: 0d054784e48f8c4e9fd7973fb3d8abaf333066960353d653fff930933b0ad041f8ae6d724eaccf8ec54ad37d98b727e8914ebf1b61053072c19368c6e27eff29
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.34.0
4
+
5
+ * Add support for will_paginate view helper used with `Acfs::Collection`s
6
+ * Add support for pagination header added by [paginate-responder](https://github.com/jgraichen/paginate-responder)
7
+ * Improve `Resource#new?` detection by using `loaded?` instead of presence of `:id` attribute
8
+
3
9
  ## 0.33.0
4
10
 
5
11
  * Do not raise errors on unknown attributes by default, add :unknown option.
@@ -0,0 +1,398 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4
+ <head>
5
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6
+ <title>
7
+ File: README
8
+
9
+ &mdash; Documentation by YARD 0.8.7.3
10
+
11
+ </title>
12
+
13
+ <link rel="stylesheet" href="css/style.css" type="text/css" charset="utf-8" />
14
+
15
+ <link rel="stylesheet" href="css/common.css" type="text/css" charset="utf-8" />
16
+
17
+ <script type="text/javascript" charset="utf-8">
18
+ hasFrames = window.top.frames.main ? true : false;
19
+ relpath = '';
20
+ framesUrl = "frames.html#!" + escape(window.location.href);
21
+ </script>
22
+
23
+
24
+ <script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
25
+
26
+ <script type="text/javascript" charset="utf-8" src="js/app.js"></script>
27
+
28
+
29
+ </head>
30
+ <body>
31
+ <div id="header">
32
+ <div id="menu">
33
+
34
+ <a href="_index.html">Index</a> &raquo;
35
+ <span class="title">File: README</span>
36
+
37
+
38
+ <div class="noframes"><span class="title">(</span><a href="." target="_top">no frames</a><span class="title">)</span></div>
39
+ </div>
40
+
41
+ <div id="search">
42
+
43
+ <a class="full_list_link" id="class_list_link"
44
+ href="class_list.html">
45
+ Class List
46
+ </a>
47
+
48
+ <a class="full_list_link" id="method_list_link"
49
+ href="method_list.html">
50
+ Method List
51
+ </a>
52
+
53
+ <a class="full_list_link" id="file_list_link"
54
+ href="file_list.html">
55
+ File List
56
+ </a>
57
+
58
+ </div>
59
+ <div class="clear"></div>
60
+ </div>
61
+
62
+ <iframe id="search_frame"></iframe>
63
+
64
+ <div id="content"><div id='filecontents'><h1>Acfs - <em>API client for services</em></h1>
65
+
66
+ <p><a href="http://badge.fury.io/rb/acfs"><img src="https://badge.fury.io/rb/acfs.png" alt="Gem Version"></a>
67
+ <a href="https://travis-ci.org/jgraichen/acfs"><img src="https://travis-ci.org/jgraichen/acfs.png?branch=master" alt="Build Status"></a>
68
+ <a href="https://coveralls.io/r/jgraichen/acfs"><img src="https://coveralls.io/repos/jgraichen/acfs/badge.png?branch=master" alt="Coverage Status"></a>
69
+ <a href="https://codeclimate.com/github/jgraichen/acfs"><img src="https://codeclimate.com/github/jgraichen/acfs.png" alt="Code Climate"></a>
70
+ <a href="https://gemnasium.com/jgraichen/acfs"><img src="https://gemnasium.com/jgraichen/acfs.png" alt="Dependency Status"></a>
71
+ <a href="http://rubydoc.info/github/jgraichen/acfs/master/frames"><img src="http://b.repl.ca/v1/rubydoc-here-blue.png" alt="RubyDoc Documentation"></a></p>
72
+
73
+ <p>Acfs is a library to develop API client libraries for single services within a larger service oriented application.</p>
74
+
75
+ <p>Acfs covers model and service abstraction, convenient query and filter methods, full middleware stack for pre-processing requests and responses on a per service level and automatic request queuing and parallel processing. See Usage for more.</p>
76
+
77
+ <h2>Installation</h2>
78
+
79
+ <p>Add this line to your application&#39;s Gemfile:</p>
80
+
81
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_gem'>gem</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>acfs</span><span class='tstring_end'>&#39;</span></span><span class='comma'>,</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>~&gt; 0.21.0</span><span class='tstring_end'>&#39;</span></span>
82
+ </code></pre>
83
+
84
+ <p><strong>Note:</strong> Acfs is under development. I&#39;ll try to avoid changes to the public API but internal APIs may change quite often.</p>
85
+
86
+ <p>And then execute:</p>
87
+
88
+ <pre class="code ruby"><code class="ruby">&gt; bundle
89
+ </code></pre>
90
+
91
+ <p>Or install it yourself as:</p>
92
+
93
+ <pre class="code ruby"><code class="ruby">&gt; gem install acfs
94
+ </code></pre>
95
+
96
+ <h2>Usage</h2>
97
+
98
+ <p>First you need to define your service(s):</p>
99
+
100
+ <pre class="code ruby"><code class="ruby"><span class='kw'>class</span> <span class='const'>UserService</span> <span class='op'>&lt;</span> <span class='const'>Acfs</span><span class='op'>::</span><span class='const'>Service</span>
101
+ <span class='kw'>self</span><span class='period'>.</span><span class='id identifier rubyid_base_url'>base_url</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>http://users.myapp.org</span><span class='tstring_end'>&#39;</span></span>
102
+
103
+ <span class='comment'># You can configure middlewares you want to use for the service here.
104
+ </span> <span class='comment'># Each service has it own middleware stack.
105
+ </span> <span class='comment'>#
106
+ </span> <span class='id identifier rubyid_use'>use</span> <span class='const'>Acfs</span><span class='op'>::</span><span class='const'>Middleware</span><span class='op'>::</span><span class='const'>JsonDecoder</span>
107
+ <span class='id identifier rubyid_use'>use</span> <span class='const'>Acfs</span><span class='op'>::</span><span class='const'>Middleware</span><span class='op'>::</span><span class='const'>MessagePackDecoder</span>
108
+ <span class='kw'>end</span>
109
+ </code></pre>
110
+
111
+ <p>This specifies where the <code>UserService</code> is located. You can now create some models representing resources served by the <code>UserService</code>.</p>
112
+
113
+ <pre class="code ruby"><code class="ruby"><span class='kw'>class</span> <span class='const'>User</span> <span class='op'>&lt;</span> <span class='const'>Acfs</span><span class='op'>::</span><span class='const'>Resource</span>
114
+ <span class='id identifier rubyid_service'>service</span> <span class='const'>UserService</span> <span class='comment'># Associate `User` model with `UserService`.
115
+ </span>
116
+ <span class='comment'># Define model attributes and types
117
+ </span> <span class='comment'># Types are needed to parse and generate request and response payload.
118
+ </span>
119
+ <span class='id identifier rubyid_attribute'>attribute</span> <span class='symbol'>:id</span><span class='comma'>,</span> <span class='symbol'>:uuid</span> <span class='comment'># Types can be classes or symbols.
120
+ </span> <span class='comment'># Symbols will be used to load a class from `Acfs::Model::Attributes` namespace.
121
+ </span> <span class='comment'># Eg. `:uuid` will load class `Acfs::Model::Attributes::Uuid`.
122
+ </span>
123
+ <span class='id identifier rubyid_attribute'>attribute</span> <span class='symbol'>:name</span><span class='comma'>,</span> <span class='symbol'>:string</span><span class='comma'>,</span> <span class='label'>default:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>Anonymous</span><span class='tstring_end'>&#39;</span></span>
124
+ <span class='id identifier rubyid_attribute'>attribute</span> <span class='symbol'>:age</span><span class='comma'>,</span> <span class='op'>::</span><span class='const'>Acfs</span><span class='op'>::</span><span class='const'>Model</span><span class='op'>::</span><span class='const'>Attributes</span><span class='op'>::</span><span class='const'>Integer</span> <span class='comment'># Or use :integer
125
+ </span>
126
+ <span class='kw'>end</span>
127
+ </code></pre>
128
+
129
+ <p>The service and model classes can be shipped as a gem or git submodule to be included by the frontend application(s).</p>
130
+
131
+ <p>You can use the model there:</p>
132
+
133
+ <pre class="code ruby"><code class="ruby"><span class='ivar'>@user</span> <span class='op'>=</span> <span class='const'>User</span><span class='period'>.</span><span class='id identifier rubyid_find'>find</span> <span class='int'>14</span>
134
+
135
+ <span class='ivar'>@user</span><span class='period'>.</span><span class='id identifier rubyid_loaded?'>loaded?</span> <span class='comment'>#=&gt; false
136
+ </span>
137
+ <span class='const'>Acfs</span><span class='period'>.</span><span class='id identifier rubyid_run'>run</span> <span class='comment'># This will run all queued request as parallel as possible.
138
+ </span> <span class='comment'># For @user the following URL will be requested:
139
+ </span> <span class='comment'># `http://users.myapp.org/users/14`
140
+ </span>
141
+ <span class='ivar'>@model</span><span class='period'>.</span><span class='id identifier rubyid_name'>name</span> <span class='comment'># =&gt; &quot;...&quot;
142
+ </span>
143
+ <span class='ivar'>@users</span> <span class='op'>=</span> <span class='const'>User</span><span class='period'>.</span><span class='id identifier rubyid_all'>all</span>
144
+ <span class='ivar'>@users</span><span class='period'>.</span><span class='id identifier rubyid_loaded?'>loaded?</span> <span class='comment'>#=&gt; false
145
+ </span>
146
+ <span class='const'>Acfs</span><span class='period'>.</span><span class='id identifier rubyid_run'>run</span> <span class='comment'># Will request `http://users.myapp.org/users`
147
+ </span>
148
+ <span class='ivar'>@users</span> <span class='comment'>#=&gt; [&lt;User&gt;, ...]
149
+ </span></code></pre>
150
+
151
+ <p>If you need multiple resources or dependent resources first define a &quot;plan&quot; how they can be loaded:</p>
152
+
153
+ <pre class="code ruby"><code class="ruby"><span class='ivar'>@user</span> <span class='op'>=</span> <span class='const'>User</span><span class='period'>.</span><span class='id identifier rubyid_find'>find</span><span class='lparen'>(</span><span class='int'>5</span><span class='rparen'>)</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_user'>user</span><span class='op'>|</span>
154
+ <span class='comment'># Block will be executed right after user with id 5 is loaded
155
+ </span>
156
+ <span class='comment'># You can load additional resources also from other services
157
+ </span> <span class='comment'># Eg. fetch comments from `CommentSerivce`. The line below will
158
+ </span> <span class='comment'># load comments from `http://comments.myapp.org/comments?user=5`
159
+ </span> <span class='ivar'>@comments</span> <span class='op'>=</span> <span class='const'>Comment</span><span class='period'>.</span><span class='id identifier rubyid_where'>where</span> <span class='label'>user:</span> <span class='id identifier rubyid_user'>user</span><span class='period'>.</span><span class='id identifier rubyid_id'>id</span>
160
+
161
+ <span class='comment'># You can load multiple resources in parallel if you have multiple
162
+ </span> <span class='comment'># ids.
163
+ </span> <span class='ivar'>@friends</span> <span class='op'>=</span> <span class='const'>User</span><span class='period'>.</span><span class='id identifier rubyid_find'>find</span> <span class='int'>1</span><span class='comma'>,</span> <span class='int'>4</span><span class='comma'>,</span> <span class='int'>10</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_friends'>friends</span><span class='op'>|</span>
164
+ <span class='comment'># This block will be executed when all friends are loaded.
165
+ </span> <span class='comment'># [ ... ]
166
+ </span> <span class='kw'>end</span>
167
+ <span class='kw'>end</span>
168
+
169
+ <span class='const'>Acfs</span><span class='period'>.</span><span class='id identifier rubyid_run'>run</span> <span class='comment'># This call will fire all request as parallel as possible.
170
+ </span> <span class='comment'># The sequence above would look similar to:
171
+ </span> <span class='comment'>#
172
+ </span> <span class='comment'># Start Fin
173
+ </span> <span class='comment'># |===================| `Acfs.run`
174
+ </span> <span class='comment'># |====| /users/5
175
+ </span> <span class='comment'># | |==============| /comments?user=5
176
+ </span> <span class='comment'># | |======| /users/1
177
+ </span> <span class='comment'># | |=======| /users/4
178
+ </span> <span class='comment'># | |======| /users/10
179
+ </span>
180
+ <span class='comment'># Now we can access all resources:
181
+ </span>
182
+ <span class='ivar'>@user</span><span class='period'>.</span><span class='id identifier rubyid_name'>name</span> <span class='comment'># =&gt; &quot;John
183
+ </span><span class='ivar'>@comments</span><span class='period'>.</span><span class='id identifier rubyid_size'>size</span> <span class='comment'># =&gt; 25
184
+ </span><span class='ivar'>@friends</span><span class='lbracket'>[</span><span class='int'>0</span><span class='rbracket'>]</span><span class='period'>.</span><span class='id identifier rubyid_name'>name</span> <span class='comment'># =&gt; &quot;Miraculix&quot;
185
+ </span></code></pre>
186
+
187
+ <p>Use <code>.find_by</code> to get first element only. <code>.find_by</code> will call the <code>index</code>-Action and return the first resource. Optionally passed params will be sent as <code>GET</code> parameters and can be used for filtering in the service&#39;s controller.
188
+ ```ruby
189
+ @user = User.find_by age: 24</p>
190
+
191
+ <p>Acfs.run # Will request <code>http://users.myapp.org/users?age=24</code></p>
192
+
193
+ <p>@user # Contains the first user object returned by the index action
194
+ ``<code>
195
+ If no object can be found,</code>.find_by<code>will return</code>nil<code>. The optional callback will then be called with</code>nil<code>as parameter. Use</code>.find_by!<code>to raise an</code>Acfs::ResourceNotFound<code>exception if no object can be found.</code>.find_by!` will only invoke the optional callback if an object was successfully loaded.</p>
196
+
197
+ <p>Acfs has basic update support using <code>PUT</code> requests:</p>
198
+
199
+ <pre class="code ruby"><code class="ruby"><span class='ivar'>@user</span> <span class='op'>=</span> <span class='const'>User</span><span class='period'>.</span><span class='id identifier rubyid_find'>find</span> <span class='int'>5</span>
200
+ <span class='ivar'>@user</span><span class='period'>.</span><span class='id identifier rubyid_name'>name</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>Bob</span><span class='tstring_end'>&quot;</span></span>
201
+
202
+ <span class='ivar'>@user</span><span class='period'>.</span><span class='id identifier rubyid_changed?'>changed?</span> <span class='comment'># =&gt; true
203
+ </span><span class='ivar'>@user</span><span class='period'>.</span><span class='id identifier rubyid_persisted?'>persisted?</span> <span class='comment'># =&gt; false
204
+ </span>
205
+ <span class='ivar'>@user</span><span class='period'>.</span><span class='id identifier rubyid_save'>save</span> <span class='comment'># Or .save!
206
+ </span> <span class='comment'># Will PUT new resource to service synchronously.
207
+ </span>
208
+ <span class='ivar'>@user</span><span class='period'>.</span><span class='id identifier rubyid_changed?'>changed?</span> <span class='comment'># =&gt; false
209
+ </span><span class='ivar'>@user</span><span class='period'>.</span><span class='id identifier rubyid_persisted?'>persisted?</span> <span class='comment'># =&gt; true
210
+ </span></code></pre>
211
+
212
+ <h2>Singleton resources</h2>
213
+
214
+ <p>Singletons can be used in Acfs by creating a new resource which inherits from <code>SingletonResource</code>:</p>
215
+
216
+ <pre class="code ruby"><code class="ruby"><span class='kw'>class</span> <span class='const'>Single</span> <span class='op'>&lt;</span> <span class='const'>Acfs</span><span class='op'>::</span><span class='const'>SingletonResource</span>
217
+ <span class='id identifier rubyid_service'>service</span> <span class='const'>UserService</span> <span class='comment'># Associate `Single` model with `UserService`.
218
+ </span>
219
+ <span class='comment'># Define model attributes and types as with regular resources
220
+ </span>
221
+ <span class='id identifier rubyid_attribute'>attribute</span> <span class='symbol'>:name</span><span class='comma'>,</span> <span class='symbol'>:string</span><span class='comma'>,</span> <span class='label'>default:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>Anonymous</span><span class='tstring_end'>&#39;</span></span>
222
+ <span class='id identifier rubyid_attribute'>attribute</span> <span class='symbol'>:age</span><span class='comma'>,</span> <span class='symbol'>:integer</span>
223
+
224
+ <span class='kw'>end</span>
225
+ </code></pre>
226
+
227
+ <p>The following code explains the routing for singleton resource requests:</p>
228
+
229
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_my_single'>my_single</span> <span class='op'>=</span> <span class='const'>Single</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span>
230
+ <span class='id identifier rubyid_mysingle'>mysingle</span><span class='period'>.</span><span class='id identifier rubyid_save'>save</span> <span class='comment'># sends POST request to /single
231
+ </span>
232
+ <span class='id identifier rubyid_my_single'>my_single</span> <span class='op'>=</span> <span class='const'>Single</span><span class='period'>.</span><span class='id identifier rubyid_find'>find</span>
233
+ <span class='const'>Acfs</span><span class='period'>.</span><span class='id identifier rubyid_run'>run</span> <span class='comment'># sends GET request to /single
234
+ </span>
235
+ <span class='id identifier rubyid_my_single'>my_single</span><span class='period'>.</span><span class='id identifier rubyid_age'>age</span> <span class='op'>=</span> <span class='int'>28</span>
236
+ <span class='id identifier rubyid_my_single'>my_single</span><span class='period'>.</span><span class='id identifier rubyid_save'>save</span> <span class='comment'># sends PUT request to /single
237
+ </span>
238
+ <span class='id identifier rubyid_my_single'>my_single</span><span class='period'>.</span><span class='id identifier rubyid_delete'>delete</span> <span class='comment'># sends DELETE request to /single
239
+ </span></code></pre>
240
+
241
+ <p>You also can pass parameters to the find call, these will sent as GET params to the index action:</p>
242
+
243
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_my_single'>my_single</span> <span class='op'>=</span> <span class='const'>Single</span><span class='period'>.</span><span class='id identifier rubyid_find'>find</span> <span class='label'>name:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>Max</span><span class='tstring_end'>&#39;</span></span>
244
+ <span class='const'>Acfs</span><span class='period'>.</span><span class='id identifier rubyid_run'>run</span> <span class='comment'># sends GET request with param to /single?name=Max
245
+ </span></code></pre>
246
+
247
+ <h2>Resource Inheritance</h2>
248
+
249
+ <p>Acfs provides a resource inheritance similar to ActiveRecord Single Table Inheritance. If a
250
+ <code>type</code> attribute exists and is a valid subclass of your resource they will be converted
251
+ to you subclassed resources:</p>
252
+
253
+ <pre class="code ruby"><code class="ruby">class Computer &lt; Acfs::Resource
254
+ ...
255
+ end
256
+
257
+ class Pc &lt; Computer end
258
+ class Mac &lt; Computer end
259
+ </code></pre>
260
+
261
+ <p>With the following response on <code>GET /computers</code> the collection will contain the appropriate
262
+ subclass resources:</p>
263
+
264
+ <pre class="code json"><code class="json">[
265
+ { &quot;id&quot;: 5, &quot;type&quot;: &quot;Computer&quot;},
266
+ { &quot;id&quot;: 6, &quot;type&quot;: &quot;Mac&quot;},
267
+ { &quot;id&quot;: 8, &quot;type&quot;: &quot;Pc&quot;}
268
+ ]
269
+ </code></pre>
270
+
271
+ <pre class="code ruby"><code class="ruby"><span class='ivar'>@computers</span> <span class='op'>=</span> <span class='const'>Computer</span><span class='period'>.</span><span class='id identifier rubyid_all'>all</span>
272
+
273
+ <span class='const'>Acfs</span><span class='period'>.</span><span class='id identifier rubyid_run'>run</span>
274
+
275
+ <span class='ivar'>@computer</span><span class='lbracket'>[</span><span class='int'>0</span><span class='rbracket'>]</span><span class='period'>.</span><span class='id identifier rubyid_class'>class</span> <span class='comment'># =&gt; Computer
276
+ </span><span class='ivar'>@computer</span><span class='lbracket'>[</span><span class='int'>1</span><span class='rbracket'>]</span><span class='period'>.</span><span class='id identifier rubyid_class'>class</span> <span class='comment'># =&gt; Mac
277
+ </span><span class='ivar'>@computer</span><span class='lbracket'>[</span><span class='int'>2</span><span class='rbracket'>]</span><span class='period'>.</span><span class='id identifier rubyid_class'>class</span> <span class='comment'># =&gt; Pc
278
+ </span></code></pre>
279
+
280
+ <h2>Stubbing</h2>
281
+
282
+ <p>You can stub resources in applications using an Acfs service client:</p>
283
+
284
+ <pre class="code ruby"><code class="ruby"><span class='comment'># spec_helper.rb
285
+ </span>
286
+ <span class='comment'># This will enable stabs before each spec and clear internal state
287
+ </span><span class='comment'># after each spec.
288
+ </span><span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>acfs/rspec</span><span class='tstring_end'>&#39;</span></span>
289
+ </code></pre>
290
+
291
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_before'>before</span> <span class='kw'>do</span>
292
+ <span class='ivar'>@stub</span> <span class='op'>=</span> <span class='const'>Acfs</span><span class='op'>::</span><span class='const'>Stub</span><span class='period'>.</span><span class='id identifier rubyid_resource'>resource</span> <span class='const'>MyUser</span><span class='comma'>,</span> <span class='symbol'>:read</span><span class='comma'>,</span> <span class='label'>with:</span> <span class='lbrace'>{</span> <span class='label'>id:</span> <span class='int'>1</span> <span class='rbrace'>}</span><span class='comma'>,</span> <span class='label'>return:</span> <span class='lbrace'>{</span> <span class='label'>id:</span> <span class='int'>1</span><span class='comma'>,</span> <span class='label'>name:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>John Smith</span><span class='tstring_end'>&#39;</span></span><span class='comma'>,</span> <span class='label'>age:</span> <span class='int'>32</span> <span class='rbrace'>}</span>
293
+ <span class='const'>Acfs</span><span class='op'>::</span><span class='const'>Stub</span><span class='period'>.</span><span class='id identifier rubyid_resource'>resource</span> <span class='const'>MyUser</span><span class='comma'>,</span> <span class='symbol'>:read</span><span class='comma'>,</span> <span class='label'>with:</span> <span class='lbrace'>{</span> <span class='label'>id:</span> <span class='int'>2</span> <span class='rbrace'>}</span><span class='comma'>,</span> <span class='label'>raise:</span> <span class='symbol'>:not_found</span>
294
+ <span class='const'>Acfs</span><span class='op'>::</span><span class='const'>Stub</span><span class='period'>.</span><span class='id identifier rubyid_resource'>resource</span> <span class='const'>Session</span><span class='comma'>,</span> <span class='symbol'>:create</span><span class='comma'>,</span> <span class='label'>with:</span> <span class='lbrace'>{</span> <span class='label'>ident:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>john@exmaple.org</span><span class='tstring_end'>&#39;</span></span><span class='comma'>,</span> <span class='label'>password:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>s3cr3t</span><span class='tstring_end'>&#39;</span></span> <span class='rbrace'>}</span><span class='comma'>,</span> <span class='label'>return:</span> <span class='lbrace'>{</span> <span class='label'>id:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>longhash</span><span class='tstring_end'>&#39;</span></span><span class='comma'>,</span> <span class='label'>user:</span> <span class='int'>1</span> <span class='rbrace'>}</span>
295
+ <span class='const'>Acfs</span><span class='op'>::</span><span class='const'>Stub</span><span class='period'>.</span><span class='id identifier rubyid_resource'>resource</span> <span class='const'>MyUser</span><span class='comma'>,</span> <span class='symbol'>:update</span><span class='comma'>,</span> <span class='label'>with:</span> <span class='id identifier rubyid_lambda'>lambda</span> <span class='lbrace'>{</span> <span class='op'>|</span><span class='id identifier rubyid_op'>op</span><span class='op'>|</span> <span class='id identifier rubyid_op'>op</span><span class='period'>.</span><span class='id identifier rubyid_data'>data</span><span class='period'>.</span><span class='id identifier rubyid_include?'>include?</span> <span class='symbol'>:my_var</span> <span class='rbrace'>}</span><span class='comma'>,</span> <span class='label'>raise:</span> <span class='int'>400</span>
296
+ <span class='kw'>end</span>
297
+
298
+ <span class='id identifier rubyid_it'>it</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>should find user number one</span><span class='tstring_end'>&#39;</span></span> <span class='kw'>do</span>
299
+ <span class='id identifier rubyid_user'>user</span> <span class='op'>=</span> <span class='const'>MyUser</span><span class='period'>.</span><span class='id identifier rubyid_find'>find</span> <span class='int'>1</span>
300
+ <span class='const'>Acfs</span><span class='period'>.</span><span class='id identifier rubyid_run'>run</span>
301
+
302
+ <span class='id identifier rubyid_expect'>expect</span><span class='lparen'>(</span><span class='id identifier rubyid_user'>user</span><span class='period'>.</span><span class='id identifier rubyid_id'>id</span><span class='rparen'>)</span><span class='period'>.</span><span class='id identifier rubyid_to'>to</span> <span class='id identifier rubyid_be'>be</span> <span class='op'>==</span> <span class='int'>1</span>
303
+ <span class='id identifier rubyid_expect'>expect</span><span class='lparen'>(</span><span class='id identifier rubyid_user'>user</span><span class='period'>.</span><span class='id identifier rubyid_name'>name</span><span class='rparen'>)</span><span class='period'>.</span><span class='id identifier rubyid_to'>to</span> <span class='id identifier rubyid_be'>be</span> <span class='op'>==</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>John Smith</span><span class='tstring_end'>&#39;</span></span>
304
+ <span class='id identifier rubyid_expect'>expect</span><span class='lparen'>(</span><span class='id identifier rubyid_user'>user</span><span class='period'>.</span><span class='id identifier rubyid_age'>age</span><span class='rparen'>)</span><span class='period'>.</span><span class='id identifier rubyid_to'>to</span> <span class='id identifier rubyid_be'>be</span> <span class='op'>==</span> <span class='int'>32</span>
305
+
306
+ <span class='id identifier rubyid_expect'>expect</span><span class='lparen'>(</span><span class='ivar'>@stub</span><span class='rparen'>)</span><span class='period'>.</span><span class='id identifier rubyid_to'>to</span> <span class='id identifier rubyid_has_called'>has_called</span>
307
+ <span class='id identifier rubyid_expect'>expect</span><span class='lparen'>(</span><span class='ivar'>@stub</span><span class='rparen'>)</span><span class='period'>.</span><span class='id identifier rubyid_to_not'>to_not</span> <span class='id identifier rubyid_have_called'>have_called</span> <span class='int'>5</span><span class='period'>.</span><span class='id identifier rubyid_times'>times</span>
308
+ <span class='kw'>end</span>
309
+
310
+ <span class='id identifier rubyid_it'>it</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>should not find user number two</span><span class='tstring_end'>&#39;</span></span> <span class='kw'>do</span>
311
+ <span class='const'>MyUser</span><span class='period'>.</span><span class='id identifier rubyid_find'>find</span> <span class='int'>3</span>
312
+
313
+ <span class='id identifier rubyid_expect'>expect</span> <span class='lbrace'>{</span> <span class='const'>Acfs</span><span class='period'>.</span><span class='id identifier rubyid_run'>run</span> <span class='rbrace'>}</span><span class='period'>.</span><span class='id identifier rubyid_to'>to</span> <span class='id identifier rubyid_raise_error'>raise_error</span><span class='lparen'>(</span><span class='const'>Acfs</span><span class='op'>::</span><span class='const'>ResourceNotFound</span><span class='rparen'>)</span>
314
+ <span class='kw'>end</span>
315
+
316
+ <span class='id identifier rubyid_it'>it</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>should allow stub resource creation</span><span class='tstring_end'>&#39;</span></span> <span class='kw'>do</span>
317
+ <span class='id identifier rubyid_session'>session</span> <span class='op'>=</span> <span class='const'>Session</span><span class='period'>.</span><span class='id identifier rubyid_create!'>create!</span> <span class='label'>ident:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>john@exmaple.org</span><span class='tstring_end'>&#39;</span></span><span class='comma'>,</span> <span class='label'>password:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>s3cr3t</span><span class='tstring_end'>&#39;</span></span>
318
+
319
+ <span class='id identifier rubyid_expect'>expect</span><span class='lparen'>(</span><span class='id identifier rubyid_session'>session</span><span class='period'>.</span><span class='id identifier rubyid_id'>id</span><span class='rparen'>)</span><span class='period'>.</span><span class='id identifier rubyid_to'>to</span> <span class='id identifier rubyid_be'>be</span> <span class='op'>==</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>longhash</span><span class='tstring_end'>&#39;</span></span>
320
+ <span class='id identifier rubyid_expect'>expect</span><span class='lparen'>(</span><span class='id identifier rubyid_session'>session</span><span class='period'>.</span><span class='id identifier rubyid_user'>user</span><span class='rparen'>)</span><span class='period'>.</span><span class='id identifier rubyid_to'>to</span> <span class='id identifier rubyid_be'>be</span> <span class='op'>==</span> <span class='int'>1</span>
321
+ <span class='kw'>end</span>
322
+ </code></pre>
323
+
324
+ <p>By default Acfs raises an error when a non stubbed resource should be requested. You can switch of the behavior:</p>
325
+
326
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_before'>before</span> <span class='kw'>do</span>
327
+ <span class='const'>Acfs</span><span class='op'>::</span><span class='const'>Stub</span><span class='period'>.</span><span class='id identifier rubyid_allow_requests'>allow_requests</span> <span class='op'>=</span> <span class='kw'>true</span>
328
+ <span class='kw'>end</span>
329
+
330
+ <span class='id identifier rubyid_it'>it</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>should find user number one</span><span class='tstring_end'>&#39;</span></span> <span class='kw'>do</span>
331
+ <span class='id identifier rubyid_user'>user</span> <span class='op'>=</span> <span class='const'>MyUser</span><span class='period'>.</span><span class='id identifier rubyid_find'>find</span> <span class='int'>1</span>
332
+ <span class='const'>Acfs</span><span class='period'>.</span><span class='id identifier rubyid_run'>run</span> <span class='comment'># Would have raised Acfs::RealRequestNotAllowedError
333
+ </span> <span class='comment'># Will run real request to user service instead.
334
+ </span><span class='kw'>end</span>
335
+ </code></pre>
336
+
337
+ <h2>Roadmap</h2>
338
+
339
+ <ul>
340
+ <li>Update
341
+
342
+ <ul>
343
+ <li>Better new? detection eg. storing ETag from request resources.</li>
344
+ <li>Use PATCH for with only changed attributes and <code>If-Unmodifed-Since</code>
345
+ and <code>If-Match</code> header fields if resource was surly loaded from service
346
+ and not created with an id (e.g <code>User.new id: 5, name: &quot;john&quot;</code>).</li>
347
+ <li>Conflict detection (ETag / If-Unmodified-Since)</li>
348
+ </ul></li>
349
+ <li>High level features
350
+
351
+ <ul>
352
+ <li>Support for custom mime types on client and server side. (<code>application/vnd.myservice.user.v2+msgpack</code>)</li>
353
+ <li>Server side components
354
+
355
+ <ul>
356
+ <li>Reusing model definitions for generating responses?</li>
357
+ <li>Rails responders providing REST operations with integrated ETag,
358
+ Modified Headers, conflict detection, ...</li>
359
+ </ul></li>
360
+ <li>Pagination? Filtering? (If service API provides such features.)</li>
361
+ </ul></li>
362
+ <li>Documentation</li>
363
+ </ul>
364
+
365
+ <h2>Contributing</h2>
366
+
367
+ <ol>
368
+ <li>Fork it</li>
369
+ <li>Create your feature branch (<code>git checkout -b my-new-feature</code>)</li>
370
+ <li>Add specs for your feature</li>
371
+ <li>Implement your feature</li>
372
+ <li>Commit your changes (<code>git commit -am &#39;Add some feature&#39;</code>)</li>
373
+ <li>Push to the branch (<code>git push origin my-new-feature</code>)</li>
374
+ <li>Create new Pull Request</li>
375
+ </ol>
376
+
377
+ <h2>Contributors</h2>
378
+
379
+ <ul>
380
+ <li><a href="https://github.com/nicolas-fricke">Nicolas Fricke</a></li>
381
+ <li><a href="https://github.com/tino-junge">Tino Junge</a></li>
382
+ </ul>
383
+
384
+ <h2>License</h2>
385
+
386
+ <p>MIT License</p>
387
+
388
+ <p>Copyright (c) 2013 Jan Graichen. MIT license, see LICENSE for more details.</p>
389
+ </div></div>
390
+
391
+ <div id="footer">
392
+ Generated on Fri Mar 7 20:03:40 2014 by
393
+ <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
394
+ 0.8.7.3 (ruby-2.1.1).
395
+ </div>
396
+
397
+ </body>
398
+ </html>
@@ -39,7 +39,7 @@ module Acfs
39
39
  # @return [Boolean] True if resource is newly created, false otherwise.
40
40
  #
41
41
  def new?
42
- read_attribute(:id).nil?
42
+ !loaded?
43
43
  end
44
44
  alias :new_record? :new?
45
45
 
@@ -0,0 +1,37 @@
1
+ module Acfs::ParameterDecoder
2
+
3
+ module Functions
4
+ def self.deep_decode(hash)
5
+ return hash unless hash.is_a? Hash
6
+
7
+ hash.each_pair do |key, value|
8
+ if value.is_a? Hash
9
+ deep_decode(value)
10
+ hash[key] = decode_typhoeus_array(value)
11
+ end
12
+ end
13
+ end
14
+
15
+ def self.decode_typhoeus_array(hash)
16
+ if typhoeus_encoded? hash
17
+ hash.inject([]) do |memo, (key, val)|
18
+ memo[Integer(key)] = val
19
+ memo
20
+ end
21
+ else
22
+ hash
23
+ end
24
+ end
25
+
26
+ def self.typhoeus_encoded?(hash)
27
+ return false if hash.empty?
28
+ self.keys.sort == (0...hash.keys.size).map { |i| i.to_s }
29
+ end
30
+ end
31
+
32
+ def self.included(base)
33
+ base.send :before_filter do
34
+ Functions.deep_decode params
35
+ end
36
+ end
37
+ end
@@ -1,8 +1,8 @@
1
1
  module Acfs
2
2
  module VERSION
3
3
  MAJOR = 0
4
- MINOR = 33
5
- PATCH = 1
4
+ MINOR = 34
5
+ PATCH = 0
6
6
  STAGE = nil
7
7
 
8
8
  STRING = [MAJOR, MINOR, PATCH, STAGE].reject(&:nil?).join('.')
@@ -8,10 +8,10 @@ describe Acfs::Model::QueryMethods do
8
8
  context 'with successful response' do
9
9
  before do
10
10
  stub_request(:get, 'http://users.example.org/users/1').to_return response({id: 1, name: 'Anon', age: 12, born_at: 'Berlin'})
11
- stub_request(:get, 'http://users.example.org/users/2').to_return response({id: 2, type: 'Customer', name: 'Clare Customer', age: 24 })
11
+ stub_request(:get, 'http://users.example.org/users/2').to_return response({id: 2, type: 'Customer', name: 'Clare Customer', age: 24})
12
12
  end
13
13
 
14
- let(:action) { lambda{|cb=nil| model.find 1, &cb } }
14
+ let(:action) { lambda { |cb=nil| model.find 1, &cb } }
15
15
  it_behaves_like 'a query method with multi-callback support'
16
16
 
17
17
  it 'should load a single remote resource' do
@@ -19,7 +19,7 @@ describe Acfs::Model::QueryMethods do
19
19
  Acfs.run
20
20
 
21
21
  expect(user.attributes).to eq(
22
- {id: 1, name: 'Anon', age: 12, born_at: 'Berlin'}.stringify_keys)
22
+ {id: 1, name: 'Anon', age: 12, born_at: 'Berlin'}.stringify_keys)
23
23
  end
24
24
 
25
25
  context 'with resource type inheritance' do
@@ -40,7 +40,7 @@ describe Acfs::Model::QueryMethods do
40
40
 
41
41
  context 'with 404 response' do
42
42
  before do
43
- stub_request(:get, 'http://users.example.org/users/1').to_return response({ error: 'not found' }, status: 404)
43
+ stub_request(:get, 'http://users.example.org/users/1').to_return response({error: 'not found'}, status: 404)
44
44
  end
45
45
 
46
46
  it 'should raise a NotFound error' do
@@ -69,10 +69,10 @@ describe Acfs::Model::QueryMethods do
69
69
 
70
70
  context 'with multiple ids' do
71
71
  before do
72
- stub_request(:get, 'http://users.example.org/users/1').to_return response({ id: 1, name: 'Anon', age: 12 })
73
- stub_request(:get, 'http://users.example.org/users/2').to_return response({ id: 2, name: 'Johnny', age: 42 })
74
- stub_request(:get, 'http://users.example.org/users/3').to_return response({ id: 3, type: 'Customer', name: 'Anon', age: 12 })
75
- stub_request(:get, 'http://users.example.org/users/4').to_return response({ id: 4, name: 'Johnny', age: 42 })
72
+ stub_request(:get, 'http://users.example.org/users/1').to_return response({id: 1, name: 'Anon', age: 12})
73
+ stub_request(:get, 'http://users.example.org/users/2').to_return response({id: 2, name: 'Johnny', age: 42})
74
+ stub_request(:get, 'http://users.example.org/users/3').to_return response({id: 3, type: 'Customer', name: 'Anon', age: 12})
75
+ stub_request(:get, 'http://users.example.org/users/4').to_return response({id: 4, name: 'Johnny', age: 42})
76
76
  end
77
77
 
78
78
  context 'with successful response' do
@@ -81,12 +81,12 @@ describe Acfs::Model::QueryMethods do
81
81
  Acfs.run
82
82
 
83
83
  expect(users.size).to be == 2
84
- expect(users[0].attributes).to be == { id: 1, name: 'Anon', age: 12 }.stringify_keys
85
- expect(users[1].attributes).to be == { id: 2, name: 'Johnny', age: 42 }.stringify_keys
84
+ expect(users[0].attributes).to be == {id: 1, name: 'Anon', age: 12}.stringify_keys
85
+ expect(users[1].attributes).to be == {id: 2, name: 'Johnny', age: 42}.stringify_keys
86
86
  end
87
87
 
88
88
  it 'should invoke callback after all models are loaded' do
89
- proc = Proc.new { }
89
+ proc = Proc.new {}
90
90
  expect(proc).to receive(:call) do |users|
91
91
  expect(users).to be === @users
92
92
  expect(users.size).to be == 2
@@ -98,8 +98,8 @@ describe Acfs::Model::QueryMethods do
98
98
  end
99
99
 
100
100
  it 'should invoke multiple callback after all models are loaded' do
101
- proc1 = Proc.new { }
102
- proc2 = Proc.new { }
101
+ proc1 = Proc.new {}
102
+ proc2 = Proc.new {}
103
103
  expect(proc1).to receive(:call) do |users|
104
104
  expect(users).to be === @users
105
105
  expect(users.size).to be == 2
@@ -127,7 +127,7 @@ describe Acfs::Model::QueryMethods do
127
127
 
128
128
  context 'with one 404 response' do
129
129
  before do
130
- stub_request(:get, 'http://users.example.org/users/1').to_return response({ error: 'not found' }, status: 404)
130
+ stub_request(:get, 'http://users.example.org/users/1').to_return response({error: 'not found'}, status: 404)
131
131
  end
132
132
 
133
133
  it 'should raise resource not found error' do
@@ -144,12 +144,12 @@ describe Acfs::Model::QueryMethods do
144
144
  let(:pc) { PC }
145
145
  let(:mac) { Mac }
146
146
  before do
147
- stub_request(:get, 'http://computers.example.org/computers').to_return response([{ id: 1, type: 'PC' }, { id: 2, type: 'Computer' }, { id: 3, type: 'Mac' }])
147
+ stub_request(:get, 'http://computers.example.org/computers').to_return response([{id: 1, type: 'PC'}, {id: 2, type: 'Computer'}, {id: 3, type: 'Mac'}])
148
148
  end
149
149
 
150
150
  it 'should invoke multiple callback after all models are loaded' do
151
- proc1 = Proc.new { }
152
- proc2 = Proc.new { }
151
+ proc1 = Proc.new {}
152
+ proc2 = Proc.new {}
153
153
  expect(proc1).to receive(:call) do |computers|
154
154
  expect(computers).to be === @computers
155
155
  expect(computers.size).to be == 3
@@ -191,21 +191,21 @@ describe Acfs::Model::QueryMethods do
191
191
 
192
192
  context 'with another resource as type instead' do
193
193
  before do
194
- stub_request(:get, 'http://computers.example.org/computers').to_return response([{ id: 1, type: 'MyUser' }, { id: 2, type: 'Computer' }, { id: 3, type: 'Mac' }])
194
+ stub_request(:get, 'http://computers.example.org/computers').to_return response([{id: 1, type: 'MyUser'}, {id: 2, type: 'Computer'}, {id: 3, type: 'Mac'}])
195
195
  end
196
196
  it_behaves_like 'with invalid type'
197
197
  end
198
198
 
199
199
  context 'with a random string as type instead' do
200
200
  before do
201
- stub_request(:get, 'http://computers.example.org/computers').to_return response([{ id: 1, type: 'PC' }, { id: 2, type: 'noValidType' }, { id: 3, type: 'Mac' }])
201
+ stub_request(:get, 'http://computers.example.org/computers').to_return response([{id: 1, type: 'PC'}, {id: 2, type: 'noValidType'}, {id: 3, type: 'Mac'}])
202
202
  end
203
203
  it_behaves_like 'with invalid type'
204
204
  end
205
205
 
206
206
  context 'with a non-string as type instead' do
207
207
  before do
208
- stub_request(:get, 'http://computers.example.org/computers').to_return response([{ id: 1, type: 'PC' }, { id: 2, type: 'Computer' }, { id: 3, type: 42 }])
208
+ stub_request(:get, 'http://computers.example.org/computers').to_return response([{id: 1, type: 'PC'}, {id: 2, type: 'Computer'}, {id: 3, type: 42}])
209
209
  end
210
210
  it_behaves_like 'with invalid type'
211
211
  end
@@ -239,7 +239,7 @@ describe Acfs::Model::QueryMethods do
239
239
  before { stub_request(:get, 'http://users.example.org/users?age=24').to_return response([{id: 1, name: 'Mike', age: 24}, {id: 4, type: 'Maria', age: 24}, {id: 7, type: 'James', age: 24}]) }
240
240
 
241
241
  it 'should invoke callback after model is loaded' do
242
- proc = Proc.new { }
242
+ proc = Proc.new {}
243
243
 
244
244
  expect(proc).to receive(:call) do |user|
245
245
  expect(user).to eql @user.__getobj__
@@ -252,8 +252,8 @@ describe Acfs::Model::QueryMethods do
252
252
  end
253
253
 
254
254
  it 'should invoke multiple callbacks after model is loaded' do
255
- proc1 = Proc.new { }
256
- proc2 = Proc.new { }
255
+ proc1 = Proc.new {}
256
+ proc2 = Proc.new {}
257
257
 
258
258
  expect(proc1).to receive(:call) do |user|
259
259
  expect(user).to eql @user.__getobj__
@@ -282,7 +282,7 @@ describe Acfs::Model::QueryMethods do
282
282
  let(:model) { Single }
283
283
 
284
284
  it '.find_by should not be defined' do
285
- expect{ model.find_by }.to raise_error NoMethodError
285
+ expect { model.find_by }.to raise_error NoMethodError
286
286
  end
287
287
  end
288
288
  end
@@ -292,7 +292,7 @@ describe Acfs::Model::QueryMethods do
292
292
  it_behaves_like 'find_by'
293
293
 
294
294
  context 'standard resource' do
295
- let(:model){ MyUser }
295
+ let(:model) { MyUser }
296
296
  let!(:user) { model.send described_method, age: 24 }
297
297
  subject { Acfs.run; user }
298
298
 
@@ -302,7 +302,7 @@ describe Acfs::Model::QueryMethods do
302
302
  it { should be_nil }
303
303
 
304
304
  it 'should invoke callback after model is loaded' do
305
- proc = Proc.new { }
305
+ proc = Proc.new {}
306
306
 
307
307
  expect(proc).to receive(:call) do |user|
308
308
  expect(user).to eql @user.__getobj__
@@ -314,8 +314,8 @@ describe Acfs::Model::QueryMethods do
314
314
  end
315
315
 
316
316
  it 'should invoke multiple callbacks after model is loaded' do
317
- proc1 = Proc.new { }
318
- proc2 = Proc.new { }
317
+ proc1 = Proc.new {}
318
+ proc2 = Proc.new {}
319
319
 
320
320
  expect(proc1).to receive(:call) do |user|
321
321
  expect(user).to eql @user.__getobj__
@@ -339,7 +339,7 @@ describe Acfs::Model::QueryMethods do
339
339
  it_behaves_like 'find_by'
340
340
 
341
341
  context 'standard resource' do
342
- let(:model){ MyUser }
342
+ let(:model) { MyUser }
343
343
  let!(:user) { model.send described_method, age: 24 }
344
344
  subject { Acfs.run; user }
345
345
 
@@ -348,16 +348,16 @@ describe Acfs::Model::QueryMethods do
348
348
 
349
349
  it 'should raise an ResourceNotFound error' do
350
350
  model.find_by! age: 24
351
- expect{ Acfs.run }.to raise_error Acfs::ResourceNotFound
351
+ expect { Acfs.run }.to raise_error Acfs::ResourceNotFound
352
352
  end
353
353
 
354
354
  it 'should not invoke callback after model could not be loaded' do
355
- proc = Proc.new { }
355
+ proc = Proc.new {}
356
356
 
357
357
  expect(proc).not_to receive(:call)
358
358
 
359
359
  model.find_by! age: 24, &proc
360
- expect{ Acfs.run }.to raise_error
360
+ expect { Acfs.run }.to raise_error
361
361
  end
362
362
  end
363
363
  end
@@ -1,6 +1,4 @@
1
1
  require 'rspec'
2
- require 'rspec/its'
3
- require 'rspec/collection_matchers'
4
2
  require 'webmock/rspec'
5
3
 
6
4
  if ENV['CI'] || (defined?(:RUBY_ENGINE) && RUBY_ENGINE != 'rbx')
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acfs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.33.1.1.b285
4
+ version: 0.34.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Graichen
@@ -14,98 +14,98 @@ dependencies:
14
14
  name: activesupport
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ! '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '3.1'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ! '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '3.1'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activemodel
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ! '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '3.1'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ! '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '3.1'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: actionpack
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ! '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '3.1'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ! '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.1'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: multi_json
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ! '>='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ! '>='
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: typhoeus
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ! '>='
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: 0.6.5
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ! '>='
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: 0.6.5
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rack
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ! '>='
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ! '>='
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: bundler
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - ~>
101
+ - - "~>"
102
102
  - !ruby/object:Gem::Version
103
103
  version: '1.3'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - ~>
108
+ - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '1.3'
111
111
  description: API Client For Services
@@ -119,6 +119,7 @@ files:
119
119
  - LICENSE
120
120
  - README.md
121
121
  - acfs.gemspec
122
+ - doc/file.README.html
122
123
  - lib/acfs.rb
123
124
  - lib/acfs/adapter/base.rb
124
125
  - lib/acfs/adapter/typhoeus.rb
@@ -156,6 +157,7 @@ files:
156
157
  - lib/acfs/model/service.rb
157
158
  - lib/acfs/model/validation.rb
158
159
  - lib/acfs/operation.rb
160
+ - lib/acfs/parameter_decoder.rb
159
161
  - lib/acfs/request.rb
160
162
  - lib/acfs/request/callbacks.rb
161
163
  - lib/acfs/resource.rb
@@ -212,14 +214,14 @@ require_paths:
212
214
  - lib
213
215
  required_ruby_version: !ruby/object:Gem::Requirement
214
216
  requirements:
215
- - - ! '>='
217
+ - - ">="
216
218
  - !ruby/object:Gem::Version
217
219
  version: '0'
218
220
  required_rubygems_version: !ruby/object:Gem::Requirement
219
221
  requirements:
220
- - - ! '>'
222
+ - - ">="
221
223
  - !ruby/object:Gem::Version
222
- version: 1.3.1
224
+ version: '0'
223
225
  requirements: []
224
226
  rubyforge_project:
225
227
  rubygems_version: 2.2.2
@@ -258,3 +260,4 @@ test_files:
258
260
  - spec/support/response.rb
259
261
  - spec/support/service.rb
260
262
  - spec/support/shared/find_callbacks.rb
263
+ has_rdoc: