restrack 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +4 -0
- data/README.rdoc +71 -0
- data/Rakefile +32 -0
- data/bin/restrack +23 -0
- data/config/constants.yaml +8 -0
- data/lib/restrack/generator/constants.yaml.erb +24 -0
- data/lib/restrack/generator/controller.rb.erb +35 -0
- data/lib/restrack/generator/loader.rb.erb +21 -0
- data/lib/restrack/generator.rb +93 -0
- data/lib/restrack/http_status.rb +10 -0
- data/lib/restrack/resource_controller.rb +192 -0
- data/lib/restrack/resource_request.rb +135 -0
- data/lib/restrack/support.rb +56 -0
- data/lib/restrack/version.rb +3 -0
- data/lib/restrack/web_service.rb +66 -0
- data/lib/restrack.rb +24 -0
- data/restrack.gemspec +28 -0
- data/test/sample_app_1/config/constants.yaml +25 -0
- data/test/sample_app_1/controllers/bat_controller.rb +9 -0
- data/test/sample_app_1/controllers/baz_controller.rb +9 -0
- data/test/sample_app_1/controllers/baza_controller.rb +11 -0
- data/test/sample_app_1/controllers/bazu_controller.rb +16 -0
- data/test/sample_app_1/controllers/foo_bar_controller.rb +62 -0
- data/test/sample_app_1/loader.rb +31 -0
- data/test/sample_app_1/test/test_controller_actions.rb +122 -0
- data/test/sample_app_1/test/test_controller_modifiers.rb +153 -0
- data/test/sample_app_1/test/test_formats.rb +119 -0
- data/test/sample_app_1/test/test_resource_request.rb +160 -0
- data/test/sample_app_1/test/test_web_service.rb +27 -0
- data/test/sample_app_1/views/foo_bar/show.xml.builder +4 -0
- data/test/sample_app_2/config/constants.yaml +24 -0
- data/test/sample_app_2/controllers/bat_controller.rb +9 -0
- data/test/sample_app_2/controllers/baz_controller.rb +9 -0
- data/test/sample_app_2/controllers/baza_controller.rb +11 -0
- data/test/sample_app_2/controllers/bazu_controller.rb +8 -0
- data/test/sample_app_2/controllers/foo_bar_controller.rb +59 -0
- data/test/sample_app_2/loader.rb +31 -0
- data/test/sample_app_2/test/test_controller_modifiers.rb +121 -0
- data/test/sample_app_2/test/test_resource_request.rb +71 -0
- data/test/sample_app_2/views/foo_bar/show.xml.builder +4 -0
- data/test/sample_app_3/config/constants.yaml +24 -0
- data/test/sample_app_3/controllers/bat_controller.rb +9 -0
- data/test/sample_app_3/controllers/baz_controller.rb +9 -0
- data/test/sample_app_3/controllers/baza_controller.rb +11 -0
- data/test/sample_app_3/controllers/bazu_controller.rb +8 -0
- data/test/sample_app_3/controllers/foo_bar_controller.rb +59 -0
- data/test/sample_app_3/loader.rb +31 -0
- data/test/sample_app_3/test/test_resource_request.rb +42 -0
- data/test/sample_app_3/views/foo_bar/show.xml.builder +4 -0
- data/test/sample_app_4/config/constants.yaml +24 -0
- data/test/sample_app_4/controllers/bar_controller.rb +11 -0
- data/test/sample_app_4/controllers/baz_controller.rb +15 -0
- data/test/sample_app_4/controllers/foo_controller.rb +21 -0
- data/test/sample_app_4/loader.rb +31 -0
- data/test/sample_app_4/test/test_controller_modifiers.rb +28 -0
- data/test/sample_app_4/test/test_formats.rb +49 -0
- data/test/sample_app_4/views/alphatest.png +0 -0
- data/test/test_support.rb +20 -0
- data/test/test_web_service.rb +31 -0
- metadata +238 -0
@@ -0,0 +1,56 @@
|
|
1
|
+
module RESTRack
|
2
|
+
|
3
|
+
class << self
|
4
|
+
def log; @@log; end
|
5
|
+
def request_log; @@request_log; end
|
6
|
+
end # of class methods
|
7
|
+
|
8
|
+
def self.load_config(file)
|
9
|
+
config = YAML.load_file(file)
|
10
|
+
# Open the logs on spin up.
|
11
|
+
@@log ||= Logger.new( config[:LOG] )
|
12
|
+
@@log.level = Logger.const_get( config[:LOG_LEVEL] )
|
13
|
+
@@request_log ||= Logger.new( config[:REQUEST_LOG] )
|
14
|
+
@@request_log.level = Logger.const_get( config[:LOG_LEVEL] )
|
15
|
+
# Do config validations
|
16
|
+
if config[:ROOT_RESOURCE_ACCEPT].is_a?(Array) and config[:ROOT_RESOURCE_ACCEPT].length == 1 and config[:ROOT_RESOURCE_ACCEPT][0].lstrip.rstrip == ''
|
17
|
+
config[:ROOT_RESOURCE_ACCEPT] = nil
|
18
|
+
@@log.warn 'Improper format for RESTRack::CONFIG[:ROOT_RESOURCE_ACCEPT], should be nil or empty array not array containing empty string.'
|
19
|
+
end
|
20
|
+
if not config[:ROOT_RESOURCE_ACCEPT].blank? and not config[:DEFAULT_RESOURCE].blank? and not config[:ROOT_RESOURCE_ACCEPT].include?( config[:DEFAULT_RESOURCE] )
|
21
|
+
@@log.warn 'RESTRack::CONFIG[:DEFAULT_RESOURCE] should be a member of RESTRack::CONFIG[:ROOT_RESOURCE_ACCEPT].'
|
22
|
+
end
|
23
|
+
config
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.mime_type_for(format)
|
27
|
+
MIME::Types.type_for(format.to_s.downcase)[0]
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.resource_exists?(resource_name)
|
31
|
+
klass = controller_class_for( resource_name )
|
32
|
+
return klass.is_a?(Class)
|
33
|
+
rescue NameError
|
34
|
+
return false
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.controller_class_for(resource_name)
|
38
|
+
Kernel.const_get( RESTRack::CONFIG[:SERVICE_NAME].to_sym ).const_get( controller_name(resource_name).to_sym )
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.controller_name(resource_name)
|
42
|
+
"#{resource_name.camelize}Controller".to_sym
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
# Courtesy of Rails' ActiveSupport, thank you DHH et al.
|
48
|
+
class Object
|
49
|
+
def blank?
|
50
|
+
respond_to?(:empty?) ? empty? : !self
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# We will support ".text" as an extension
|
55
|
+
MIME::Types['text/plain'][0].extensions << 'text'
|
56
|
+
MIME::Types.index_extensions( MIME::Types['text/plain'][0] )
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module RESTRack
|
2
|
+
class WebService
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
# Establish the namespace pointer.
|
6
|
+
RESTRack::CONFIG[:SERVICE_NAME] = self.class.to_s.split('::')[0].to_sym
|
7
|
+
end
|
8
|
+
|
9
|
+
def call( env )
|
10
|
+
# Handle requests.
|
11
|
+
request = Rack::Request.new(env)
|
12
|
+
begin
|
13
|
+
resource_request = RESTRack::ResourceRequest.new( :request => request )
|
14
|
+
resource_request.locate
|
15
|
+
resource_request.call
|
16
|
+
response = resource_request.output
|
17
|
+
return valid resource_request, response
|
18
|
+
rescue Exception => exception
|
19
|
+
return caught resource_request, exception
|
20
|
+
end
|
21
|
+
end # method call
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def valid( resource_request, response )
|
26
|
+
# Return HTTP200OK SUCCESS
|
27
|
+
RESTRack.request_log.debug "'#{resource_request.mime_type.to_s}' response data (Request ID: #{resource_request.request_id})\n" + response.to_s unless not response.respond_to?( :to_s )
|
28
|
+
RESTRack.request_log.info "HTTP200OK - (Request ID: #{resource_request.request_id})"
|
29
|
+
return [200, {'Content-Type' => resource_request.content_type}, response ]
|
30
|
+
end
|
31
|
+
|
32
|
+
def caught( resource_request, exception )
|
33
|
+
# Return appropriate response code and messages per raised exception type.
|
34
|
+
if resource_request && resource_request.request_id
|
35
|
+
RESTRack.request_log.info exception.message + "(Request ID: #{resource_request.request_id})"
|
36
|
+
else
|
37
|
+
RESTRack.request_log.info exception.message
|
38
|
+
end
|
39
|
+
case
|
40
|
+
when exception.is_a?( HTTP400BadRequest )
|
41
|
+
return [400, {'Content-Type' => 'text/plain'}, exception.message + "\nThe request cannot be fulfilled due to bad syntax." ]
|
42
|
+
when exception.is_a?( HTTP401Unauthorized )
|
43
|
+
return [401, {'Content-Type' => 'text/plain'}, exception.message + "\nYou have failed authentication for access to the resource." ]
|
44
|
+
when exception.is_a?( HTTP403Forbidden )
|
45
|
+
return [403, {'Content-Type' => 'text/plain'}, exception.message + "\nYou are forbidden to access that resource." ]
|
46
|
+
when exception.is_a?( HTTP404ResourceNotFound )
|
47
|
+
return [404, {'Content-Type' => 'text/plain'}, exception.message + "\nThe resource you requested could not be found." ]
|
48
|
+
when exception.is_a?( HTTP405MethodNotAllowed )
|
49
|
+
return [405, {'Content-Type' => 'text/plain'}, exception.message + "\nThe resource you requested does not support the request method provided." ]
|
50
|
+
when exception.is_a?( HTTP409Conflict )
|
51
|
+
return [409, {'Content-Type' => 'text/plain'}, exception.message + "\nThe resource you requested is in a conflicted state." ]
|
52
|
+
when exception.is_a?( HTTP410Gone )
|
53
|
+
return [410, {'Content-Type' => 'text/plain'}, exception.message + "\nThe resource you requested is no longer available." ]
|
54
|
+
else # HTTP500ServerError
|
55
|
+
msg = exception.message + "\n\n" + exception.backtrace.join("\n")
|
56
|
+
if resource_request && resource_request.request_id
|
57
|
+
RESTRack.log.error msg + " (Request ID: #{resource_request.request_id})\n\n"
|
58
|
+
else
|
59
|
+
RESTRack.log.error msg
|
60
|
+
end
|
61
|
+
return [500, {'Content-Type' => 'text/plain'}, msg ]
|
62
|
+
end # case Exception
|
63
|
+
end # method caught
|
64
|
+
|
65
|
+
end # class WebService
|
66
|
+
end # module RESTRack
|
data/lib/restrack.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
%w[
|
2
|
+
rack
|
3
|
+
logger
|
4
|
+
find
|
5
|
+
yaml
|
6
|
+
rubygems
|
7
|
+
json
|
8
|
+
xmlsimple
|
9
|
+
builder
|
10
|
+
active_support/inflector
|
11
|
+
mime/types
|
12
|
+
].each do |file|
|
13
|
+
require file
|
14
|
+
end
|
15
|
+
|
16
|
+
# Dynamically load all files in lib
|
17
|
+
Find.find( File.join(File.dirname(__FILE__)) ) do |file|
|
18
|
+
next if File.extname(file) != '.rb'
|
19
|
+
puts 'loading file ' + file
|
20
|
+
require file
|
21
|
+
end
|
22
|
+
|
23
|
+
include HTTPStatus
|
24
|
+
include ActiveSupport::Inflector
|
data/restrack.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "restrack/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "restrack"
|
7
|
+
s.version = RESTRack::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'
|
12
|
+
s.summary = %q{A lightweight MVC framework developed specifically for JSON and XML REST services.}
|
13
|
+
s.description = %q{RESTRack is an MVC framework that makes it extremely easy to develop RESTful data services. It is inspired by Rails, and follows some of its conventions, but aims at being lightweight and easy to use.}
|
14
|
+
|
15
|
+
s.rubyforge_project = "restrack"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_runtime_dependency 'json'
|
23
|
+
s.add_runtime_dependency 'xml-simple', '>= 1.0.13'
|
24
|
+
s.add_runtime_dependency 'builder'
|
25
|
+
s.add_runtime_dependency 'activesupport'
|
26
|
+
s.add_runtime_dependency 'mime-types'
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#GENERATOR-CONST# -DO NOT REMOVE OR CHANGE THIS LINE- Application-Namespace => SampleApp
|
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/restrack/sample_app.log'
|
9
|
+
# Request log path definition
|
10
|
+
:REQUEST_LOG: '/var/log/restrack/sample_app.request.log'
|
11
|
+
|
12
|
+
# Logger object levels
|
13
|
+
:LOG_LEVEL: :DEBUG # Logger object level
|
14
|
+
:REQUEST_LOG_LEVEL: :DEBUG # Logger object level
|
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
|
+
# This setting ('bazu') won't work because of :ROOT_RESOURCE_ACCEPT VALUE (:DEFAULT_RESOURCE should be a member of :ROOT_RESOURCE_ACCEPT).
|
20
|
+
:DEFAULT_RESOURCE: 'bazu'
|
21
|
+
|
22
|
+
# 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.
|
23
|
+
:ROOT_RESOURCE_ACCEPT: [ 'foo_bar' ]
|
24
|
+
# 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).
|
25
|
+
:ROOT_RESOURCE_DENY: [ 'baz' ]
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class SampleApp::BazuController < RESTRack::ResourceController
|
2
|
+
|
3
|
+
def show(id)
|
4
|
+
return 1 if id == 1
|
5
|
+
return 0
|
6
|
+
end
|
7
|
+
|
8
|
+
def index
|
9
|
+
return [
|
10
|
+
{ :id => 1, :val => 111 },
|
11
|
+
{ :id => 2, :val => 222 },
|
12
|
+
{ :id => 3, :val => 333 }
|
13
|
+
]
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
class SampleApp::FooBarController < RESTRack::ResourceController
|
2
|
+
|
3
|
+
has_direct_relationship_to( :baz, :as => :baz ) do |id|
|
4
|
+
if id =='144'
|
5
|
+
output = '777'
|
6
|
+
else
|
7
|
+
output = '666'
|
8
|
+
end
|
9
|
+
output # You can't "return" from a Proc! It will do a "return" in the outer method. Remember a "Proc" is not a Method.
|
10
|
+
end
|
11
|
+
|
12
|
+
has_direct_relationship_to( :bat, :as => :slugger ) do |id|
|
13
|
+
if id =='144'
|
14
|
+
output = '777'
|
15
|
+
else
|
16
|
+
output = '666'
|
17
|
+
end
|
18
|
+
output # You can't "return" from a Proc! It will do a "return" in the outer method. Remember a "Proc" is not a Method.
|
19
|
+
end
|
20
|
+
|
21
|
+
has_direct_relationships_to( :baza, :as => :children ) do |id|
|
22
|
+
[1,2,3,4,5,6,7,8,9]
|
23
|
+
end
|
24
|
+
|
25
|
+
has_mapped_relationships_to( :bazu, :as => :maps ) do |id|
|
26
|
+
{
|
27
|
+
:first => 1,
|
28
|
+
:second => 2,
|
29
|
+
:third => 3
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
def index
|
34
|
+
[1,2,3,4,5,6,7]
|
35
|
+
end
|
36
|
+
def create
|
37
|
+
{ :success => true }
|
38
|
+
end
|
39
|
+
def replace
|
40
|
+
{ :success => true }
|
41
|
+
end
|
42
|
+
def drop
|
43
|
+
{ :success => true }
|
44
|
+
end
|
45
|
+
|
46
|
+
def show(id)
|
47
|
+
if id == '1234567890'
|
48
|
+
return { :foo => 'abc', :bar => '123', 'baz' => 456, :more => { :one => 1, :two => [1,2], :three => :deep_fu } }
|
49
|
+
end
|
50
|
+
{ :foo => 'bar', :baz => 123 }
|
51
|
+
end
|
52
|
+
def update(id)
|
53
|
+
{ :success => true }
|
54
|
+
end
|
55
|
+
def destroy(id)
|
56
|
+
{ :success => true }
|
57
|
+
end
|
58
|
+
def add(id)
|
59
|
+
{ :success => true }
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# for development only
|
2
|
+
$:.unshift File.expand_path(File.join(File.dirname(__FILE__),'../../lib'))
|
3
|
+
#####
|
4
|
+
require 'restrack'
|
5
|
+
|
6
|
+
module SampleApp; end
|
7
|
+
class SampleApp::WebService < RESTRack::WebService; end
|
8
|
+
|
9
|
+
RESTRack::CONFIG = RESTRack::load_config(File.join(File.dirname(__FILE__), 'config/constants.yaml'))
|
10
|
+
RESTRack::CONFIG[:ROOT] = File.dirname(__FILE__)
|
11
|
+
|
12
|
+
# Dynamically load all controllers
|
13
|
+
Find.find( File.join(File.dirname(__FILE__), 'controllers') ) do |file|
|
14
|
+
next if File.extname(file) != '.rb'
|
15
|
+
require file
|
16
|
+
end
|
17
|
+
|
18
|
+
if File.directory?( File.join(File.dirname(__FILE__), 'models') )
|
19
|
+
# Dynamically load all models
|
20
|
+
Find.find( File.join(File.dirname(__FILE__), 'models') ) do |file|
|
21
|
+
next if File.extname(file) != '.rb'
|
22
|
+
require file
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
puts "sample_app_1 RESTRack::CONFIG:\n"
|
27
|
+
config = RESTRack::CONFIG.keys.map {|c| c.to_s }.sort
|
28
|
+
config.each do |key|
|
29
|
+
puts "\t" + key + ' => ' + RESTRack::CONFIG[key.to_sym].to_s
|
30
|
+
end
|
31
|
+
puts "\n"
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'rack/test'
|
4
|
+
require File.expand_path(File.join(File.dirname(__FILE__),'..','loader'))
|
5
|
+
require 'pp'
|
6
|
+
|
7
|
+
class SampleApp::TestControllerActions < Test::Unit::TestCase
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@ws = SampleApp::WebService.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_show
|
14
|
+
env = Rack::MockRequest.env_for('/foo_bar/144', {
|
15
|
+
:method => 'GET'
|
16
|
+
})
|
17
|
+
output = ''
|
18
|
+
assert_nothing_raised do
|
19
|
+
output = @ws.call(env)
|
20
|
+
end
|
21
|
+
test_val = { :foo => 'bar', :baz => 123 }.to_json
|
22
|
+
assert_equal test_val, output[2]
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_update
|
26
|
+
env = Rack::MockRequest.env_for('/foo_bar/144', {
|
27
|
+
:method => 'PUT'
|
28
|
+
})
|
29
|
+
output = ''
|
30
|
+
assert_nothing_raised do
|
31
|
+
output = @ws.call(env)
|
32
|
+
end
|
33
|
+
test_val = { :success => true }.to_json
|
34
|
+
assert_equal test_val, output[2]
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_add
|
38
|
+
env = Rack::MockRequest.env_for('/foo_bar/144', {
|
39
|
+
:method => 'POST'
|
40
|
+
})
|
41
|
+
output = ''
|
42
|
+
assert_nothing_raised do
|
43
|
+
output = @ws.call(env)
|
44
|
+
end
|
45
|
+
test_val = { :success => true }.to_json
|
46
|
+
assert_equal test_val, output[2]
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_destroy
|
50
|
+
env = Rack::MockRequest.env_for('/foo_bar/144', {
|
51
|
+
:method => 'DELETE'
|
52
|
+
})
|
53
|
+
output = ''
|
54
|
+
assert_nothing_raised do
|
55
|
+
output = @ws.call(env)
|
56
|
+
end
|
57
|
+
test_val = { :success => true }.to_json
|
58
|
+
assert_equal test_val, output[2]
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
def test_index
|
63
|
+
env = Rack::MockRequest.env_for('/foo_bar/', {
|
64
|
+
:method => 'GET'
|
65
|
+
})
|
66
|
+
output = ''
|
67
|
+
assert_nothing_raised do
|
68
|
+
output = @ws.call(env)
|
69
|
+
end
|
70
|
+
test_val = [1,2,3,4,5,6,7].to_json
|
71
|
+
assert_equal test_val, output[2]
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_replace
|
75
|
+
env = Rack::MockRequest.env_for('/foo_bar', {
|
76
|
+
:method => 'PUT'
|
77
|
+
})
|
78
|
+
output = ''
|
79
|
+
assert_nothing_raised do
|
80
|
+
output = @ws.call(env)
|
81
|
+
end
|
82
|
+
test_val = { :success => true }.to_json
|
83
|
+
assert_equal test_val, output[2]
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_create
|
87
|
+
env = Rack::MockRequest.env_for('/foo_bar/', {
|
88
|
+
:method => 'POST'
|
89
|
+
})
|
90
|
+
output = ''
|
91
|
+
assert_nothing_raised do
|
92
|
+
output = @ws.call(env)
|
93
|
+
end
|
94
|
+
test_val = { :success => true }.to_json
|
95
|
+
assert_equal test_val, output[2]
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_drop
|
99
|
+
env = Rack::MockRequest.env_for('/foo_bar', {
|
100
|
+
:method => 'DELETE'
|
101
|
+
})
|
102
|
+
output = ''
|
103
|
+
assert_nothing_raised do
|
104
|
+
output = @ws.call(env)
|
105
|
+
end
|
106
|
+
test_val = { :success => true }.to_json
|
107
|
+
assert_equal test_val, output[2]
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
def test_missing
|
112
|
+
env = Rack::MockRequest.env_for('/foo_bar/144/missing', {
|
113
|
+
:method => 'GET'
|
114
|
+
})
|
115
|
+
output = ''
|
116
|
+
assert_nothing_raised do
|
117
|
+
output = @ws.call(env)
|
118
|
+
end
|
119
|
+
assert_equal 405, output[0]
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'rack/test'
|
4
|
+
require File.expand_path(File.join(File.dirname(__FILE__),'..','loader'))
|
5
|
+
require 'pp'
|
6
|
+
|
7
|
+
class SampleApp::TestControllerModifiers < Test::Unit::TestCase
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@ws = SampleApp::WebService.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_has_relationship_to
|
14
|
+
env = Rack::MockRequest.env_for('/foo_bar/144/baz', {
|
15
|
+
:method => 'GET'
|
16
|
+
})
|
17
|
+
output = ''
|
18
|
+
assert_nothing_raised do
|
19
|
+
output = @ws.call(env)
|
20
|
+
end
|
21
|
+
test_val = { :BAZ => 'HOLA!' }.to_json
|
22
|
+
assert_equal test_val, output[2]
|
23
|
+
|
24
|
+
env = Rack::MockRequest.env_for('/foo_bar/133/baz', {
|
25
|
+
:method => 'GET'
|
26
|
+
})
|
27
|
+
output = ''
|
28
|
+
assert_nothing_raised do
|
29
|
+
output = @ws.call(env)
|
30
|
+
end
|
31
|
+
test_val = { :OTHER => 'YUP' }.to_json
|
32
|
+
assert_equal test_val, output[2]
|
33
|
+
|
34
|
+
env = Rack::MockRequest.env_for('/foo_bar/144/baz/', {
|
35
|
+
:method => 'GET'
|
36
|
+
})
|
37
|
+
output = ''
|
38
|
+
assert_nothing_raised do
|
39
|
+
output = @ws.call(env)
|
40
|
+
end
|
41
|
+
test_val = { :BAZ => 'HOLA!' }.to_json
|
42
|
+
assert_equal test_val, output[2]
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_second_has_relationship_to
|
46
|
+
env = Rack::MockRequest.env_for('/foo_bar/144/slugger', {
|
47
|
+
:method => 'GET'
|
48
|
+
})
|
49
|
+
output = ''
|
50
|
+
assert_nothing_raised do
|
51
|
+
output = @ws.call(env)
|
52
|
+
end
|
53
|
+
test_val = { :WOM => 'BAT!' }.to_json
|
54
|
+
assert_equal test_val, output[2]
|
55
|
+
|
56
|
+
env = Rack::MockRequest.env_for('/foo_bar/133/slugger', {
|
57
|
+
:method => 'GET'
|
58
|
+
})
|
59
|
+
output = ''
|
60
|
+
assert_nothing_raised do
|
61
|
+
output = @ws.call(env)
|
62
|
+
end
|
63
|
+
test_val = { :SUHWING => 'BATTER' }.to_json
|
64
|
+
assert_equal test_val, output[2]
|
65
|
+
|
66
|
+
env = Rack::MockRequest.env_for('/foo_bar/144/slugger/', {
|
67
|
+
:method => 'GET'
|
68
|
+
})
|
69
|
+
output = ''
|
70
|
+
assert_nothing_raised do
|
71
|
+
output = @ws.call(env)
|
72
|
+
end
|
73
|
+
test_val = { :WOM => 'BAT!' }.to_json
|
74
|
+
assert_equal test_val, output[2]
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_has_direct_relationships_to
|
78
|
+
env = Rack::MockRequest.env_for('/foo_bar/133/children/1', {
|
79
|
+
:method => 'GET'
|
80
|
+
})
|
81
|
+
output = ''
|
82
|
+
assert_nothing_raised do
|
83
|
+
output = @ws.call(env)
|
84
|
+
end
|
85
|
+
test_val = { :BAZA => 'YESSIR' }.to_json
|
86
|
+
assert_equal test_val, output[2]
|
87
|
+
|
88
|
+
env = Rack::MockRequest.env_for('/foo_bar/133/children/8', {
|
89
|
+
:method => 'GET'
|
90
|
+
})
|
91
|
+
output = ''
|
92
|
+
assert_nothing_raised do
|
93
|
+
output = @ws.call(env)
|
94
|
+
end
|
95
|
+
test_val = { :NOWAY => 'JOSE' }.to_json
|
96
|
+
assert_equal test_val, output[2]
|
97
|
+
|
98
|
+
env = Rack::MockRequest.env_for('/foo_bar/133/children/11', {
|
99
|
+
:method => 'GET'
|
100
|
+
})
|
101
|
+
output = ''
|
102
|
+
assert_nothing_raised do
|
103
|
+
output = @ws.call(env)
|
104
|
+
end
|
105
|
+
assert_equal 404, output[0]
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_has_mapped_relationships_to
|
109
|
+
env = Rack::MockRequest.env_for('/foo_bar/133/maps/first', {
|
110
|
+
:method => 'GET'
|
111
|
+
})
|
112
|
+
output = ''
|
113
|
+
assert_nothing_raised do
|
114
|
+
output = @ws.call(env)
|
115
|
+
end
|
116
|
+
test_val = '1'
|
117
|
+
assert_equal test_val, output[2]
|
118
|
+
|
119
|
+
env = Rack::MockRequest.env_for('/foo_bar/133/maps/second', {
|
120
|
+
:method => 'GET'
|
121
|
+
})
|
122
|
+
output = ''
|
123
|
+
assert_nothing_raised do
|
124
|
+
output = @ws.call(env)
|
125
|
+
end
|
126
|
+
test_val = '0'
|
127
|
+
assert_equal test_val, output[2]
|
128
|
+
|
129
|
+
env = Rack::MockRequest.env_for('/foo_bar/133/maps/third', {
|
130
|
+
:method => 'GET'
|
131
|
+
})
|
132
|
+
output = ''
|
133
|
+
assert_nothing_raised do
|
134
|
+
output = @ws.call(env)
|
135
|
+
end
|
136
|
+
test_val = '0'
|
137
|
+
assert_equal test_val, output[2]
|
138
|
+
end
|
139
|
+
|
140
|
+
def test_keyed_with_type
|
141
|
+
# baza controller exercises this option
|
142
|
+
env = Rack::MockRequest.env_for('/foo_bar/133/children/1', {
|
143
|
+
:method => 'GET'
|
144
|
+
})
|
145
|
+
output = ''
|
146
|
+
assert_nothing_raised do
|
147
|
+
output = @ws.call(env)
|
148
|
+
end
|
149
|
+
test_val = { :BAZA => 'YESSIR' }.to_json
|
150
|
+
assert_equal test_val, output[2]
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|