ki 0.1.2 → 0.2.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/VERSION +1 -1
- data/examples/base/Gemfile +2 -0
- data/examples/northpole.ro/Gemfile +3 -0
- data/examples/northpole.ro/Gemfile.lock +34 -0
- data/examples/northpole.ro/app.rb +40 -0
- data/examples/northpole.ro/config.ru +6 -0
- data/examples/northpole.ro/config.yml +3 -0
- data/examples/northpole.ro/views/index.haml +0 -0
- data/ki.gemspec +11 -3
- data/lib/db.rb +1 -0
- data/lib/model.rb +18 -14
- data/lib/modules/callbacks.rb +6 -0
- data/lib/modules/model_helpers.rb +43 -0
- data/lib/modules/query_interface.rb +5 -1
- data/lib/modules/restrictions.rb +12 -11
- data/spec/db_spec.rb +9 -1
- data/spec/integration/integration_spec.rb +114 -0
- data/spec/model_spec.rb +1 -7
- data/spec/modules/callbacks_spec.rb +12 -1
- data/spec/modules/query_interface_spec.rb +15 -0
- data/spec/modules/restrictions_spec.rb +27 -3
- data/spec/spec_helper.rb +16 -0
- metadata +38 -95
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/examples/base/Gemfile
CHANGED
@@ -0,0 +1,34 @@
|
|
1
|
+
PATH
|
2
|
+
remote: ../../
|
3
|
+
specs:
|
4
|
+
ki (0.1.2)
|
5
|
+
bson_ext
|
6
|
+
haml
|
7
|
+
mongo
|
8
|
+
rack
|
9
|
+
thin
|
10
|
+
thor
|
11
|
+
|
12
|
+
GEM
|
13
|
+
remote: https://rubygems.org/
|
14
|
+
specs:
|
15
|
+
bson (1.8.2)
|
16
|
+
bson_ext (1.8.2)
|
17
|
+
bson (~> 1.8.2)
|
18
|
+
daemons (1.1.9)
|
19
|
+
eventmachine (1.0.0)
|
20
|
+
haml (3.1.7)
|
21
|
+
mongo (1.8.2)
|
22
|
+
bson (~> 1.8.2)
|
23
|
+
rack (1.5.2)
|
24
|
+
thin (1.5.0)
|
25
|
+
daemons (>= 1.0.9)
|
26
|
+
eventmachine (>= 0.12.6)
|
27
|
+
rack (>= 1.0.0)
|
28
|
+
thor (0.17.0)
|
29
|
+
|
30
|
+
PLATFORMS
|
31
|
+
ruby
|
32
|
+
|
33
|
+
DEPENDENCIES
|
34
|
+
ki!
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'ki'
|
2
|
+
require 'digest/md5'
|
3
|
+
|
4
|
+
def encrypt s
|
5
|
+
Digest::MD5.hexdigest(s)
|
6
|
+
end
|
7
|
+
|
8
|
+
class User < Ki::Model
|
9
|
+
requires :mail, :password
|
10
|
+
respond_to :json
|
11
|
+
forbid :delete, :update
|
12
|
+
unique :mail
|
13
|
+
|
14
|
+
def before_all
|
15
|
+
params['password'] = encrypt(params['password'])
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class Storage < Ki::Model
|
20
|
+
respond_to :json
|
21
|
+
requires :mail
|
22
|
+
|
23
|
+
def before_all
|
24
|
+
ensure_authorization
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def ensure_authorization
|
30
|
+
if params['mail'].nil? || params['password'].nil?
|
31
|
+
raise 'not authorized'
|
32
|
+
end
|
33
|
+
h = { 'mail' => params['mail'], 'password' => encrypt(params['password'])}
|
34
|
+
u = User.find(h)
|
35
|
+
if u.empty?
|
36
|
+
raise 'not authorized'
|
37
|
+
end
|
38
|
+
params.delete['password']
|
39
|
+
end
|
40
|
+
end
|
File without changes
|
data/ki.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "ki"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Cristian Mircea Messel"]
|
12
|
-
s.date = "2013-02-
|
12
|
+
s.date = "2013-02-11"
|
13
13
|
s.description = "Fuck setting up a database for your prototypes. Some call it an ORM with a RESTful interface. Some say its for prototyping."
|
14
14
|
s.email = "mess110@gmail.com"
|
15
15
|
s.executables = ["ki"]
|
@@ -33,6 +33,12 @@ Gem::Specification.new do |s|
|
|
33
33
|
"examples/base/Gemfile.lock",
|
34
34
|
"examples/base/app.rb",
|
35
35
|
"examples/base/config.ru",
|
36
|
+
"examples/northpole.ro/Gemfile",
|
37
|
+
"examples/northpole.ro/Gemfile.lock",
|
38
|
+
"examples/northpole.ro/app.rb",
|
39
|
+
"examples/northpole.ro/config.ru",
|
40
|
+
"examples/northpole.ro/config.yml",
|
41
|
+
"examples/northpole.ro/views/index.haml",
|
36
42
|
"examples/northpole/Gemfile",
|
37
43
|
"examples/northpole/Gemfile.lock",
|
38
44
|
"examples/northpole/app.rb",
|
@@ -48,6 +54,7 @@ Gem::Specification.new do |s|
|
|
48
54
|
"lib/ki_cli.rb",
|
49
55
|
"lib/model.rb",
|
50
56
|
"lib/modules/callbacks.rb",
|
57
|
+
"lib/modules/model_helpers.rb",
|
51
58
|
"lib/modules/query_interface.rb",
|
52
59
|
"lib/modules/restrictions.rb",
|
53
60
|
"lib/req.rb",
|
@@ -59,6 +66,7 @@ Gem::Specification.new do |s|
|
|
59
66
|
"lib/views/index.haml",
|
60
67
|
"logo.png",
|
61
68
|
"spec/db_spec.rb",
|
69
|
+
"spec/integration/integration_spec.rb",
|
62
70
|
"spec/ki_spec.rb",
|
63
71
|
"spec/model_spec.rb",
|
64
72
|
"spec/modules/callbacks_spec.rb",
|
@@ -71,7 +79,7 @@ Gem::Specification.new do |s|
|
|
71
79
|
s.homepage = "http://github.com/mess110/ki"
|
72
80
|
s.licenses = ["MIT"]
|
73
81
|
s.require_paths = ["lib"]
|
74
|
-
s.rubygems_version = "1.8.
|
82
|
+
s.rubygems_version = "1.8.17"
|
75
83
|
s.summary = "Prototyping noSQL RESTful API cloud database"
|
76
84
|
|
77
85
|
if s.respond_to? :specification_version then
|
data/lib/db.rb
CHANGED
data/lib/model.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'modules/callbacks'
|
2
2
|
require 'modules/restrictions'
|
3
3
|
require 'modules/query_interface'
|
4
|
+
require 'modules/model_helpers'
|
4
5
|
|
5
6
|
require 'extensions/mail'
|
6
7
|
|
@@ -8,11 +9,12 @@ module Ki
|
|
8
9
|
class Model
|
9
10
|
extend Restrictions
|
10
11
|
extend QueryInterface
|
11
|
-
|
12
|
+
|
12
13
|
include Callbacks
|
14
|
+
include ModelHelpers
|
13
15
|
|
14
16
|
attr_accessor :hash
|
15
|
-
|
17
|
+
attr_accessor :req
|
16
18
|
|
17
19
|
def initialize req
|
18
20
|
@hash = {}
|
@@ -26,27 +28,19 @@ module Ki
|
|
26
28
|
|
27
29
|
def find
|
28
30
|
raise 'params missing' unless @req.params
|
29
|
-
|
30
|
-
if @req.params['_id']
|
31
|
-
unless @req.params.length == 1
|
32
|
-
raise 'no other params allowed when querying _id'
|
33
|
-
end
|
34
|
-
@hash = @db.find(class_name, @req.params['_id'])
|
35
|
-
else
|
36
|
-
@hash = @db.find_by(class_name, @req.params)
|
37
|
-
end
|
31
|
+
@hash = @db.find_by(class_name, @req.params)
|
38
32
|
raise "#{class_name} not found" if @hash.nil?
|
39
33
|
end
|
40
34
|
|
41
35
|
def create
|
42
36
|
check_for_required_attributes
|
37
|
+
check_for_unique_attributes
|
43
38
|
@hash['_id'] = @db.create(class_name, @req.params)
|
44
39
|
end
|
45
40
|
|
46
41
|
def update
|
47
42
|
raise 'params missing' unless @req.params
|
48
43
|
raise 'param _id missing' unless @req.params['_id']
|
49
|
-
|
50
44
|
check_for_required_attributes
|
51
45
|
@hash['_id'] = @db.update(class_name, @req.params)
|
52
46
|
end
|
@@ -54,7 +48,6 @@ module Ki
|
|
54
48
|
def delete
|
55
49
|
raise 'params missing' unless @req.params
|
56
50
|
raise 'param _id missing' unless @req.params['_id']
|
57
|
-
|
58
51
|
@hash = @db.delete(class_name, @req.params['_id'])
|
59
52
|
end
|
60
53
|
|
@@ -70,12 +63,21 @@ module Ki
|
|
70
63
|
|
71
64
|
def check_for_required_attributes
|
72
65
|
required_attributes.each do |ra|
|
73
|
-
|
66
|
+
if !@req.params.keys.include?(ra.to_s)
|
74
67
|
raise "#{ra.to_s} missing"
|
75
68
|
end
|
76
69
|
end
|
77
70
|
end
|
78
71
|
|
72
|
+
def check_for_unique_attributes
|
73
|
+
unique_attributes.each do |ua|
|
74
|
+
u = self.class.find({ua.to_s => params[ua.to_s]})
|
75
|
+
unless u.empty?
|
76
|
+
raise "#{ua.to_s} not unique"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
79
81
|
def to_action req
|
80
82
|
case req.request_method
|
81
83
|
when 'GET'
|
@@ -93,9 +95,11 @@ module Ki
|
|
93
95
|
|
94
96
|
# calls method m + before and after methods
|
95
97
|
def ccall m
|
98
|
+
before_all
|
96
99
|
send "before_#{m.to_s}".to_sym
|
97
100
|
send m.to_sym
|
98
101
|
send "after_#{m.to_s}".to_sym
|
102
|
+
after_all
|
99
103
|
end
|
100
104
|
end
|
101
105
|
end
|
data/lib/modules/callbacks.rb
CHANGED
@@ -0,0 +1,43 @@
|
|
1
|
+
module Ki
|
2
|
+
module ModelHelpers
|
3
|
+
def params
|
4
|
+
@req.params
|
5
|
+
end
|
6
|
+
|
7
|
+
def get?
|
8
|
+
@req.get?
|
9
|
+
end
|
10
|
+
|
11
|
+
def post?
|
12
|
+
@req.post?
|
13
|
+
end
|
14
|
+
|
15
|
+
def put?
|
16
|
+
@req.put?
|
17
|
+
end
|
18
|
+
|
19
|
+
def delete?
|
20
|
+
@req.delete?
|
21
|
+
end
|
22
|
+
|
23
|
+
def forbidden_actions
|
24
|
+
[]
|
25
|
+
end
|
26
|
+
|
27
|
+
def responds_to_formats
|
28
|
+
[:json, :html]
|
29
|
+
end
|
30
|
+
|
31
|
+
def required_attributes
|
32
|
+
[]
|
33
|
+
end
|
34
|
+
|
35
|
+
def skipped_params
|
36
|
+
[]
|
37
|
+
end
|
38
|
+
|
39
|
+
def unique_attributes
|
40
|
+
[]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/modules/restrictions.rb
CHANGED
@@ -15,17 +15,17 @@ module Ki
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
18
|
+
def responds_to_formats
|
19
19
|
[:json, :html]
|
20
20
|
end
|
21
21
|
|
22
22
|
def respond_to *formats
|
23
|
-
send :define_method, :
|
23
|
+
send :define_method, :responds_to_formats do
|
24
24
|
formats
|
25
25
|
end
|
26
26
|
|
27
27
|
eigen_class = class << self; self; end
|
28
|
-
eigen_class.send(:define_method, :
|
28
|
+
eigen_class.send(:define_method, :responds_to_formats) do
|
29
29
|
formats
|
30
30
|
end
|
31
31
|
end
|
@@ -44,19 +44,20 @@ module Ki
|
|
44
44
|
attributes
|
45
45
|
end
|
46
46
|
end
|
47
|
-
end
|
48
47
|
|
49
|
-
|
50
|
-
def forbidden_actions
|
48
|
+
def unique_attributes
|
51
49
|
[]
|
52
50
|
end
|
53
51
|
|
54
|
-
def
|
55
|
-
|
56
|
-
|
52
|
+
def unique *attributes
|
53
|
+
send :define_method, :unique_attributes do
|
54
|
+
attributes
|
55
|
+
end
|
57
56
|
|
58
|
-
|
59
|
-
|
57
|
+
eigen_class = class << self; self; end
|
58
|
+
eigen_class.send(:define_method, :unique_attributes) do
|
59
|
+
attributes
|
60
|
+
end
|
60
61
|
end
|
61
62
|
end
|
62
63
|
end
|
data/spec/db_spec.rb
CHANGED
@@ -57,7 +57,7 @@ describe Ki::Db do
|
|
57
57
|
end
|
58
58
|
|
59
59
|
it "should find by an attribute" do
|
60
|
-
@db.create 'zoidberg', { :foo => [1,2], :bar => 'highj' }
|
60
|
+
id = @db.create 'zoidberg', { :foo => [1,2], :bar => 'highj' }
|
61
61
|
@db.create 'zoidberg', { :foo => [3,4], :bar => 'lowj' }
|
62
62
|
@db.create 'zoidberg', { :foo => [5,6], :bar => 'lowj' }
|
63
63
|
r = @db.find_by 'zoidberg', { :bar => 'lowj' }
|
@@ -68,4 +68,12 @@ describe Ki::Db do
|
|
68
68
|
r.class.should == Array
|
69
69
|
r.length.should == 1
|
70
70
|
end
|
71
|
+
|
72
|
+
it "should transform _id in BSON::ObjectId when using find_by" do
|
73
|
+
hash = { :foo => [1,2], :bar => 'highj' }
|
74
|
+
id = @db.create 'zoidberg', hash
|
75
|
+
hash['_id'] = id
|
76
|
+
r = @db.find_by 'zoidberg', hash
|
77
|
+
r.length.should == 1
|
78
|
+
end
|
71
79
|
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
def encrypt s
|
4
|
+
s + '!'
|
5
|
+
end
|
6
|
+
|
7
|
+
describe 'Integration Tests' do
|
8
|
+
before :each do
|
9
|
+
@db = Ki::Db.instance
|
10
|
+
@db.remove_collections
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should handle user and storage" do
|
14
|
+
class User < Ki::Model
|
15
|
+
requires :mail, :password
|
16
|
+
respond_to :json
|
17
|
+
forbid :delete, :update
|
18
|
+
unique :mail
|
19
|
+
|
20
|
+
def before_all
|
21
|
+
params['password'] = encrypt(params['password']) if params['password']
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Storage < Ki::Model
|
26
|
+
respond_to :json
|
27
|
+
requires :mail, :all_my_data
|
28
|
+
|
29
|
+
def before_all
|
30
|
+
ensure_authorization
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def ensure_authorization
|
36
|
+
if params['mail'].nil? || params['password'].nil?
|
37
|
+
raise 'not authorized'
|
38
|
+
end
|
39
|
+
h = { 'mail' => params['mail'], 'password' => encrypt(params['password'])}
|
40
|
+
u = User.find(h)
|
41
|
+
if u.empty?
|
42
|
+
raise 'not authorized'
|
43
|
+
end
|
44
|
+
params.delete('password')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
expect {
|
49
|
+
User.new(ReqFactory.new(:post, { 'mail' => 'cool@beans.com'})).hash['_id']
|
50
|
+
}.to raise_error 'password missing'
|
51
|
+
|
52
|
+
expect {
|
53
|
+
id = User.new(ReqFactory.new(:post, { 'mail' => 'cool@beans.com', 'password' => '123'})).hash['_id']
|
54
|
+
User.new(ReqFactory.new(:get, { '_id' => id })).hash[0]['password'].should == '123!'
|
55
|
+
}.to change(User, :count).by(1)
|
56
|
+
|
57
|
+
expect {
|
58
|
+
id = User.new(ReqFactory.new(:post, { 'mail' => 'cool@beans.com', 'password' => '123'})).hash['_id']
|
59
|
+
}.to raise_error 'mail not unique'
|
60
|
+
|
61
|
+
expect {
|
62
|
+
Storage.new(ReqFactory.new(:post, {}))
|
63
|
+
}.to raise_error 'not authorized'
|
64
|
+
|
65
|
+
expect {
|
66
|
+
Storage.new(ReqFactory.new(:post, {'mail' => 'cool@beans.com'}))
|
67
|
+
}.to raise_error 'not authorized'
|
68
|
+
|
69
|
+
# create storage
|
70
|
+
storage = Storage.new(ReqFactory.new(:post, {'mail' => 'cool@beans.com', 'password' => '123', 'all_my_data' => [1,2,3]}))
|
71
|
+
id = storage.hash['_id']
|
72
|
+
r = Storage.new(ReqFactory.new(:get, { 'mail' => 'cool@beans.com', 'password' => '123'}))
|
73
|
+
r.hash[0]['all_my_data'].should == [1,2,3]
|
74
|
+
r.hash[0]['password'].should == nil
|
75
|
+
|
76
|
+
expect {
|
77
|
+
Storage.new(ReqFactory.new(:delete, {}))
|
78
|
+
}.to raise_error 'not authorized'
|
79
|
+
|
80
|
+
expect {
|
81
|
+
Storage.new(ReqFactory.new(:delete, {'_id' => id}))
|
82
|
+
}.to raise_error 'not authorized'
|
83
|
+
|
84
|
+
expect {
|
85
|
+
Storage.new(ReqFactory.new(:delete, {'mail' => 'cool@beans.com', 'password' => '123'}))
|
86
|
+
}.to raise_error 'param _id missing'
|
87
|
+
|
88
|
+
# delete from storage
|
89
|
+
expect {
|
90
|
+
Storage.new(ReqFactory.new(:delete, {'_id' => id, 'mail' => 'cool@beans.com', 'password' => '123'}))
|
91
|
+
}.to change(Storage, :count).by(-1)
|
92
|
+
|
93
|
+
# not allowed to delete user
|
94
|
+
expect {
|
95
|
+
id = User.new(ReqFactory.new(:post, { 'mail' => 'other@beans.com', 'password' => '123'})).hash['_id']
|
96
|
+
p User.new(ReqFactory.new(:delete, { '_id' => id }))
|
97
|
+
}.to raise_error 'action forbidden'
|
98
|
+
|
99
|
+
storage = Storage.new(ReqFactory.new(:post, {'mail' => 'cool@beans.com', 'password' => '123', 'all_my_data' => [4,4,5]}))
|
100
|
+
id = storage.hash['_id']
|
101
|
+
expect {
|
102
|
+
Storage.new(ReqFactory.new(:put, {'mail' => 'cool@beans.com', 'password' => '123', 'all_my_data' => [1]}))
|
103
|
+
}.to raise_error 'param _id missing'
|
104
|
+
|
105
|
+
expect {
|
106
|
+
Storage.new(ReqFactory.new(:put, {'mail' => 'cool@beans.com', 'password' => '1234', 'all_my_data' => [1]}))
|
107
|
+
}.to raise_error 'not authorized'
|
108
|
+
|
109
|
+
storage = Storage.new(ReqFactory.new(:put, {'_id' => id, 'mail' => 'cool@beans.com', 'password' => '123', 'all_my_data' => [1]}))
|
110
|
+
storage.hash['_id'].should == id
|
111
|
+
storage = Storage.find(id)
|
112
|
+
storage['all_my_data'].should == [1]
|
113
|
+
end
|
114
|
+
end
|
data/spec/model_spec.rb
CHANGED
@@ -24,7 +24,7 @@ describe Ki::Model do
|
|
24
24
|
id = @db.create 'zoidberg', { :name => 'homer' }
|
25
25
|
|
26
26
|
get = ReqFactory.new(:get, {'_id' => id})
|
27
|
-
Zoidberg.new(get).hash['name'].should == 'homer'
|
27
|
+
Zoidberg.new(get).hash[0]['name'].should == 'homer'
|
28
28
|
end
|
29
29
|
|
30
30
|
it "should find objects depending on params" do
|
@@ -48,12 +48,6 @@ describe Ki::Model do
|
|
48
48
|
r.length.should == 2
|
49
49
|
end
|
50
50
|
|
51
|
-
it "should raise error when _id and other params are given. it should be _id only" do
|
52
|
-
expect {
|
53
|
-
Zoidberg.new(ReqFactory.new(:get, { '_id' => 'hi', 'foo' => 'bar'}))
|
54
|
-
}.to raise_error 'no other params allowed when querying _id'
|
55
|
-
end
|
56
|
-
|
57
51
|
it "should only accept valid object ids" do
|
58
52
|
expect {
|
59
53
|
Zoidberg.new(ReqFactory.new(:get_with_params, { :_id => 'homer' }))
|
@@ -9,6 +9,17 @@ describe Ki::Callbacks do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
id = Foo.new(ReqFactory.new(:post, {:foo => 'bar'})).hash['_id']
|
12
|
-
Foo.new(ReqFactory.new(:get, { '_id' => id })).hash['meaning_of_life'].should == 42
|
12
|
+
Foo.new(ReqFactory.new(:get, { '_id' => id })).hash[0]['meaning_of_life'].should == 42
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should handle before and after all" do
|
16
|
+
class Foo < Ki::Model
|
17
|
+
def before_all
|
18
|
+
params[:cool] = true unless get?
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
id = Foo.new(ReqFactory.new(:post, {:foo => 'bar'})).hash['_id']
|
23
|
+
Foo.new(ReqFactory.new(:get, { '_id' => id })).hash[0]['cool'].should be_true
|
13
24
|
end
|
14
25
|
end
|
@@ -15,6 +15,21 @@ describe Ki::QueryInterface do
|
|
15
15
|
waldo = Waldo.find(id)
|
16
16
|
waldo['location'].should == 'amsterdam'
|
17
17
|
end
|
18
|
+
|
19
|
+
it "should find by a hash" do
|
20
|
+
@db.create 'waldo', { :location => 'amsterdam', :cool => true, :value => 0 }
|
21
|
+
@db.create 'waldo', { :location => 'copenhagen', :cool => true, :value => 1 }
|
22
|
+
@db.create 'waldo', { :location => 'kronstadt', :cool => true, :value => 1 }
|
23
|
+
|
24
|
+
class Waldo < Ki::Model
|
25
|
+
end
|
26
|
+
|
27
|
+
r = Waldo.find({ :cool => true })
|
28
|
+
r.length.should == 3
|
29
|
+
|
30
|
+
r = Waldo.find({ :cool => true, :value => 1 })
|
31
|
+
r.length.should == 2
|
32
|
+
end
|
18
33
|
|
19
34
|
it "should delete porn" do
|
20
35
|
id = @db.create 'porn', { :website => 'youporn.com' }
|
@@ -1,6 +1,11 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
2
|
|
3
3
|
describe Ki::Restrictions do
|
4
|
+
before :each do
|
5
|
+
@db = Ki::Db.instance
|
6
|
+
@db.remove_collections
|
7
|
+
end
|
8
|
+
|
4
9
|
it "should only allow specified methods" do
|
5
10
|
class Foo < Ki::Model
|
6
11
|
end
|
@@ -30,15 +35,15 @@ describe Ki::Restrictions do
|
|
30
35
|
it "should respond to html and json by default" do
|
31
36
|
class Foo < Ki::Model
|
32
37
|
end
|
33
|
-
Foo.
|
38
|
+
Foo.responds_to_formats.should == [:json, :html]
|
34
39
|
end
|
35
40
|
|
36
41
|
it "should allow only json" do
|
37
42
|
class Foo < Ki::Model
|
38
43
|
respond_to :json
|
39
44
|
end
|
40
|
-
Foo.
|
41
|
-
Foo.
|
45
|
+
Foo.responds_to_formats.include?(:json).should be_true
|
46
|
+
Foo.responds_to_formats.include?(:html).should be_false
|
42
47
|
end
|
43
48
|
|
44
49
|
it "should not have any required attributes" do
|
@@ -61,4 +66,23 @@ describe Ki::Restrictions do
|
|
61
66
|
Foo.new(ReqFactory.new(:post, {'name' => 'bart' }))
|
62
67
|
}.to change(Ki::Db.instance.db['foo'], :count).by(1)
|
63
68
|
end
|
69
|
+
|
70
|
+
it "should handle unique attributes" do
|
71
|
+
class Foo < Ki::Model
|
72
|
+
end
|
73
|
+
Foo.unique_attributes.should == []
|
74
|
+
|
75
|
+
class Bar < Ki::Model
|
76
|
+
unique :foo
|
77
|
+
end
|
78
|
+
Bar.unique_attributes.should == [:foo]
|
79
|
+
|
80
|
+
expect {
|
81
|
+
Bar.new(ReqFactory.new(:post, { 'foo' => 'bar'}))
|
82
|
+
}.to change(Bar, :count).by(1)
|
83
|
+
|
84
|
+
expect {
|
85
|
+
Bar.new(ReqFactory.new(:post, { 'foo' => 'bar'}))
|
86
|
+
}.to raise_error 'foo not unique'
|
87
|
+
end
|
64
88
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -16,6 +16,22 @@ Ki::Db.instance.config DB_HOST, DB_PORT, DB_NAME
|
|
16
16
|
class MockReq
|
17
17
|
attr_accessor :request_method
|
18
18
|
attr_accessor :params
|
19
|
+
|
20
|
+
def get?
|
21
|
+
request_method == 'GET'
|
22
|
+
end
|
23
|
+
|
24
|
+
def post?
|
25
|
+
request_method == 'POST'
|
26
|
+
end
|
27
|
+
|
28
|
+
def put?
|
29
|
+
request_method == 'PUT'
|
30
|
+
end
|
31
|
+
|
32
|
+
def delete?
|
33
|
+
request_method == 'DELETE'
|
34
|
+
end
|
19
35
|
end
|
20
36
|
|
21
37
|
class ReqFactory
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ki
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-02-
|
12
|
+
date: 2013-02-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirement: &70671260 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,15 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
25
|
-
none: false
|
26
|
-
requirements:
|
27
|
-
- - ! '>='
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: '0'
|
24
|
+
version_requirements: *70671260
|
30
25
|
- !ruby/object:Gem::Dependency
|
31
26
|
name: mongo
|
32
|
-
requirement: !ruby/object:Gem::Requirement
|
27
|
+
requirement: &70670860 !ruby/object:Gem::Requirement
|
33
28
|
none: false
|
34
29
|
requirements:
|
35
30
|
- - ! '>='
|
@@ -37,15 +32,10 @@ dependencies:
|
|
37
32
|
version: '0'
|
38
33
|
type: :runtime
|
39
34
|
prerelease: false
|
40
|
-
version_requirements:
|
41
|
-
none: false
|
42
|
-
requirements:
|
43
|
-
- - ! '>='
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
version: '0'
|
35
|
+
version_requirements: *70670860
|
46
36
|
- !ruby/object:Gem::Dependency
|
47
37
|
name: bson_ext
|
48
|
-
requirement: !ruby/object:Gem::Requirement
|
38
|
+
requirement: &70670500 !ruby/object:Gem::Requirement
|
49
39
|
none: false
|
50
40
|
requirements:
|
51
41
|
- - ! '>='
|
@@ -53,15 +43,10 @@ dependencies:
|
|
53
43
|
version: '0'
|
54
44
|
type: :runtime
|
55
45
|
prerelease: false
|
56
|
-
version_requirements:
|
57
|
-
none: false
|
58
|
-
requirements:
|
59
|
-
- - ! '>='
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
46
|
+
version_requirements: *70670500
|
62
47
|
- !ruby/object:Gem::Dependency
|
63
48
|
name: thor
|
64
|
-
requirement: !ruby/object:Gem::Requirement
|
49
|
+
requirement: &70670150 !ruby/object:Gem::Requirement
|
65
50
|
none: false
|
66
51
|
requirements:
|
67
52
|
- - ! '>='
|
@@ -69,15 +54,10 @@ dependencies:
|
|
69
54
|
version: '0'
|
70
55
|
type: :runtime
|
71
56
|
prerelease: false
|
72
|
-
version_requirements:
|
73
|
-
none: false
|
74
|
-
requirements:
|
75
|
-
- - ! '>='
|
76
|
-
- !ruby/object:Gem::Version
|
77
|
-
version: '0'
|
57
|
+
version_requirements: *70670150
|
78
58
|
- !ruby/object:Gem::Dependency
|
79
59
|
name: haml
|
80
|
-
requirement: !ruby/object:Gem::Requirement
|
60
|
+
requirement: &70669770 !ruby/object:Gem::Requirement
|
81
61
|
none: false
|
82
62
|
requirements:
|
83
63
|
- - ! '>='
|
@@ -85,15 +65,10 @@ dependencies:
|
|
85
65
|
version: '0'
|
86
66
|
type: :runtime
|
87
67
|
prerelease: false
|
88
|
-
version_requirements:
|
89
|
-
none: false
|
90
|
-
requirements:
|
91
|
-
- - ! '>='
|
92
|
-
- !ruby/object:Gem::Version
|
93
|
-
version: '0'
|
68
|
+
version_requirements: *70669770
|
94
69
|
- !ruby/object:Gem::Dependency
|
95
70
|
name: thin
|
96
|
-
requirement: !ruby/object:Gem::Requirement
|
71
|
+
requirement: &70669240 !ruby/object:Gem::Requirement
|
97
72
|
none: false
|
98
73
|
requirements:
|
99
74
|
- - ! '>='
|
@@ -101,15 +76,10 @@ dependencies:
|
|
101
76
|
version: '0'
|
102
77
|
type: :runtime
|
103
78
|
prerelease: false
|
104
|
-
version_requirements:
|
105
|
-
none: false
|
106
|
-
requirements:
|
107
|
-
- - ! '>='
|
108
|
-
- !ruby/object:Gem::Version
|
109
|
-
version: '0'
|
79
|
+
version_requirements: *70669240
|
110
80
|
- !ruby/object:Gem::Dependency
|
111
81
|
name: rspec
|
112
|
-
requirement: !ruby/object:Gem::Requirement
|
82
|
+
requirement: &70668680 !ruby/object:Gem::Requirement
|
113
83
|
none: false
|
114
84
|
requirements:
|
115
85
|
- - ! '>='
|
@@ -117,15 +87,10 @@ dependencies:
|
|
117
87
|
version: '0'
|
118
88
|
type: :development
|
119
89
|
prerelease: false
|
120
|
-
version_requirements:
|
121
|
-
none: false
|
122
|
-
requirements:
|
123
|
-
- - ! '>='
|
124
|
-
- !ruby/object:Gem::Version
|
125
|
-
version: '0'
|
90
|
+
version_requirements: *70668680
|
126
91
|
- !ruby/object:Gem::Dependency
|
127
92
|
name: guard-rspec
|
128
|
-
requirement: !ruby/object:Gem::Requirement
|
93
|
+
requirement: &70668240 !ruby/object:Gem::Requirement
|
129
94
|
none: false
|
130
95
|
requirements:
|
131
96
|
- - ! '>='
|
@@ -133,15 +98,10 @@ dependencies:
|
|
133
98
|
version: '0'
|
134
99
|
type: :development
|
135
100
|
prerelease: false
|
136
|
-
version_requirements:
|
137
|
-
none: false
|
138
|
-
requirements:
|
139
|
-
- - ! '>='
|
140
|
-
- !ruby/object:Gem::Version
|
141
|
-
version: '0'
|
101
|
+
version_requirements: *70668240
|
142
102
|
- !ruby/object:Gem::Dependency
|
143
103
|
name: rb-inotify
|
144
|
-
requirement: !ruby/object:Gem::Requirement
|
104
|
+
requirement: &70667730 !ruby/object:Gem::Requirement
|
145
105
|
none: false
|
146
106
|
requirements:
|
147
107
|
- - ~>
|
@@ -149,15 +109,10 @@ dependencies:
|
|
149
109
|
version: 0.8.8
|
150
110
|
type: :development
|
151
111
|
prerelease: false
|
152
|
-
version_requirements:
|
153
|
-
none: false
|
154
|
-
requirements:
|
155
|
-
- - ~>
|
156
|
-
- !ruby/object:Gem::Version
|
157
|
-
version: 0.8.8
|
112
|
+
version_requirements: *70667730
|
158
113
|
- !ruby/object:Gem::Dependency
|
159
114
|
name: rdoc
|
160
|
-
requirement: !ruby/object:Gem::Requirement
|
115
|
+
requirement: &70667280 !ruby/object:Gem::Requirement
|
161
116
|
none: false
|
162
117
|
requirements:
|
163
118
|
- - ! '>='
|
@@ -165,15 +120,10 @@ dependencies:
|
|
165
120
|
version: '0'
|
166
121
|
type: :development
|
167
122
|
prerelease: false
|
168
|
-
version_requirements:
|
169
|
-
none: false
|
170
|
-
requirements:
|
171
|
-
- - ! '>='
|
172
|
-
- !ruby/object:Gem::Version
|
173
|
-
version: '0'
|
123
|
+
version_requirements: *70667280
|
174
124
|
- !ruby/object:Gem::Dependency
|
175
125
|
name: bundler
|
176
|
-
requirement: !ruby/object:Gem::Requirement
|
126
|
+
requirement: &70666920 !ruby/object:Gem::Requirement
|
177
127
|
none: false
|
178
128
|
requirements:
|
179
129
|
- - ! '>='
|
@@ -181,15 +131,10 @@ dependencies:
|
|
181
131
|
version: '0'
|
182
132
|
type: :development
|
183
133
|
prerelease: false
|
184
|
-
version_requirements:
|
185
|
-
none: false
|
186
|
-
requirements:
|
187
|
-
- - ! '>='
|
188
|
-
- !ruby/object:Gem::Version
|
189
|
-
version: '0'
|
134
|
+
version_requirements: *70666920
|
190
135
|
- !ruby/object:Gem::Dependency
|
191
136
|
name: jeweler
|
192
|
-
requirement: !ruby/object:Gem::Requirement
|
137
|
+
requirement: &70666450 !ruby/object:Gem::Requirement
|
193
138
|
none: false
|
194
139
|
requirements:
|
195
140
|
- - ! '>='
|
@@ -197,15 +142,10 @@ dependencies:
|
|
197
142
|
version: '0'
|
198
143
|
type: :development
|
199
144
|
prerelease: false
|
200
|
-
version_requirements:
|
201
|
-
none: false
|
202
|
-
requirements:
|
203
|
-
- - ! '>='
|
204
|
-
- !ruby/object:Gem::Version
|
205
|
-
version: '0'
|
145
|
+
version_requirements: *70666450
|
206
146
|
- !ruby/object:Gem::Dependency
|
207
147
|
name: simplecov
|
208
|
-
requirement: !ruby/object:Gem::Requirement
|
148
|
+
requirement: &70453200 !ruby/object:Gem::Requirement
|
209
149
|
none: false
|
210
150
|
requirements:
|
211
151
|
- - ! '>='
|
@@ -213,12 +153,7 @@ dependencies:
|
|
213
153
|
version: '0'
|
214
154
|
type: :development
|
215
155
|
prerelease: false
|
216
|
-
version_requirements:
|
217
|
-
none: false
|
218
|
-
requirements:
|
219
|
-
- - ! '>='
|
220
|
-
- !ruby/object:Gem::Version
|
221
|
-
version: '0'
|
156
|
+
version_requirements: *70453200
|
222
157
|
description: Fuck setting up a database for your prototypes. Some call it an ORM with
|
223
158
|
a RESTful interface. Some say its for prototyping.
|
224
159
|
email: mess110@gmail.com
|
@@ -244,6 +179,12 @@ files:
|
|
244
179
|
- examples/base/Gemfile.lock
|
245
180
|
- examples/base/app.rb
|
246
181
|
- examples/base/config.ru
|
182
|
+
- examples/northpole.ro/Gemfile
|
183
|
+
- examples/northpole.ro/Gemfile.lock
|
184
|
+
- examples/northpole.ro/app.rb
|
185
|
+
- examples/northpole.ro/config.ru
|
186
|
+
- examples/northpole.ro/config.yml
|
187
|
+
- examples/northpole.ro/views/index.haml
|
247
188
|
- examples/northpole/Gemfile
|
248
189
|
- examples/northpole/Gemfile.lock
|
249
190
|
- examples/northpole/app.rb
|
@@ -259,6 +200,7 @@ files:
|
|
259
200
|
- lib/ki_cli.rb
|
260
201
|
- lib/model.rb
|
261
202
|
- lib/modules/callbacks.rb
|
203
|
+
- lib/modules/model_helpers.rb
|
262
204
|
- lib/modules/query_interface.rb
|
263
205
|
- lib/modules/restrictions.rb
|
264
206
|
- lib/req.rb
|
@@ -270,6 +212,7 @@ files:
|
|
270
212
|
- lib/views/index.haml
|
271
213
|
- logo.png
|
272
214
|
- spec/db_spec.rb
|
215
|
+
- spec/integration/integration_spec.rb
|
273
216
|
- spec/ki_spec.rb
|
274
217
|
- spec/model_spec.rb
|
275
218
|
- spec/modules/callbacks_spec.rb
|
@@ -293,7 +236,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
293
236
|
version: '0'
|
294
237
|
segments:
|
295
238
|
- 0
|
296
|
-
hash: -
|
239
|
+
hash: -16119203
|
297
240
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
298
241
|
none: false
|
299
242
|
requirements:
|
@@ -302,7 +245,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
302
245
|
version: '0'
|
303
246
|
requirements: []
|
304
247
|
rubyforge_project:
|
305
|
-
rubygems_version: 1.8.
|
248
|
+
rubygems_version: 1.8.17
|
306
249
|
signing_key:
|
307
250
|
specification_version: 3
|
308
251
|
summary: Prototyping noSQL RESTful API cloud database
|