blindgaenger-sinatra-rest 0.2 → 0.3.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.
data/test/crud_spec.rb ADDED
@@ -0,0 +1,99 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ describe 'some use cases' do
4
+
5
+ def total_models
6
+ Person.all.size
7
+ end
8
+
9
+ require "rexml/document"
10
+ def doc(xml)
11
+ REXML::Document.new(xml.gsub(/>\s+</, '><').strip)
12
+ end
13
+
14
+ before(:each) do
15
+ Person.reset!
16
+ mock_rest Person
17
+ end
18
+
19
+ it 'should list all persons' do
20
+ get '/people'
21
+ normalized_response.should == [200, '<people><person><id>1</id></person><person><id>2</id></person><person><id>3</id></person></people>']
22
+ total_models.should == 3
23
+ end
24
+
25
+ it 'should create a new person' do
26
+ get '/people'
27
+ normalized_response.should == [200, '<people><person><id>1</id></person><person><id>2</id></person><person><id>3</id></person></people>']
28
+ total_models.should == 3
29
+
30
+ get '/people/new'
31
+ normalized_response.should == [200, '<person><id></id><name></name></person>']
32
+ total_models.should == 3
33
+
34
+ post '/people', {:name => 'four'}
35
+ normalized_response.should == [302, 'person created']
36
+ total_models.should == 4
37
+
38
+ get '/people'
39
+ normalized_response.should == [200, '<people><person><id>1</id></person><person><id>2</id></person><person><id>3</id></person><person><id>4</id></person></people>']
40
+ total_models.should == 4
41
+ end
42
+
43
+ it 'should read all persons' do
44
+ get '/people'
45
+
46
+ el_people = doc(body).elements.to_a("*/person/id")
47
+ el_people.size.should == 3
48
+ total_models.should == 3
49
+
50
+ get "/people/#{el_people[0].text}"
51
+ normalized_response.should == [200, '<person><id>1</id><name>one</name></person>']
52
+ total_models.should == 3
53
+
54
+ get "/people/#{el_people[1].text}"
55
+ normalized_response.should == [200, '<person><id>2</id><name>two</name></person>']
56
+ total_models.should == 3
57
+
58
+ get "/people/#{el_people[2].text}"
59
+ normalized_response.should == [200, '<person><id>3</id><name>three</name></person>']
60
+ total_models.should == 3
61
+
62
+ get "/people/99"
63
+ normalized_response.should == [404, 'route not found']
64
+ total_models.should == 3
65
+ end
66
+
67
+ it 'should update a person' do
68
+ get '/people/2'
69
+ normalized_response.should == [200, '<person><id>2</id><name>two</name></person>']
70
+ total_models.should == 3
71
+
72
+ put '/people/2', {:name => 'tomorrow'}
73
+ normalized_response.should == [302, 'person updated']
74
+ total_models.should == 3
75
+
76
+ get '/people/2'
77
+ normalized_response.should == [200, '<person><id>2</id><name>tomorrow</name></person>']
78
+ total_models.should == 3
79
+ end
80
+
81
+ it 'should destroy a person' do
82
+ get '/people'
83
+ normalized_response.should == [200, '<people><person><id>1</id></person><person><id>2</id></person><person><id>3</id></person></people>']
84
+ total_models.should == 3
85
+
86
+ delete '/people/2'
87
+ normalized_response.should == [302, 'person destroyed']
88
+ total_models.should == 2
89
+
90
+ get '/people'
91
+ normalized_response.should == [200, '<people><person><id>1</id></person><person><id>3</id></person></people>']
92
+ total_models.should == 2
93
+
94
+ get '/people/2'
95
+ normalized_response.should == [404, 'route not found']
96
+ total_models.should == 2
97
+ end
98
+
99
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,151 @@
1
+ require 'spec'
2
+ require 'spec/interop/test'
3
+ require 'sinatra/test'
4
+
5
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
6
+ require 'sinatra/base'
7
+ require 'sinatra/rest'
8
+
9
+ Sinatra::Default.set(:environment, :test)
10
+ Test::Unit::TestCase.send :include, Sinatra::Test
11
+
12
+ #
13
+ # Sets up a Sinatra::Base subclass defined with the block
14
+ # given. Used in setup or individual spec methods to establish
15
+ # the application.
16
+ def mock_app(&block)
17
+ base = Sinatra::Application
18
+ @app = Sinatra.new(base) do
19
+ set :views, File.dirname(__FILE__) + '/views'
20
+
21
+ not_found do
22
+ 'route not found'
23
+ end
24
+ end
25
+ @app.instance_eval(&block) if block_given?
26
+ end
27
+
28
+ #
29
+ # sets rest in a sinatra instance
30
+ # and returns the block's result, if a block is given
31
+ def mock_rest(model, options={}, &block)
32
+ mock_app {
33
+ rest model, options
34
+ }
35
+ instance = @app.new
36
+ instance.instance_eval(&block) if block_given?
37
+ end
38
+
39
+
40
+ #
41
+ # normalize for easier testing
42
+ def normalized_response
43
+ return status, body.gsub(/>\s+</, '><').strip
44
+ end
45
+
46
+ # index GET /models
47
+ def index(url)
48
+ get url
49
+ normalized_response
50
+ end
51
+
52
+ # new GET /models/new
53
+ def new(url)
54
+ get url
55
+ normalized_response
56
+ end
57
+
58
+ # create POST /models
59
+ def create(url, params={})
60
+ post url, params
61
+ normalized_response
62
+ end
63
+
64
+ # show GET /models/1
65
+ def show(url)
66
+ get url
67
+ normalized_response
68
+ end
69
+
70
+ # edit GET /models/1/edit
71
+ def edit(url)
72
+ get url
73
+ normalized_response
74
+ end
75
+
76
+ # update PUT /models/1
77
+ def update(url, params={})
78
+ put url, params
79
+ normalized_response
80
+ end
81
+
82
+ # destroy DELETE /models/1
83
+ def destroy(url)
84
+ delete url
85
+ normalized_response
86
+ end
87
+
88
+
89
+ ##
90
+ ## kind of a 'minimal model'
91
+ class Person
92
+ attr_accessor :id
93
+ attr_accessor :name
94
+
95
+ def initialize(*args)
96
+ #puts "new #{args.inspect}"
97
+ if args.size == 0
98
+ @id = nil
99
+ @name = nil
100
+ elsif args.size == 2
101
+ @id = args[0].to_i
102
+ @name = args[1]
103
+ else args.size == 1
104
+ update_attributes(args[0])
105
+ end
106
+ end
107
+
108
+ def save
109
+ #puts "save #{@id}"
110
+ @@people << self
111
+ self.id = @@people.size
112
+ end
113
+
114
+ def update_attributes(hash)
115
+ #puts "update_attributes #{hash.inspect}"
116
+ unless hash.empty?
117
+ @id = hash['id'].to_i if hash.include?('id')
118
+ @name = hash['name'] if hash.include?('name')
119
+ end
120
+ end
121
+
122
+ def self.delete(id)
123
+ #puts "delete #{id}"
124
+ @@people.delete_if {|person| person.id == id.to_i}
125
+ end
126
+
127
+ @@people = []
128
+
129
+ def self.all(criteria={})
130
+ #puts 'all'
131
+ return @@people
132
+ end
133
+
134
+ def self.find_by_id(id)
135
+ #puts "find_by_id #{id}"
136
+ all.find {|f| f.id == id.to_i}
137
+ end
138
+
139
+ def self.clear!
140
+ @@people = []
141
+ end
142
+
143
+ def self.reset!
144
+ clear!
145
+ Person.new(1, 'one').save
146
+ Person.new(2, 'two').save
147
+ Person.new(3, 'three').save
148
+ end
149
+ end
150
+
151
+
@@ -0,0 +1,76 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ describe 'url helpers' do
4
+
5
+ it 'should generate the correct urls for the model' do
6
+ mock_rest Person do
7
+ person = Person.new(99, 'foo')
8
+ url_for_people_create.should == '/people'
9
+ url_for_people_destroy(person).should == '/people/99'
10
+ url_for_people_edit(person).should == '/people/99/edit'
11
+ url_for_people_index.should == '/people'
12
+ url_for_people_new.should == '/people/new'
13
+ url_for_people_show(person).should == '/people/99'
14
+ url_for_people_update(person).should == '/people/99'
15
+ end
16
+ end
17
+
18
+ it 'should add :all helpers' do
19
+ mock_rest(Person) { methods.grep(/^url_for_people_/).sort }.should == [
20
+ "url_for_people_create",
21
+ "url_for_people_destroy",
22
+ "url_for_people_edit",
23
+ "url_for_people_index",
24
+ "url_for_people_new",
25
+ "url_for_people_show",
26
+ "url_for_people_update",
27
+ ]
28
+ end
29
+
30
+ it 'should add :readable helpers' do
31
+ mock_rest(Person, :routes => :readable) { methods.grep(/^url_for_people_/).sort }.should == [
32
+ "url_for_people_index",
33
+ "url_for_people_show",
34
+ ]
35
+ end
36
+
37
+ it 'should add :writeable helpers' do
38
+ mock_rest(Person, :routes => :writeable) { methods.grep(/^url_for_people_/).sort }.should == [
39
+ "url_for_people_create",
40
+ "url_for_people_destroy",
41
+ "url_for_people_index",
42
+ "url_for_people_show",
43
+ "url_for_people_update",
44
+ ]
45
+ end
46
+
47
+ it 'should add :editable helpers' do
48
+ mock_rest(Person, :routes => :editable) { methods.grep(/^url_for_people_/).sort }.should == [
49
+ "url_for_people_create",
50
+ "url_for_people_destroy",
51
+ "url_for_people_edit",
52
+ "url_for_people_index",
53
+ "url_for_people_new",
54
+ "url_for_people_show",
55
+ "url_for_people_update",
56
+ ]
57
+ end
58
+
59
+ it 'should add helpers by name' do
60
+ mock_rest(Person, :routes => [:new, :create, :destroy]) { methods.grep(/^url_for_people_/).sort }.should == [
61
+ "url_for_people_create",
62
+ "url_for_people_destroy",
63
+ "url_for_people_new",
64
+ ]
65
+ end
66
+
67
+ it 'should add helpers by mixing aliases and names' do
68
+ mock_rest(Person, :routes => [:readable, :create, :destroy]) { methods.grep(/^url_for_people_/).sort }.should == [
69
+ "url_for_people_create",
70
+ "url_for_people_destroy",
71
+ "url_for_people_index",
72
+ "url_for_people_show",
73
+ ]
74
+ end
75
+
76
+ end
@@ -0,0 +1,29 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ describe 'model inflection' do
4
+
5
+ def conjugate(model)
6
+ mock_app {
7
+ include Sinatra::REST
8
+ conjugate(model)
9
+ }
10
+ end
11
+
12
+ it "should conjugate a simple model name" do
13
+ conjugate(Person).should == %w(Person person people)
14
+ end
15
+
16
+ it "should conjugate a String as model name" do
17
+ conjugate('Person').should == %w(Person person people)
18
+ end
19
+
20
+ it "should conjugate a model name in camel cases" do
21
+ conjugate('SomePerson').should == %w(SomePerson some_person some_people)
22
+ end
23
+
24
+ it "should conjugate a model name without module" do
25
+ conjugate('MyModule::ModulePerson').should == %w(ModulePerson module_person module_people)
26
+ end
27
+
28
+ end
29
+
@@ -0,0 +1,112 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ describe 'routes' do
4
+
5
+ before(:each) do
6
+ Person.reset!
7
+ end
8
+
9
+ describe 'one by one' do
10
+
11
+ before(:each) do
12
+ mock_rest Person
13
+ end
14
+
15
+ it 'should list all people on index by their id' do
16
+ index('/people').should == [200, '<people><person><id>1</id></person><person><id>2</id></person><person><id>3</id></person></people>']
17
+ end
18
+
19
+ it 'should prepare an empty item on new' do
20
+ new('/people/new').should == [200, '<person><id></id><name></name></person>']
21
+ end
22
+
23
+ it 'should create an item on post' do
24
+ create('/people', :name => 'new resource').should == [302, 'person created']
25
+ end
26
+
27
+ it 'should show an item on get' do
28
+ show('/people/1').should == [200, '<person><id>1</id><name>one</name></person>']
29
+ end
30
+
31
+ it 'should get the item for editing' do
32
+ edit('/people/1/edit').should == [200, '<person><id>1</id><name>one</name></person>']
33
+ end
34
+
35
+ it 'should update an item on put' do
36
+ update('/people/1', :name => 'another name').should == [302, 'person updated']
37
+ end
38
+
39
+ it 'should destroy an item on delete' do
40
+ destroy('/people/1').should == [302, 'person destroyed']
41
+ end
42
+
43
+ end
44
+
45
+ describe 'options' do
46
+
47
+ it 'should add :all routes' do
48
+ mock_rest Person
49
+
50
+ index('/people').should == [200, '<people><person><id>1</id></person><person><id>2</id></person><person><id>3</id></person></people>']
51
+ new('/people/new').should == [200, '<person><id></id><name></name></person>']
52
+ create('/people', :name => 'new person').should == [302, "person created"]
53
+ show('/people/1').should == [200, '<person><id>1</id><name>one</name></person>']
54
+ edit('/people/1/edit').should == [200, "<person><id>1</id><name>one</name></person>"]
55
+ update('/people/1', :name => 'new name').should == [302, "person updated"]
56
+ destroy('/people/1').should == [302, "person destroyed"]
57
+ end
58
+
59
+ it 'should add :readable routes' do
60
+ mock_rest Person, :routes => :readable
61
+
62
+ index('/people').should == [200, '<people><person><id>1</id></person><person><id>2</id></person><person><id>3</id></person></people>']
63
+ show('/people/1').should == [200, '<person><id>1</id><name>one</name></person>']
64
+
65
+ new('/people/new').should == [404, "route not found"]
66
+ create('/people', :name => 'new person').should == [404, "route not found"]
67
+ edit('/people/1/edit').should == [404, "route not found"]
68
+ update('/people/1', :name => 'new name').should == [404, "route not found"]
69
+ destroy('/people/1').should == [404, "route not found"]
70
+ end
71
+
72
+ it 'should add :writeable routes' do
73
+ mock_rest Person, :routes => :writeable
74
+
75
+ index('/people').should == [200, '<people><person><id>1</id></person><person><id>2</id></person><person><id>3</id></person></people>']
76
+ show('/people/1').should == [200, '<person><id>1</id><name>one</name></person>']
77
+ create('/people', :name => 'new person').should == [302, "person created"]
78
+ update('/people/1', :name => 'new name').should == [302, "person updated"]
79
+ destroy('/people/1').should == [302, "person destroyed"]
80
+
81
+ new('/people/new').should == [404, "route not found"]
82
+ edit('/people/1/edit').should == [404, "route not found"]
83
+ end
84
+
85
+ it 'should add :editable routes' do
86
+ mock_rest Person, :routes => :editable
87
+
88
+ index('/people').should == [200, '<people><person><id>1</id></person><person><id>2</id></person><person><id>3</id></person></people>']
89
+ new('/people/new').should == [200, '<person><id></id><name></name></person>']
90
+ create('/people', :name => 'new person').should == [302, "person created"]
91
+ show('/people/1').should == [200, '<person><id>1</id><name>one</name></person>']
92
+ edit('/people/1/edit').should == [200, "<person><id>1</id><name>one</name></person>"]
93
+ update('/people/1', :name => 'new name').should == [302, "person updated"]
94
+ destroy('/people/1').should == [302, "person destroyed"]
95
+ end
96
+
97
+ it 'should add routes by name' do
98
+ mock_rest Person, :routes => [:readable, :new, :create]
99
+
100
+ index('/people').should == [200, '<people><person><id>1</id></person><person><id>2</id></person><person><id>3</id></person></people>']
101
+ show('/people/1').should == [200, '<person><id>1</id><name>one</name></person>']
102
+ new('/people/new').should == [200, '<person><id></id><name></name></person>']
103
+ create('/people', :name => 'new person').should == [302, "person created"]
104
+
105
+ edit('/people/1/edit').should == [404, "route not found"]
106
+ update('/people/1', :name => 'new name').should == [404, "route not found"]
107
+ destroy('/people/1').should == [404, "route not found"]
108
+ end
109
+
110
+ end
111
+
112
+ end