sinatra-backbone 0.1.0.rc1 → 0.1.0.rc2
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/HISTORY.md +9 -0
- data/examples/restapi/app.rb +40 -0
- data/examples/restapi/config.ru +3 -0
- data/examples/restapi/home.erb +24 -0
- data/examples/restapi/public/app.js +105 -0
- data/lib/sinatra/backbone.rb +1 -2
- data/lib/sinatra/jstpages.rb +1 -1
- data/lib/sinatra/restapi.rb +98 -10
- data/sinatra-backbone.gemspec +1 -0
- data/test/app_test.rb +12 -0
- data/test/arity_test.rb +43 -0
- data/test/emulate_test.rb +30 -0
- data/test/test_helper.rb +1 -0
- metadata +28 -11
data/HISTORY.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
v0.1.0.rc2 - Sep 12, 2011
|
2
|
+
-------------------------
|
3
|
+
|
4
|
+
### Changed:
|
5
|
+
* Check for validity of models on the server, and add an example.
|
6
|
+
* Added examples in the documentation.
|
7
|
+
* Support multiple args in routes.
|
8
|
+
* Added more tests.
|
9
|
+
|
1
10
|
v0.1.0.rc1 - Sept 12, 2011
|
2
11
|
--------------------------
|
3
12
|
|
@@ -0,0 +1,40 @@
|
|
1
|
+
$:.unshift File.expand_path('../../lib', __FILE__)
|
2
|
+
|
3
|
+
require 'sinatra/base'
|
4
|
+
require 'sequel'
|
5
|
+
require 'sinatra/backbone'
|
6
|
+
|
7
|
+
DB = Sequel.connect("sqlite::memory:")
|
8
|
+
DB.create_table :books do
|
9
|
+
primary_key :id
|
10
|
+
String :title
|
11
|
+
String :author
|
12
|
+
end
|
13
|
+
|
14
|
+
class Book < Sequel::Model
|
15
|
+
def to_hash
|
16
|
+
{ :id => id, :title => title, :author => author }
|
17
|
+
end
|
18
|
+
|
19
|
+
def validate
|
20
|
+
errors.add :author, "can't be empty" if author.to_s.size == 0
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class App < Sinatra::Base
|
25
|
+
enable :raise_errors, :logging
|
26
|
+
enable :show_exceptions if development?
|
27
|
+
|
28
|
+
register Sinatra::RestAPI
|
29
|
+
|
30
|
+
rest_create("/book") { Book.new }
|
31
|
+
rest_resource("/book/:id") { |id| Book[id] }
|
32
|
+
|
33
|
+
set :root, File.expand_path('../', __FILE__)
|
34
|
+
set :views, File.expand_path('../', __FILE__)
|
35
|
+
set :public, File.expand_path('../public', __FILE__)
|
36
|
+
|
37
|
+
get '/' do
|
38
|
+
erb :home
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en">
|
3
|
+
<head>
|
4
|
+
<meta charset="UTF-8" />
|
5
|
+
<title></title>
|
6
|
+
<script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/1.6.2/jquery.min.js'></script>
|
7
|
+
<script src='http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.1.7/underscore-min.js'></script>
|
8
|
+
<script src='http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.5.3/backbone-min.js'></script>
|
9
|
+
<style>
|
10
|
+
body { font-family: sans-serif; font-size: 13px; line-height: 1.5; background: #d0d0da; }
|
11
|
+
#messages { width: 400px; margin: 20px auto; background: white; padding: 20px; border: solid 10px #c0c0ca; }
|
12
|
+
h3 { border-top: dotted 1px #ccc; padding: 20px 20px 0 20px; margin: 20px -20px 0 -20px; color: #46a; }
|
13
|
+
h3:first-child { border-top: 0; margin-top: 0; padding-top: 0; }
|
14
|
+
dl { overflow: hidden; }
|
15
|
+
dt { float: left; width: 120px; margin-right: 10px; text-align: right; color: #aaa; }
|
16
|
+
h3 { font-family: palatino; font-size: 1.3em; }
|
17
|
+
</style>
|
18
|
+
</head>
|
19
|
+
<body>
|
20
|
+
<div id="messages">
|
21
|
+
</div>
|
22
|
+
<script src='app.js'></script>
|
23
|
+
</body>
|
24
|
+
</html>
|
@@ -0,0 +1,105 @@
|
|
1
|
+
// Here is our Backbone model!
|
2
|
+
Book = Backbone.Model.extend({
|
3
|
+
urlRoot: '/book'
|
4
|
+
});
|
5
|
+
|
6
|
+
$(function() {
|
7
|
+
do_create();
|
8
|
+
});
|
9
|
+
|
10
|
+
function do_create() {
|
11
|
+
echo("<h3>Creating a book:</h3>");
|
12
|
+
|
13
|
+
var book = new Book;
|
14
|
+
book.set({ title: "Darkly Dreaming Dexter", author: "Jeff Lindsay" });
|
15
|
+
book.save({}, {
|
16
|
+
error: onerror,
|
17
|
+
success: function() {
|
18
|
+
print_book(book);
|
19
|
+
echo("<h3>Retrieving the same book:</h3>");
|
20
|
+
do_retrieve(book);
|
21
|
+
}
|
22
|
+
});
|
23
|
+
}
|
24
|
+
|
25
|
+
function do_retrieve(_book) {
|
26
|
+
var book = new Book({ id: _book.id });
|
27
|
+
book.fetch({
|
28
|
+
error: onerror,
|
29
|
+
success: function() {
|
30
|
+
print_book(book);
|
31
|
+
do_edit_error(book);
|
32
|
+
}
|
33
|
+
});
|
34
|
+
}
|
35
|
+
|
36
|
+
function do_edit_error(book) {
|
37
|
+
echo("<h3>Editing book with an error:</h3>");
|
38
|
+
console.log("(You should see an HTTP error right about here:)");
|
39
|
+
book.set({ author: '' });
|
40
|
+
book.save({}, {
|
41
|
+
success: onerror,
|
42
|
+
error: function() {
|
43
|
+
console.log("(...yep.)");
|
44
|
+
echo("...yes, it occured.");
|
45
|
+
do_edit(book);
|
46
|
+
}
|
47
|
+
});
|
48
|
+
}
|
49
|
+
|
50
|
+
function do_edit(book) {
|
51
|
+
echo("<h3>Editing book:</h3>");
|
52
|
+
book.set({ author: 'Anne Rice', title: 'The Claiming of Sleeping Beauty' });
|
53
|
+
book.save({}, {
|
54
|
+
error: onerror,
|
55
|
+
success: function() {
|
56
|
+
print_book(book);
|
57
|
+
do_delete(book);
|
58
|
+
}
|
59
|
+
});
|
60
|
+
}
|
61
|
+
|
62
|
+
function do_delete(book) {
|
63
|
+
echo("<h3>Deleting book:</h3>");
|
64
|
+
book.destroy({
|
65
|
+
error: onerror,
|
66
|
+
success: function() {
|
67
|
+
echo("Success.");
|
68
|
+
do_verify_delete(book.id);
|
69
|
+
}
|
70
|
+
});
|
71
|
+
}
|
72
|
+
|
73
|
+
function do_verify_delete(id) {
|
74
|
+
echo("<h3>Checking if book "+id+" still exists:</h3>");
|
75
|
+
console.log("(You should see an HTTP error right about here:)");
|
76
|
+
var book = new Book({ id: id });
|
77
|
+
book.fetch({
|
78
|
+
success: onerror,
|
79
|
+
error: function() {
|
80
|
+
console.log("(...yep.)");
|
81
|
+
echo("No, it doesn't.");
|
82
|
+
do_success();
|
83
|
+
}
|
84
|
+
});
|
85
|
+
}
|
86
|
+
|
87
|
+
function do_success() {
|
88
|
+
echo("<h3>Success!</h3>");
|
89
|
+
}
|
90
|
+
|
91
|
+
function print_book(book) {
|
92
|
+
echo("<dl><dt>Title:</dt><dd>"+book.get('title')+"</dd></dl>");
|
93
|
+
echo("<dl><dt>Author:</dt><dd>"+book.get('author')+"</dd></dl>");
|
94
|
+
echo("<dl><dt>ID:</dt><dd>"+book.get('id')+"</dd></dl>");
|
95
|
+
}
|
96
|
+
|
97
|
+
// Helper functions
|
98
|
+
function echo(html) {
|
99
|
+
$("#messages").append(html);
|
100
|
+
};
|
101
|
+
|
102
|
+
function onerror() {
|
103
|
+
echo("<p class='error'>Oops... an error occured.</p>");
|
104
|
+
};
|
105
|
+
|
data/lib/sinatra/backbone.rb
CHANGED
data/lib/sinatra/jstpages.rb
CHANGED
data/lib/sinatra/restapi.rb
CHANGED
@@ -12,6 +12,86 @@ require 'json'
|
|
12
12
|
# register Sinatra::RestAPI
|
13
13
|
# end
|
14
14
|
#
|
15
|
+
# ### RestAPI example
|
16
|
+
# Here's a simple example of how to use Backbone models with RestAPI.
|
17
|
+
# Also see the [example application][ex] included in the gem.
|
18
|
+
#
|
19
|
+
# [ex]: https://github.com/rstacruz/sinatra-backbone/tree/master/examples/restapi
|
20
|
+
#
|
21
|
+
# #### Model setup
|
22
|
+
# Let's say you have a `Book` model in your application. Let's use [Sequel][sq]
|
23
|
+
# for this example, but feel free to use any other ORM that is
|
24
|
+
# ActiveModel-compatible.
|
25
|
+
#
|
26
|
+
# You will need to define `to_hash` in your model.
|
27
|
+
#
|
28
|
+
# db = Sequel.connect(...)
|
29
|
+
#
|
30
|
+
# db.create_table :books do
|
31
|
+
# primary_key :id
|
32
|
+
# String :title
|
33
|
+
# String :author
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# class Book < Sequel::Model
|
37
|
+
# # ...
|
38
|
+
# def to_hash
|
39
|
+
# { :title => title, :author => author, :id => id }
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# [sq]: http://sequel.rubyforge.org
|
44
|
+
#
|
45
|
+
# #### Sinatra
|
46
|
+
# To provide some routes for Backbone models, use `rest_resource` and
|
47
|
+
# `rest_create`:
|
48
|
+
#
|
49
|
+
# require 'sinatra/restapi'
|
50
|
+
#
|
51
|
+
# class App < Sinatra::Base
|
52
|
+
# register Sinatra::RestAPI
|
53
|
+
#
|
54
|
+
# rest_create '/book' do
|
55
|
+
# Book.new
|
56
|
+
# end
|
57
|
+
#
|
58
|
+
# rest_resource '/book/:id' do |id|
|
59
|
+
# Book.find(:id => id)
|
60
|
+
# end
|
61
|
+
# end
|
62
|
+
#
|
63
|
+
# #### JavaScript
|
64
|
+
# In your JavaScript files, let's make a corresponding model.
|
65
|
+
#
|
66
|
+
# Book = Backbone.Model.extend({
|
67
|
+
# urlRoot: '/book'
|
68
|
+
# });
|
69
|
+
#
|
70
|
+
# Now you may create a new book through your JavaScript:
|
71
|
+
#
|
72
|
+
# book = new Book;
|
73
|
+
# book.set({ title: "Darkly Dreaming Dexter", author: "Jeff Lindsay" });
|
74
|
+
# book.save();
|
75
|
+
#
|
76
|
+
# // In Ruby, equivalent to:
|
77
|
+
# // book = Book.new
|
78
|
+
# // book.title = "Darkly Dreaming Dexter"
|
79
|
+
# // book.author = "Jeff Lindsay"
|
80
|
+
# // book.save
|
81
|
+
#
|
82
|
+
# Or you may retrieve new items. Note that in this example, since we defined
|
83
|
+
# `urlRoot()` but not `url()`, the model URL with default to `/[urlRoot]/[id]`.
|
84
|
+
#
|
85
|
+
# book = new Book({ id: 1 });
|
86
|
+
# book.fetch();
|
87
|
+
#
|
88
|
+
# // In Ruby, equivalent to:
|
89
|
+
# // Book.find(:id => 1)
|
90
|
+
#
|
91
|
+
# Deletes will work just like how you would expect it:
|
92
|
+
#
|
93
|
+
# book.destroy();
|
94
|
+
#
|
15
95
|
module Sinatra::RestAPI
|
16
96
|
def self.registered(app)
|
17
97
|
app.helpers Helpers
|
@@ -32,7 +112,9 @@ module Sinatra::RestAPI
|
|
32
112
|
# your record. For instance, for an attrib like `title`, it wil lbe
|
33
113
|
# calling `object.title = "hello"`.
|
34
114
|
#
|
35
|
-
# * `object.
|
115
|
+
# * if `object.valid?` returns false, it returns an error 400.
|
116
|
+
#
|
117
|
+
# * `object.save` will then be called.
|
36
118
|
#
|
37
119
|
# * `object`'s contents will then be returned to the client as JSON.
|
38
120
|
#
|
@@ -49,6 +131,9 @@ module Sinatra::RestAPI
|
|
49
131
|
post path do
|
50
132
|
@object = yield
|
51
133
|
rest_params.each { |k, v| @object.send :"#{k}=", v }
|
134
|
+
|
135
|
+
return 400, @object.errors.to_json unless @object.valid?
|
136
|
+
|
52
137
|
@object.save
|
53
138
|
rest_respond @object.to_hash
|
54
139
|
end
|
@@ -79,8 +164,8 @@ module Sinatra::RestAPI
|
|
79
164
|
# All the methods above take the same arguments as `rest_resource`.
|
80
165
|
#
|
81
166
|
# class App < Sinatra::Base
|
82
|
-
# rest_resource "/document/:id" do
|
83
|
-
# Document.find(id)
|
167
|
+
# rest_resource "/document/:id" do |id|
|
168
|
+
# Document.find(:id => id)
|
84
169
|
# end
|
85
170
|
# end
|
86
171
|
#
|
@@ -94,8 +179,8 @@ module Sinatra::RestAPI
|
|
94
179
|
# This is the same as `rest_resource`, but only handles *GET* requests.
|
95
180
|
#
|
96
181
|
def rest_get(path, options={}, &blk)
|
97
|
-
get path do |
|
98
|
-
@object = yield(
|
182
|
+
get path do |*args|
|
183
|
+
@object = yield(*args) or pass
|
99
184
|
rest_respond @object
|
100
185
|
end
|
101
186
|
end
|
@@ -105,9 +190,12 @@ module Sinatra::RestAPI
|
|
105
190
|
# requests.
|
106
191
|
#
|
107
192
|
def rest_edit(path, options={}, &blk)
|
108
|
-
callback = Proc.new { |
|
109
|
-
@object = yield(
|
193
|
+
callback = Proc.new { |*args|
|
194
|
+
@object = yield(*args) or pass
|
110
195
|
rest_params.each { |k, v| @object.send :"#{k}=", v unless k == 'id' }
|
196
|
+
|
197
|
+
return 400, @object.errors.to_json unless @object.valid?
|
198
|
+
|
111
199
|
@object.save
|
112
200
|
rest_respond @object
|
113
201
|
}
|
@@ -122,8 +210,8 @@ module Sinatra::RestAPI
|
|
122
210
|
# requests. This uses `Model#destroy` on your model.
|
123
211
|
#
|
124
212
|
def rest_delete(path, options={}, &blk)
|
125
|
-
delete path do |
|
126
|
-
@object = yield(
|
213
|
+
delete path do |*args|
|
214
|
+
@object = yield(*args) or pass
|
127
215
|
@object.destroy
|
128
216
|
rest_respond :result => :success
|
129
217
|
end
|
@@ -167,7 +255,7 @@ module Sinatra::RestAPI
|
|
167
255
|
#
|
168
256
|
# If the client sent a standard URL-encoded POST with a `model` key
|
169
257
|
# (happens when Backbone uses `Backbone.emulateJSON = true`), it tries
|
170
|
-
# to parse
|
258
|
+
# to parse its value as JSON.
|
171
259
|
#
|
172
260
|
# Otherwise, the params will be returned as is.
|
173
261
|
#
|
data/sinatra-backbone.gemspec
CHANGED
@@ -14,5 +14,6 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.add_development_dependency "sequel", ">= 3.25.0"
|
15
15
|
s.add_development_dependency "sqlite3", ">= 1.3.4"
|
16
16
|
s.add_development_dependency "contest"
|
17
|
+
s.add_development_dependency "mocha"
|
17
18
|
s.add_development_dependency "rack-test"
|
18
19
|
end
|
data/test/app_test.rb
CHANGED
@@ -10,6 +10,11 @@ class Book < Sequel::Model
|
|
10
10
|
def to_hash
|
11
11
|
{ :name => name, :author => author }
|
12
12
|
end
|
13
|
+
|
14
|
+
def validate
|
15
|
+
super
|
16
|
+
errors.add(:author, "can't be empty") if author.to_s.size == 0
|
17
|
+
end
|
13
18
|
end
|
14
19
|
|
15
20
|
class AppTest < UnitTest
|
@@ -17,6 +22,7 @@ class AppTest < UnitTest
|
|
17
22
|
register Sinatra::RestAPI
|
18
23
|
disable :show_exceptions
|
19
24
|
enable :raise_errors
|
25
|
+
rest_create("/book") { Book.new }
|
20
26
|
rest_resource("/book/:id") { |id| Book[id] }
|
21
27
|
end
|
22
28
|
def app() App; end
|
@@ -41,6 +47,12 @@ class AppTest < UnitTest
|
|
41
47
|
assert json_response['author'] == @book.author
|
42
48
|
end
|
43
49
|
|
50
|
+
test "validation fail" do
|
51
|
+
hash = { :name => "The Claiming of Sleeping Beauty" }
|
52
|
+
post "/book", :model => hash.to_json
|
53
|
+
p last_response
|
54
|
+
end
|
55
|
+
|
44
56
|
test "should 404" do
|
45
57
|
get "/book/823978"
|
46
58
|
|
data/test/arity_test.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require File.expand_path('../test_helper', __FILE__)
|
2
|
+
|
3
|
+
class ArityTest < UnitTest
|
4
|
+
class FauxModel
|
5
|
+
def initialize(stuff)
|
6
|
+
@stuff = stuff
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_hash
|
10
|
+
{ :contents => @stuff }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class App < Sinatra::Base
|
15
|
+
register Sinatra::RestAPI
|
16
|
+
disable :show_exceptions
|
17
|
+
enable :raise_errors
|
18
|
+
|
19
|
+
rest_resource("/api/:x/:y/:z") { |x, y, z| FauxModel.new ["Hello", x.to_i+1, y.to_i+1, z.to_i+1] }
|
20
|
+
end
|
21
|
+
|
22
|
+
def app() App; end
|
23
|
+
|
24
|
+
describe "Multi args support" do
|
25
|
+
test "get" do
|
26
|
+
header 'Accept', 'application/json, */*'
|
27
|
+
get "/api/20/40/60"
|
28
|
+
|
29
|
+
assert json_response["contents"] = ["Hello", 21, 41, 61]
|
30
|
+
end
|
31
|
+
|
32
|
+
test "put/post" do
|
33
|
+
FauxModel.any_instance.expects(:x=).times(1).returns(true)
|
34
|
+
FauxModel.any_instance.expects(:save).times(1).returns(true)
|
35
|
+
|
36
|
+
header 'Accept', 'application/json, */*'
|
37
|
+
header 'Content-Type', 'application/json'
|
38
|
+
post "/api/20/40/60", JSON.generate('x' => 2)
|
39
|
+
|
40
|
+
assert json_response["contents"] = ["Hello", 21, 41, 61]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require File.expand_path('../test_helper', __FILE__)
|
2
|
+
|
3
|
+
class EmulateTest < UnitTest
|
4
|
+
class App < Sinatra::Base
|
5
|
+
register Sinatra::RestAPI
|
6
|
+
disable :show_exceptions
|
7
|
+
enable :raise_errors
|
8
|
+
|
9
|
+
rest_resource("/api/:id") { |id| FauxModel.new id }
|
10
|
+
end
|
11
|
+
|
12
|
+
def app() App; end
|
13
|
+
|
14
|
+
setup do
|
15
|
+
header 'Accept', 'application/json, */*'
|
16
|
+
end
|
17
|
+
|
18
|
+
test "emulate json and emulate http" do
|
19
|
+
FauxModel.any_instance.expects(:two=).times(1).returns(true)
|
20
|
+
FauxModel.any_instance.expects(:save).times(1).returns(true)
|
21
|
+
FauxModel.any_instance.expects(:to_hash).times(1).returns('a' => 'b')
|
22
|
+
|
23
|
+
post "/api/2", :model => { :two => 2 }.to_json
|
24
|
+
assert json_response == { 'a' => 'b' }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class FauxModel
|
29
|
+
end
|
30
|
+
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sinatra-backbone
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.0.
|
4
|
+
version: 0.1.0.rc2
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -14,7 +14,7 @@ default_executable:
|
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: sinatra
|
17
|
-
requirement: &
|
17
|
+
requirement: &2165346540 !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ! '>='
|
@@ -22,10 +22,10 @@ dependencies:
|
|
22
22
|
version: '0'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
|
-
version_requirements: *
|
25
|
+
version_requirements: *2165346540
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: sequel
|
28
|
-
requirement: &
|
28
|
+
requirement: &2165345800 !ruby/object:Gem::Requirement
|
29
29
|
none: false
|
30
30
|
requirements:
|
31
31
|
- - ! '>='
|
@@ -33,10 +33,10 @@ dependencies:
|
|
33
33
|
version: 3.25.0
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
|
-
version_requirements: *
|
36
|
+
version_requirements: *2165345800
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
name: sqlite3
|
39
|
-
requirement: &
|
39
|
+
requirement: &2165345140 !ruby/object:Gem::Requirement
|
40
40
|
none: false
|
41
41
|
requirements:
|
42
42
|
- - ! '>='
|
@@ -44,10 +44,10 @@ dependencies:
|
|
44
44
|
version: 1.3.4
|
45
45
|
type: :development
|
46
46
|
prerelease: false
|
47
|
-
version_requirements: *
|
47
|
+
version_requirements: *2165345140
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
49
|
name: contest
|
50
|
-
requirement: &
|
50
|
+
requirement: &2165344580 !ruby/object:Gem::Requirement
|
51
51
|
none: false
|
52
52
|
requirements:
|
53
53
|
- - ! '>='
|
@@ -55,10 +55,21 @@ dependencies:
|
|
55
55
|
version: '0'
|
56
56
|
type: :development
|
57
57
|
prerelease: false
|
58
|
-
version_requirements: *
|
58
|
+
version_requirements: *2165344580
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: mocha
|
61
|
+
requirement: &2165343740 !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ! '>='
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
type: :development
|
68
|
+
prerelease: false
|
69
|
+
version_requirements: *2165343740
|
59
70
|
- !ruby/object:Gem::Dependency
|
60
71
|
name: rack-test
|
61
|
-
requirement: &
|
72
|
+
requirement: &2165343140 !ruby/object:Gem::Requirement
|
62
73
|
none: false
|
63
74
|
requirements:
|
64
75
|
- - ! '>='
|
@@ -66,7 +77,7 @@ dependencies:
|
|
66
77
|
version: '0'
|
67
78
|
type: :development
|
68
79
|
prerelease: false
|
69
|
-
version_requirements: *
|
80
|
+
version_requirements: *2165343140
|
70
81
|
description: Provides Rest API access to your models and serves JST pages.
|
71
82
|
email:
|
72
83
|
- rico@sinefunc.com
|
@@ -78,6 +89,10 @@ files:
|
|
78
89
|
- HISTORY.md
|
79
90
|
- README.md
|
80
91
|
- Rakefile
|
92
|
+
- examples/restapi/app.rb
|
93
|
+
- examples/restapi/config.ru
|
94
|
+
- examples/restapi/home.erb
|
95
|
+
- examples/restapi/public/app.js
|
81
96
|
- lib/sinatra/backbone.rb
|
82
97
|
- lib/sinatra/jstpages.rb
|
83
98
|
- lib/sinatra/restapi.rb
|
@@ -85,6 +100,8 @@ files:
|
|
85
100
|
- test/app/views/chrome.jst.tpl
|
86
101
|
- test/app/views/editor/edit.jst.jade
|
87
102
|
- test/app_test.rb
|
103
|
+
- test/arity_test.rb
|
104
|
+
- test/emulate_test.rb
|
88
105
|
- test/jst_test.rb
|
89
106
|
- test/test_helper.rb
|
90
107
|
- test/to_json_test.rb
|