siren_client 0.1.1 → 0.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: 2235dbb7d6503b6712f4f2db4c6830fd56bcac2f
4
- data.tar.gz: b48315c74552103bacb992ec1d47ad75dcdb2eb5
3
+ metadata.gz: f38d3c4581d5764d0798e4c4d3908f7404ca7cdb
4
+ data.tar.gz: 3e71628070a1391ef839335602ef778b1d1d7d94
5
5
  SHA512:
6
- metadata.gz: 544030c9e76a6cb6ac88c920c6e651b116838ec62d2ef08856fee5883d6fbffca740a2c27c95261f914eb2364c1fbef664332890b50e61ea8fbb6dad80b3f6f8
7
- data.tar.gz: 74d4ab57514bfada4a2b8c7b02978588abfcb0edbdf5bd2cd918180f44b767fe7f9cd03d4bebc4d6c20af25afd05e2c5379f14a711c83ab4a39a755c47773e4e
6
+ metadata.gz: 7edd967f314c6d036d7cfdef8889fd9953b1e0b19523343d71d0e5f1586d7f9438f44e01051aabb4e53e4d5489e6d01aca5f55196494bf89fdb4ecf5897065ec
7
+ data.tar.gz: 043795907a4f6166549f42f9776447a1566d8e7f47f1f7995e47826f500e467eee0e904fd50c7a4209241b2022bcbe353c0436cc78c5e00d658dc35c04d3d579
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.3"
4
+ - "2.0.0"
5
+ - "2.1.0"
6
+ - "2.2.0"
7
+ - jruby-19mode
8
+ script: bundle exec rspec
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # SirenClient
1
+ # SirenClient [![Build Status](https://travis-ci.org/cha55son/siren_client.svg)](https://travis-ci.org/cha55son/siren_client)
2
2
 
3
3
  A simple client for traversing Siren APIs. Not sure what Siren is? View the spec here: https://github.com/kevinswiber/siren.
4
4
 
@@ -46,6 +46,18 @@ root.entities[x] # This is an array
46
46
  root.each do |entity|
47
47
  # do something
48
48
  end
