blindgaenger-sinatra-rest 0.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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