restrack-client 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specifying gem's dependencies in restrack-client.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,24 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ restrack-client (0.0.0)
5
+ i18n
6
+ json
7
+ mime-types
8
+ xml-simple (>= 1.0.13)
9
+
10
+ GEM
11
+ remote: http://rubygems.org/
12
+ specs:
13
+ i18n (0.5.0)
14
+ json (1.5.1)
15
+ mime-types (1.16)
16
+ shoulda (2.11.3)
17
+ xml-simple (1.0.14)
18
+
19
+ PLATFORMS
20
+ ruby
21
+
22
+ DEPENDENCIES
23
+ restrack-client!
24
+ shoulda
data/README.markdown ADDED
@@ -0,0 +1,33 @@
1
+ # RESTRack::Client
2
+
3
+ A library for interacting with RESTful web services. Use this to communicate with RESTRack based services.
4
+
5
+
6
+ ## Usage
7
+
8
+ uri = URI.new('http://localhost')
9
+ client = RESTRackClient.new(uri)
10
+ client = RESTRackClient.new('http://localhost')
11
+ foo_resource = client.foo(123) # pivot object that hasn't yet made request
12
+ foo = foo_resource.get( { :data => 'something_here' } ) # request is made to GET /foo/123
13
+ bar = client.foo(123).bar # pivot object that hasn't yet made request
14
+ bar.delete # request is made to DELETE /foo/123/bar
15
+ bar = client.foo(123).bar.post( { :data => 'something_here' } ) # request is made to POST /foo/123/bar
16
+
17
+
18
+ ## License
19
+
20
+ Copyright (c) 2011 Chris St. John
21
+
22
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
23
+ documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
24
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
25
+ persons to whom the Software is furnished to do so, subject to the following conditions:
26
+
27
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
28
+ Software.
29
+
30
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
31
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
32
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
33
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+
4
+ require 'bundler'
5
+ Bundler::GemHelper.install_tasks
6
+
7
+ task :default => [:test]
8
+
9
+ desc 'Run tests.'
10
+ Rake::TestTask.new('test') { |t|
11
+ t.pattern = 'test/**/*.rb'
12
+ }
@@ -0,0 +1,3 @@
1
+ module RESTRackClient
2
+ VERSION = "0.0.0"
3
+ end
@@ -0,0 +1,96 @@
1
+ require 'rubygems'
2
+ require 'mime/types'
3
+ require 'net/http'
4
+ require 'json'
5
+ require 'xmlsimple'
6
+
7
+ module RESTRack
8
+ class Client
9
+
10
+ def initialize(uri, format=:JSON)
11
+ @uri = URI.parse(uri) unless uri.is_a? URI
12
+ @path = ''
13
+ @format = format
14
+ end
15
+
16
+ def method_missing(resource_name, *args)
17
+ @path << '/' + resource_name.to_s + '/' + args.join('/')
18
+ self
19
+ end
20
+
21
+ def get
22
+ request = Net::HTTP::Get.new(@path)
23
+ response = send request
24
+ parse response
25
+ end
26
+
27
+ def delete
28
+ request = Net::HTTP::Delete.new(@path)
29
+ response = send request
30
+ parse response
31
+ end
32
+
33
+ def post(data=nil)
34
+ request = Net::HTTP::Post.new(@path, {'Content-Type' => content_type })
35
+ request.body = prepare data unless data.nil?
36
+ response = send request
37
+ parse response
38
+ end
39
+
40
+ def put(data=nil)
41
+ request = Net::HTTP::Put.new(@path, {'Content-Type' => content_type })
42
+ request.body = prepare data unless data.nil?
43
+ response = send request
44
+ parse response
45
+ end
46
+
47
+ private
48
+ def content_type
49
+ RESTRack.mime_type_for(@format).to_s
50
+ end
51
+
52
+ def prepare(data)
53
+ case @format
54
+ when :JSON
55
+ data = data.to_json
56
+ when :XML
57
+ data = XmlSimple.xml_out(data, 'AttrPrefix' => true, 'XmlDeclaration' => true, 'NoIndent' => true)
58
+ when :YAML
59
+ data = YAML.dump(data)
60
+ when :TEXT
61
+ data = data.to_s
62
+ end
63
+ data
64
+ end
65
+
66
+ def send(request)
67
+ response = Net::HTTP.start(@uri.host, @uri.port) { |http| http.request(request) }
68
+ unless response.kind_of?(Net::HTTPSuccess)
69
+ e = RuntimeError.new("#{request.method} #{request.path} - #{res.code}:#{res.message}\n#{res.body}")
70
+ raise e
71
+ end
72
+ response
73
+ end
74
+
75
+ def parse(response)
76
+ mime_type = MIME::Type.new( response.content_type )#response['content-type'] )
77
+ if mime_type.like?( RESTRack.mime_type_for( :JSON ) )
78
+ return JSON.parse( response.body )
79
+ elsif mime_type.like?( RESTRack.mime_type_for( :XML ) )
80
+ return XmlSimple.xml_in( response.body, 'ForceArray' => false )
81
+ else
82
+ return response.body
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ # XXX - code smells this is also in RESTRack lib/support.rb
89
+ module RESTRack
90
+ def self.mime_type_for(format)
91
+ MIME::Types.type_for(format.to_s.downcase)[0]
92
+ end
93
+ end
94
+ MIME::Types['text/plain'][0].extensions << 'text'
95
+ MIME::Types.index_extensions( MIME::Types['text/plain'][0] )
96
+ # -------------------------------------------------------/
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "restrack-client/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "restrack-client"
7
+ s.version = RESTRackClient::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ['Chris St. John']
10
+ s.email = ['chris@stjohnstudios.com']
11
+ s.homepage = 'http://github.com/stjohncj/RESTRack-Client'
12
+ s.summary = %q{A library for interacting with RESTful web services. Use this to communicate with RESTRack based services.}
13
+ s.description = %q{A library for interacting with RESTful web services. Use this to communicate with RESTRack based services.}
14
+ s.rubyforge_project = "restrack-client"
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ s.require_paths = ["lib"]
19
+
20
+ s.add_development_dependency 'shoulda'
21
+ s.add_runtime_dependency 'mime-types'
22
+ s.add_runtime_dependency 'i18n'
23
+ s.add_runtime_dependency 'json'
24
+ s.add_runtime_dependency 'xml-simple', '>= 1.0.13'
25
+
26
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+ require 'shoulda'
12
+
13
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
15
+ require 'restrack-client'
16
+
17
+ class Test::Unit::TestCase
18
+ end
@@ -0,0 +1,24 @@
1
+ #GENERATOR-CONST# -DO NOT REMOVE OR CHANGE THIS LINE- Application-Namespace => test_app
2
+ #
3
+ # = constants.yaml
4
+ # This is where RESTRack applications define the constants relevant to their particular
5
+ # application that are used by the RESTRack base classes.
6
+
7
+ # Application log path definition
8
+ :LOG: '/var/log/test_app/test_app.log'
9
+ # Request log path definition
10
+ :REQUEST_LOG: '/var/log/test_app/test_app.request.log'
11
+
12
+ # Logger object levels
13
+ :LOG_LEVEL: :DEBUG
14
+ :REQUEST_LOG_LEVEL: :DEBUG
15
+
16
+ # Supported formats are :JSON, :XML, :YAML, :BIN, :TEXT
17
+ :DEFAULT_FORMAT: :JSON
18
+ # The resource which will handle root level requests where the name is not specified. Best for users of this not to implement method_missing in their default controller, unless they are checking for bad URI.
19
+ :DEFAULT_RESOURCE: nil
20
+
21
+ # These are the resources which can be accessed from the root of your web service. If left empty, all resources are available at the root.
22
+ :ROOT_RESOURCE_ACCEPT: []
23
+ # These are the resources which cannot be accessed from the root of your web service. Use either this or ROOT_RESOURCE_ACCEPT as a blacklist or whitelist to establish routing (relationships defined in resource controllers define further routing).
24
+ :ROOT_RESOURCE_DENY: []
@@ -0,0 +1,3 @@
1
+ # Rails.root/config.ru
2
+ require 'loader'
3
+ run TestApp::WebService.new
@@ -0,0 +1,39 @@
1
+ class TestApp::ParentController < RESTRack::ResourceController
2
+
3
+ has_relationship_to :responses do |id|
4
+ id
5
+ end
6
+
7
+ def index
8
+
9
+ end
10
+
11
+ def create
12
+
13
+ end
14
+
15
+ def replace
16
+
17
+ end
18
+
19
+ def destroy
20
+
21
+ end
22
+
23
+ def show(id)
24
+
25
+ end
26
+
27
+ def update(id)
28
+
29
+ end
30
+
31
+ def delete(id)
32
+
33
+ end
34
+
35
+ def add(id)
36
+
37
+ end
38
+
39
+ end
@@ -0,0 +1,66 @@
1
+ class TestApp::ResponsesController < RESTRack::ResourceController
2
+
3
+ def method_missing(method_name, *args)
4
+ {
5
+ :method_called => method_name.to_s,
6
+ :args => args.join(':')
7
+ }
8
+ end
9
+
10
+ def index
11
+ {
12
+ :action => :index
13
+ }
14
+ end
15
+
16
+ def create
17
+ {
18
+ :action => :create,
19
+ :data => @input
20
+ }
21
+ end
22
+
23
+ def replace
24
+ {
25
+ :action => :replace,
26
+ :data => @input
27
+ }
28
+ end
29
+
30
+ def drop
31
+ {
32
+ :action => :destroy
33
+ }
34
+ end
35
+
36
+ def show(id)
37
+ {
38
+ :action => :show,
39
+ :id => id
40
+ }
41
+ end
42
+
43
+ def update(id)
44
+ {
45
+ :action => :update,
46
+ :id => id,
47
+ :data => @input
48
+ }
49
+ end
50
+
51
+ def destroy(id)
52
+ {
53
+ :action => :delete,
54
+ :id => id
55
+ }
56
+ end
57
+
58
+ def add(id)
59
+ {
60
+ :action => :add,
61
+ :id => id,
62
+ :data => @input
63
+ }
64
+ end
65
+
66
+ end
@@ -0,0 +1,21 @@
1
+ require 'restrack'
2
+
3
+ module TestApp; end
4
+ class TestApp::WebService < RESTRack::WebService; end
5
+
6
+ RESTRack::CONFIG = RESTRack::load_config(File.join(File.dirname(__FILE__), 'config/constants.yaml'))
7
+ RESTRack::CONFIG[:ROOT] = File.dirname(__FILE__)
8
+
9
+ # Dynamically load all controllers
10
+ Find.find( File.join(File.dirname(__FILE__), 'controllers') ) do |file|
11
+ next if File.extname(file) != '.rb'
12
+ require file
13
+ end
14
+
15
+ if File.directory?( File.join(File.dirname(__FILE__), 'models') )
16
+ # Dynamically load all models
17
+ Find.find( File.join(File.dirname(__FILE__), 'models') ) do |file|
18
+ next if File.extname(file) != '.rb'
19
+ require file
20
+ end
21
+ end
@@ -0,0 +1,168 @@
1
+ require File.join( File.dirname(__FILE__ ), 'helper' )
2
+
3
+ class TestRESTRackClient < Test::Unit::TestCase
4
+
5
+ context 'instantiation' do
6
+ should 'accept a String URI' do
7
+ assert_nothing_raised { client_1 = RESTRack::Client.new('http://localhost:9292') }
8
+ end
9
+ should 'accept a URI object' do
10
+ uri = URI.parse('http://localhost:9292')
11
+ assert_nothing_raised { client_2 = RESTRack::Client.new(uri) }
12
+ end
13
+ end
14
+
15
+ should 'get a resource' do
16
+ client = RESTRack::Client.new('http://localhost:9292')
17
+ get_response = nil
18
+ assert_nothing_raised do
19
+ get_response = client.responses(1).get
20
+ end
21
+ expected_response = { 'action' => 'show', 'id' => '1' }
22
+ assert_equal expected_response, get_response
23
+ end
24
+ should 'get a collection' do
25
+ client = RESTRack::Client.new('http://localhost:9292')
26
+ get_response = nil
27
+ assert_nothing_raised do
28
+ get_response = client.responses.get
29
+ end
30
+ expected_response = { 'action' => 'index' }
31
+ assert_equal expected_response, get_response
32
+ end
33
+
34
+ should 'delete a resource' do
35
+ client = RESTRack::Client.new('http://localhost:9292')
36
+ delete_response = nil
37
+ assert_nothing_raised do
38
+ delete_response = client.responses(1).delete
39
+ end
40
+ expected_response = { 'action' => 'delete', 'id' => '1' }
41
+ assert_equal expected_response, delete_response
42
+ end
43
+ should 'delete a collection' do
44
+ client = RESTRack::Client.new('http://localhost:9292')
45
+ delete_response = nil
46
+ assert_nothing_raised do
47
+ delete_response = client.responses.delete
48
+ end
49
+ expected_response = { 'action' => 'destroy' }
50
+ assert_equal expected_response, delete_response
51
+ end
52
+
53
+ should 'post a resource' do
54
+ client = RESTRack::Client.new('http://localhost:9292')
55
+ post_response = nil
56
+ data = {
57
+ 'test' => 'data'
58
+ }
59
+ assert_nothing_raised do
60
+ post_response = client.responses(1).post(data)
61
+ end
62
+ expected_response = { 'action' => 'add', 'id' => '1', 'data' => data }
63
+ assert_equal expected_response, post_response
64
+ end
65
+ should 'post a collection' do
66
+ client = RESTRack::Client.new('http://localhost:9292')
67
+ post_response = nil
68
+ data = {
69
+ 'test' => 'data'
70
+ }
71
+ assert_nothing_raised do
72
+ post_response = client.responses.post(data)
73
+ end
74
+ expected_response = { 'action' => 'create', 'data' => data }
75
+ assert_equal expected_response, post_response
76
+ end
77
+
78
+ should 'put a resource' do
79
+ client = RESTRack::Client.new('http://localhost:9292')
80
+ put_response = nil
81
+ data = {
82
+ 'test' => 'data'
83
+ }
84
+ assert_nothing_raised do
85
+ put_response = client.responses(1).put(data)
86
+ end
87
+ expected_response = { 'action' => 'update', 'id' => '1', 'data' => data }
88
+ assert_equal expected_response, put_response
89
+ end
90
+ should 'put a collection' do
91
+ client = RESTRack::Client.new('http://localhost:9292')
92
+ put_response = nil
93
+ data = {
94
+ 'test' => 'data'
95
+ }
96
+ assert_nothing_raised do
97
+ put_response = client.responses.put(data)
98
+ end
99
+ expected_response = { 'action' => 'replace', 'data' => data }
100
+ assert_equal expected_response, put_response
101
+ end
102
+
103
+ should 'send and parse response json data' do
104
+ client = RESTRack::Client.new('http://localhost:9292', :JSON)
105
+ post_response = nil
106
+ data = {
107
+ 'test' => 'data'
108
+ }
109
+ assert_nothing_raised do
110
+ post_response = client.responses(1).post(data)
111
+ end
112
+ expected_response = { 'action' => 'add', 'id' => '1', 'data' => data }
113
+ assert_equal expected_response, post_response
114
+ end
115
+ should 'send and parse response xml data' do
116
+ client = RESTRack::Client.new('http://localhost:9292', :XML)
117
+ post_response = nil
118
+ data = {
119
+ 'test' => 'data'
120
+ }
121
+ assert_nothing_raised do
122
+ post_response = client.responses(1).post(data)
123
+ end
124
+ expected_response = { 'action' => 'add', 'id' => '1', 'data' => data }
125
+ assert_equal expected_response, post_response
126
+ end
127
+ #should 'send and parse response yaml data' do
128
+ # client = RESTRack::Client.new('http://localhost:9292', :YAML)
129
+ # post_response = nil
130
+ # data = {
131
+ # 'test' => 'data'
132
+ # }
133
+ # assert_nothing_raised do
134
+ # post_response = client.responses(1).post(data)
135
+ # end
136
+ # expected_response = { 'action' => 'add', 'id' => '1', 'data' => data }
137
+ # assert_equal expected_response, post_response
138
+ #end
139
+ should 'allow building of request path prior to request' do
140
+ client = RESTRack::Client.new('http://localhost:9292')
141
+ object = client.responses(1)
142
+ assert object.class.to_s, 'RESTRack::Client'
143
+ assert object.const_get(:path), '/responses/1'
144
+ end
145
+ should 'pivot' do
146
+ client = RESTRack::Client.new('http://localhost:9292')
147
+ object = client.responses(1)
148
+ get_response = nil
149
+ assert_nothing_raised do
150
+ get_response = object.get
151
+ end
152
+ expected_response = { 'action' => 'show', 'id' => '1' }
153
+ assert_equal expected_response, get_response
154
+ end
155
+ should 'walk a relation path to a child resource' do
156
+ client = RESTRack::Client.new('http://localhost:9292')
157
+ post_response = nil
158
+ data = {
159
+ 'test' => 'data'
160
+ }
161
+ assert_nothing_raised do
162
+ post_response = client.parent(1).responses.post(data)
163
+ end
164
+ expected_response = { 'action' => 'add', 'id' => '1', 'data' => data }
165
+ assert_equal expected_response, post_response
166
+ end
167
+
168
+ end
metadata ADDED
@@ -0,0 +1,131 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: restrack-client
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.0
6
+ platform: ruby
7
+ authors:
8
+ - Chris St. John
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-02-26 00:00:00 -05:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: shoulda
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "0"
25
+ type: :development
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: mime-types
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: "0"
36
+ type: :runtime
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: i18n
40
+ prerelease: false
41
+ requirement: &id003 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ type: :runtime
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
50
+ name: json
51
+ prerelease: false
52
+ requirement: &id004 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ type: :runtime
59
+ version_requirements: *id004
60
+ - !ruby/object:Gem::Dependency
61
+ name: xml-simple
62
+ prerelease: false
63
+ requirement: &id005 !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 1.0.13
69
+ type: :runtime
70
+ version_requirements: *id005
71
+ description: A library for interacting with RESTful web services. Use this to communicate with RESTRack based services.
72
+ email:
73
+ - chris@stjohnstudios.com
74
+ executables: []
75
+
76
+ extensions: []
77
+
78
+ extra_rdoc_files: []
79
+
80
+ files:
81
+ - .document
82
+ - Gemfile
83
+ - Gemfile.lock
84
+ - README.markdown
85
+ - Rakefile
86
+ - lib/restrack-client.rb
87
+ - lib/restrack-client/version.rb
88
+ - restrack-client.gemspec
89
+ - test/helper.rb
90
+ - test/test_app/config.ru
91
+ - test/test_app/config/constants.yaml
92
+ - test/test_app/controllers/parent_controller.rb
93
+ - test/test_app/controllers/responses_controller.rb
94
+ - test/test_app/loader.rb
95
+ - test/test_restrack-client.rb
96
+ has_rdoc: true
97
+ homepage: http://github.com/stjohncj/RESTRack-Client
98
+ licenses: []
99
+
100
+ post_install_message:
101
+ rdoc_options: []
102
+
103
+ require_paths:
104
+ - lib
105
+ required_ruby_version: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: "0"
111
+ required_rubygems_version: !ruby/object:Gem::Requirement
112
+ none: false
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: "0"
117
+ requirements: []
118
+
119
+ rubyforge_project: restrack-client
120
+ rubygems_version: 1.5.2
121
+ signing_key:
122
+ specification_version: 3
123
+ summary: A library for interacting with RESTful web services. Use this to communicate with RESTRack based services.
124
+ test_files:
125
+ - test/helper.rb
126
+ - test/test_app/config.ru
127
+ - test/test_app/config/constants.yaml
128
+ - test/test_app/controllers/parent_controller.rb
129
+ - test/test_app/controllers/responses_controller.rb
130
+ - test/test_app/loader.rb
131
+ - test/test_restrack-client.rb