49
+ # With full enumerable support entities work similarly to arrays
50
+ root.map { |entity| ... }
51
+ root.select { |entity| ... }
52
+ root.find { |entity| ... }
53
+ # You can view all the enumerable methods here: http://ruby-doc.org/core-2.0.0/Enumerable.html
54
+ ```
55
+
56
+ Entities also provide the method `.search` for searching across sub-entities' classes, rels, and hrefs (sub-links only).
57
+
58
+ ```ruby
59
+ root.search("messages") # => Array<SirenClient::Entity>
60
+ root.search(/(messages|concepts)/) # => Array<SirenClient::Entity>
49
61
  ```
50
62
 
51
63
  #### Entity sub-links
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'byebug'
3
+ require 'byebug' if RUBY_VERSION > '2'
4
4
  require 'siren_cli'
5
5
 
6
6
  SirenCLI::Shell.new
@@ -1,6 +1,7 @@
1
1
  module SirenClient
2
2
  class Action
3
- attr_reader :payload, :name, :classes, :method, :href, :title, :type, :fields, :config
3
+ attr_accessor :href
4
+ attr_reader :payload, :name, :classes, :method, :title, :type, :fields, :config
4
5
 
5
6
  def initialize(data, config={})
6
7
  if data.class != Hash
@@ -1,7 +1,9 @@
1
1
  module SirenClient
2
2
  class Entity
3
+ include Enumerable
4
+ attr_accessor :href
3
5
  attr_reader :payload, :classes, :properties, :entities, :rels,
4
- :links, :actions, :title, :type, :config, :href
6
+ :links, :actions, :title, :type, :config
5
7
 
6
8
 
7
9
  def initialize(data, config={})
@@ -36,6 +38,23 @@ module SirenClient
36
38
  @entities.each(&block) rescue nil
37
39
  end
38
40
 
41
+ def search(criteria)
42
+ return false unless criteria
43
+ if criteria.is_a? String
44
+ return entities.select do |ent|
45
+ true if ent.classes.include?(criteria) ||
46
+ ent.rels.include?(criteria) ||
47
+ ent.href == criteria
48
+ end
49
+ elsif criteria.is_a? Regexp
50
+ return entities.select do |ent|
51
+ true if ent.classes.any? { |klass| criteria.match(klass) } ||
52
+ ent.rels.any? { |rel| criteria.match(rel) } ||
53
+ criteria.match(ent.href)
54
+ end
55
+ end
56
+ end
57
+
39
58
  ### Entity sub-links only
40
59
  def go
41
60
  return if self.href.empty?
@@ -51,15 +70,16 @@ module SirenClient
51
70
  end
52
71
  # Does it match an entity sub-link's class?
53
72
  @entities.each do |ent|
54
- return ent.go if ent.href && ent.classes.include?(method_str)
73
+ return ent.go if ent.href &&
74
+ (ent.classes.map { |c| c.underscore }).include?(method_str.underscore)
55
75
  end
56
76
  # Does it match a link, if so traverse it and return the entity.
57
77
  @links.each do |key, link|
58
- return link.go if method_str == key
78
+ return link.go if method_str == key.underscore
59
79
  end
60
80
  # Does it match an action, if so return the action.
61
81
  @actions.each do |key, action|
62
- return action if method_str == key
82
+ return action if method_str == key.underscore
63
83
  end
64
84
  raise NoMethodError, 'The method does not match a property, action, or link on SirenClient::Entity.'
65
85
  end
@@ -90,7 +110,7 @@ module SirenClient
90
110
  hash_rel = rel and break
91
111
  end
92
112
  # Ensure the rel name is a valid hash key
93
- hash[hash_rel.underscore] = link
113
+ hash[hash_rel] = link
94
114
  hash
95
115
  end
96
116
  @actions = @payload['actions'] || []
@@ -100,7 +120,7 @@ module SirenClient
100
120
  # Convert actions into a hash
101
121
  @actions = @actions.inject({}) do |hash, action|
102
122
  next unless action.name
103
- hash[action.name.underscore] = action
123
+ hash[action.name] = action
104
124
  hash
105
125
  end
106
126
  @title = @payload['title'] || ''
@@ -1,6 +1,7 @@
1
1
  module SirenClient
2
2
  class Link
3
- attr_reader :payload, :rels, :href, :title, :type, :config
3
+ attr_accessor :href
4
+ attr_reader :payload, :rels, :title, :type, :config
4
5
 
5
6
  def initialize(data, config={})
6
7
  if data.class != Hash
@@ -1,3 +1,3 @@
1
1
  module SirenClient
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -24,9 +24,8 @@ Gem::Specification.new do |spec|
24
24
  spec.add_development_dependency "rack"
25
25
  spec.add_development_dependency "rake"
26
26
  spec.add_development_dependency "sinatra"
27
- spec.add_development_dependency "sinatra-simple-auth"
28
27
  spec.add_development_dependency "rspec"
29
- spec.add_development_dependency "byebug"
28
+ spec.add_development_dependency "byebug" if RUBY_VERSION > "2"
30
29
  spec.add_development_dependency "guard"
31
30
  spec.add_development_dependency "guard-rspec"
32
31
  end
@@ -1,4 +1,4 @@
1
- require 'byebug'
1
+ require 'byebug' if RUBY_VERSION > '2'
2
2
  require 'siren_client'
3
3
 
4
4
  RSpec.configure do |config|
@@ -32,6 +32,12 @@ def siren_body
32
32
  'class' => ['concepts', 'collection'],
33
33
  'rel' => ['/rels/concepts'],
34
34
  'href' => '/graphs/test2/concepts'
35
+ },
36
+ {
37
+ # Just to test the underscore transformation
38
+ 'class' => ['user-preferences', 'collection'],
39
+ 'rel' => ['/rels/user-preferences'],
40
+ 'href' => '/graphs/user/preferences'
35
41
  }
36
42
  ],
37
43
  'links' => [
@@ -71,7 +77,7 @@ def siren_body
71
77
  ]
72
78
  },
73
79
  {
74
- 'name' => 'filter_messages',
80
+ 'name' => 'filter-messages',
75
81
  'method' => 'GET',
76
82
  'href' => '/graphs/test1/messages',
77
83
  'title' => 'Get an optionally filtered list of Messages',
@@ -103,6 +109,10 @@ def siren_body
103
109
  'rel' => ['self'],
104
110
  'href' => '/graphs?limit=1&page=1&order_by=name'
105
111
  },
112
+ {
113
+ 'rel' => ['prev-page'],
114
+ 'href' => '/graphs?limit=1&page=0&order_by=name'
115
+ },
106
116
  {
107
117
  'rel' => ['next'],
108
118
  'href' => '/graphs?limit=1&page=2&order_by=name'
@@ -14,4 +14,4 @@ class TestServer < Sinatra::Base
14
14
  end
15
15
 
16
16
  # Require all the endpoint files that build the api.
17
- Dir[__dir__ + "/endpoints/*.rb"].each {|file| require file }
17
+ Dir[File.expand_path(File.dirname(__FILE__)) + "/endpoints/*.rb"].each {|file| require file }
@@ -52,6 +52,10 @@ describe SirenClient::Action do
52
52
  it 'is a string' do
53
53
  expect(action.href).to be_a String
54
54
  end
55
+ it 'can change .href as needed' do
56
+ action.href = action.href + '?query=test'
57
+ expect(/query=test/).to match(action.href)
58
+ end
55
59
  end
56
60
  describe '.title' do
57
61
  it 'is a string' do
@@ -112,6 +112,10 @@ describe SirenClient::Entity do
112
112
  it 'should be empty' do
113
113
  expect(entity.href).to eq('')
114
114
  end
115
+ it 'can change .href as needed' do
116
+ entity.href = 'http://example.com?query=test'
117
+ expect(/query=test/).to match(entity.href)
118
+ end
115
119
  end
116
120
  # Similar to SirenClient::Link.go this function will create a
117
121
  # new entity from the .href method. For entity sub-links only.
@@ -167,13 +171,182 @@ describe SirenClient::Entity do
167
171
  expect(entity[0]).to be_a SirenClient::Entity
168
172
  end
169
173
  end
170
- describe '.each' do
171
- it 'can iterate over all the entities' do
172
- expect {
173
- entity.each do |ent|
174
- expect(ent).to be_a SirenClient::Entity
175
- end
176
- }.to_not raise_error
174
+ let (:graph) { entity[0] }
175
+ describe '.search("messages")' do
176
+ it 'returns an Array' do
177
+ expect(graph.search('messages')).to be_a Array
178
+ end
179
+ it 'returns an Array of the right size' do
180
+ expect(graph.search('messages').length).to eq(1)
181
+ end
182
+ it 'the first element is a SirenClient::Entity' do
183
+ expect(graph.search('messages')[0]).to be_a SirenClient::Entity
184
+ end
185
+ it 'the first element\'s classes include "messages"' do
186
+ expect(graph.search('messages')[0].classes.include?('messages')).to eq(true)
187
+ end
188
+ end
189
+ describe '.string(/test1/)' do
190
+ it 'returns an Array' do
191
+ expect(graph.search(/test1/)).to be_a Array
192
+ end
193
+ it 'returns an Array of the right size' do
194
+ expect(graph.search(/test1/).length).to eq(1)
195
+ end
196
+ it 'the second element is a SirenClient::Entity' do
197
+ expect(graph.search(/test1/)[0]).to be_a SirenClient::Entity
198
+ end
199
+ it 'the second element\'s classes include "concepts"' do
200
+ expect(graph.search(/test1/)[0].classes.include?('messages')).to eq(true)
201
+ end
202
+ end
203
+ describe '.string(/test[0-9]/)' do
204
+ it 'returns an Array' do
205
+ expect(graph.search(/test[0-9]/)).to be_a Array
206
+ end
207
+ it 'returns an Array of the right size' do
208
+ expect(graph.search(/test[0-9]/).length).to eq(2)
209
+ end
210
+ it 'the second element is a SirenClient::Entity' do
211
+ expect(graph.search(/test[0-9]/)[1]).to be_a SirenClient::Entity
212
+ end
213
+ it 'the second element\'s classes include "concepts"' do
214
+ expect(graph.search(/test[0-9]/)[1].classes.include?('concepts')).to eq(true)
215
+ end
216
+ end
217
+ describe 'underscore support' do
218
+ it 'can access entity sub-links' do
219
+ # Since this will trigger the sub-link. We expect an error
220
+ expect { graph.user_preferences }.to raise_error
221
+ end
222
+ it 'can access actions' do
223
+ expect(entity.filter_messages).to be_a SirenClient::Action
224
+ end
225
+ it 'can access links' do
226
+ # Since this will trigger the link. We expect an error
227
+ expect { entity.prev_page }.to raise_error
228
+ end
229
+ end
230
+ # Entities enumerable support
231
+ describe "enumerable support" do
232
+ describe '.each' do
233
+ it 'can iterate over all the entities' do
234
+ expect {
235
+ graph.each do |ent|
236
+ expect(ent).to be_a SirenClient::Entity
237
+ end
238
+ }.to_not raise_error
239
+ end
240
+ end
241
+ # Useful enumerable methods
242
+ describe '.all?' do
243
+ it 'matches .entities.all?' do
244
+ expect(
245
+ graph.all? do |ent|
246
+ ent == SirenClient::Entity
247
+ end
248
+ ).to eq(
249
+ graph.entities.all? do |ent|
250
+ ent == SirenClient::Entity
251
+ end
252
+ )
253
+ end
254
+ end
255
+ describe '.find' do
256
+ it 'matches .entities.find' do
257
+ expect(
258
+ graph.find do |ent|
259
+ ent.rels.include?('/rels/messages')
260
+ end
261
+ ).to eq(
262
+ graph.entities.find do |ent|
263
+ ent.rels.include?('/rels/messages')
264
+ end
265
+ )
266
+ end
267
+ end
268
+ describe '.find_all' do
269
+ it 'matches .entities.find_all' do
270
+ expect(
271
+ graph.find_all do |ent|
272
+ ent.classes.include?('collection')
273
+ end
274
+ ).to eq(
275
+ graph.entities.find_all do |ent|
276
+ ent.classes.include?('collection')
277
+ end
278
+ )
279
+ end
280
+ end
281
+ describe '.first' do
282
+ it 'matches .entities.first' do
283
+ expect(graph.first).to eq(graph.entities.first)
284
+ end
285
+ end
286
+ describe '.grep' do
287
+ it "matches .entities.grep" do
288
+ expect(
289
+ graph.grep(/test1/) do |ent|
290
+ ent.href
291
+ end
292
+ ).to eq(
293
+ graph.entities.grep(/test1/) do |ent|
294
+ ent.href
295
+ end
296
+ )
297
+ end
298
+ end
299
+ describe '.map' do
300
+ it 'matches .entities.map' do
301
+ expect(
302
+ graph.map do |ent|
303
+ ent.classes.include?('concepts')
304
+ end
305
+ ).to eq(
306
+ graph.entities.map do |ent|
307
+ ent.classes.include?('concepts')
308
+ end
309
+ )
310
+ end
311
+ end
312
+ describe '.reject' do
313
+ it 'matches .entities.reject' do
314
+ expect(
315
+ graph.reject do |ent|
316
+ ent.classes.include?('messages')
317
+ end
318
+ ).to eq(
319
+ graph.entities.reject do |ent|
320
+ ent.classes.include?('messages')
321
+ end
322
+ )
323
+ end
324
+ end
325
+ describe '.select' do
326
+ it 'matches .entities.select' do
327
+ expect(
328
+ graph.select do |ent|
329
+ ent.rels.include?('/rels/concepts')
330
+ end
331
+ ).to eq(
332
+ graph.entities.select do |ent|
333
+ ent.rels.include?('/rels/concepts')
334
+ end
335
+ )
336
+ end
337
+ end
338
+ describe '.sort' do
339
+ it 'matches .entities.sort' do
340
+ expect(
341
+ graph.sort do |ent_a, ent_b|
342
+ ent_b.classes[0] <=> ent_a.classes[0]
343
+ end
344
+ ).to eq(
345
+ graph.entities.sort do |ent_a, ent_b|
346
+ ent_b.classes[0] <=> ent_a.classes[0]
347
+ end
348
+ )
349
+ end
177
350
  end
178
351
  end
179
352
  end
@@ -33,6 +33,10 @@ describe SirenClient::Link do
33
33
  it 'is a string' do
34
34
  expect(link.href).to be_a String
35
35
  end
36
+ it 'can change .href as needed' do
37
+ link.href = link.href + '?query=test'
38
+ expect(/query=test/).to match(link.href)
39
+ end
36
40
  end
37
41
  describe '.title' do
38
42
  it 'is a string' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: siren_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chason Choate
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-10 00:00:00.000000000 Z
11
+ date: 2015-02-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -94,20 +94,6 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: sinatra-simple-auth
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
97
  - !ruby/object:Gem::Dependency
112
98
  name: rspec
113
99
  requirement: !ruby/object:Gem::Requirement
@@ -173,6 +159,7 @@ extra_rdoc_files: []
173
159
  files:
174
160
  - ".gitignore"
175
161
  - ".rspec"
162
+ - ".travis.yml"
176
163
  - Gemfile
177
164
  - Guardfile
178
165
  - LICENSE.txt
@@ -222,7 +209,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
222
209
  version: '0'
223
210
  requirements: []
224
211
  rubyforge_project:
225
- rubygems_version: 2.4.5
212
+ rubygems_version: 2.2.2
226
213
  signing_key:
227
214
  specification_version: 4
228
215
  summary: A client to traverse Siren APIs https://github.com/kevinswiber/siren