yogo-db 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ # Defining a schema factory
2
+ Factory.define(:schema) do |u|
3
+ u.sequence(:name) { |n| "yogo_#{n}" }
4
+ u.operations [['add/property', :name, 'String']]
5
+ end
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+
3
+ # This is inspired by Warden's spec helpers
4
+ module Yogo
5
+ module Spec
6
+ module Helpers
7
+
8
+ def env_with_params(path = "/", params = {})
9
+ method = params.fetch(:method, "GET")
10
+ ::Rack::MockRequest.env_for(path, :input => ::Rack::Utils.build_query(params),
11
+ 'HTTP_VERSION' => '1.1',
12
+ 'REQUEST_METHOD' => "#{method}")
13
+ end
14
+
15
+ def setup_rack(app = default_app, middleware = {}, &block)
16
+ app ||= block if block_given?
17
+
18
+ ::Rack::Builder.new do
19
+ use Yogo::Rack::ModelLookup, :paths => ['schema', 'data']
20
+ run app
21
+ end
22
+
23
+ end
24
+
25
+ def default_app
26
+ lambda { |env| [ 200, {'Content-Type' => 'text/plain'}, ["Hello World"]]}
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,136 @@
1
+ # encoding: utf-8
2
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
3
+ require 'yogo/model/schema'
4
+
5
+ # Testing the middleware and how it modifies the environment
6
+ describe Schema do
7
+
8
+ before(:all) do
9
+ @schema = Factory.create(:schema)
10
+ end
11
+
12
+ after(:all) do
13
+ @schema.destroy
14
+ end
15
+
16
+ it "should generate a proc" do
17
+ Schema.first.to_proc.should be_kind_of Proc
18
+ end
19
+
20
+ it "should store and generate a model" do
21
+ Schema.first.data_model.should be_a(DataMapper::Model)
22
+ end
23
+
24
+ it "should update the data_model after being updated" do
25
+ original_model = @schema.data_model
26
+ # original_model.auto_migrate!
27
+
28
+ @schema.operation('add/property', :age, 'Integer')
29
+ @schema.save
30
+ # @schema.data_model.auto_upgrade!
31
+ # @schema.data_model.i.should_not eql original_model
32
+ @schema.data_model.properties.should_not eql original_model.properties
33
+ end
34
+
35
+ # it "should update the attributes" do
36
+ # updated_schema = {:name => @schema.name,
37
+ # :operations => [['add/property', :id, 'Serial'],['add/property', :description, 'Text'] ]}
38
+ # @schema.update(updated_schema)
39
+ # @schema.operation_definitions.should eql updated_schema[:operations]
40
+ # end
41
+
42
+ it "should remove the data_model data while being destroyed"
43
+
44
+ describe "the generated data model" do
45
+
46
+ before(:all) do
47
+
48
+ @schema.operation('add/property', :address, 'String', 'label' => 'Address')
49
+ @schema.operation('add/property', :food, 'Boolean', 'label' => 'Likes Food?')
50
+ @schema.save
51
+ end
52
+
53
+ it "should have a reference back to the schema object" do
54
+ model = @schema.data_model
55
+
56
+ model.schema.should eql @schema
57
+ end
58
+
59
+ # Assume that each add/property op is exacitly 1 property at the end
60
+ it "should have the same number of properties as described in the schema" do
61
+ property_operations = @schema.operation_definitions.select{|op| op[0].eql?('add/property')}
62
+
63
+ # There are 3 'default' properties added
64
+ @schema.data_model.properties.length.should eql(property_operations.length + 3)
65
+ end
66
+
67
+ describe "json" do
68
+ it "should respond to \#to_json" do
69
+ @schema.data_model.create.should respond_to(:to_json)
70
+ end
71
+
72
+ it "should should be valid" do
73
+ item = @schema.data_model.create
74
+ lambda {
75
+ JSON.parse(item.to_json)
76
+ }.should_not raise_exception
77
+ end
78
+
79
+ it "should should inclue url and :id keys" do
80
+ JSON.parse(@schema.data_model.create.to_json).should include('url', 'data')
81
+ end
82
+ end
83
+
84
+ it "should respond to \#to_url}" do
85
+ @schema.data_model.create.should respond_to(:to_url)
86
+ end
87
+
88
+ it "should raise an exception when new and to_url is called" do
89
+ lambda {
90
+ @schema.data_model.new.to_url
91
+ }.should raise_exception
92
+
93
+ end
94
+
95
+ it "should return valid urls" do
96
+ new_item = @schema.data_model.create
97
+ new_item.to_url.should eql("/data/#{@schema.name}/#{new_item.yogo_id}")
98
+ end
99
+
100
+ it "should respond to .parse_json" do
101
+ @schema.data_model.should respond_to(:parse_json)
102
+ end
103
+
104
+ describe "parse_json" do
105
+
106
+ it "should return a hash ready for the model" do
107
+ json = {:data => {'Address' => 'an address', 'Likes Food?' => true}}.to_json
108
+ opts = @schema.data_model.parse_json(json)
109
+ item = @schema.data_model.new(opts)
110
+ item.should be_valid
111
+ end
112
+ end
113
+
114
+ it "should respond to attributes_by_label" do
115
+ @schema.data_model.new.should respond_to(:attributes_by_label)
116
+ end
117
+
118
+ it "should return labeled attributed" do
119
+ item = @schema.data_model.new
120
+ attributes = item.attributes_by_label
121
+ attributes.should be_a Hash
122
+ attributes.keys.should include('Address', 'Likes Food?')
123
+ end
124
+ end
125
+
126
+ describe "file handling" do
127
+ it "should beable to have a file added" do
128
+ @schema.operation('add/file', :my_file, {'label' => "My File"})
129
+
130
+ @schema.save
131
+ lambda{
132
+ @schema.data_model.first
133
+ }.should_not raise_exception
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,37 @@
1
+ # Standard requirements for Bundler management
2
+ require 'rubygems'
3
+ require 'bundler/setup'
4
+
5
+ # Load the bundler gemset
6
+ Bundler.require(:default, ENV['RACK_ENV'] || :test )
7
+
8
+ # Mess with load paths
9
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..'))
10
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
11
+
12
+ require 'rspec/core'
13
+ require 'autotest/rspec2'
14
+ require 'rack/test'
15
+ require 'rack/mock'
16
+
17
+ require 'config/datamapper'
18
+
19
+ begin
20
+ require 'ruby-debug'
21
+ rescue Exception => e
22
+ puts "ruby-debug is not installed. Install it with 'gem install ruby-debug'"
23
+ end
24
+
25
+ Dir[File.join(File.dirname(__FILE__), "helpers", "**/*.rb")].each do |f|
26
+ require f
27
+ end
28
+
29
+ Dir[File.join(File.dirname(__FILE__), "factories", "**/*.rb")].each do |f|
30
+ require f
31
+ end
32
+
33
+ Rspec.configure do |config|
34
+ config.include Yogo::Spec::Helpers
35
+ # config.mock_with :rspec
36
+ config.before(:all) { DataMapper.finalize.auto_migrate! }
37
+ end
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
3
+ require 'yogo/data_app'
4
+
5
+ # Testing potential endpoints
6
+ describe Yogo::DataApp do
7
+ include Rack::Test::Methods
8
+
9
+ def app
10
+ setup_rack(Yogo::DataApp)
11
+ end
12
+
13
+ before(:all) do
14
+ @cur_schema = Factory.create(:schema)
15
+ end
16
+
17
+ after(:all) do
18
+ @cur_schema.destroy
19
+ end
20
+
21
+ describe "when retrieving /data/:model_id" do
22
+
23
+ it "should return all data" do
24
+ header 'accepts', 'application/json'
25
+ get "/data/#{@cur_schema.name}", :headers => {'accepts' => 'application/json'}
26
+
27
+ last_response.should be_ok
28
+ last_response.headers['content-type'].should eql 'application/json;charset=utf-8'
29
+ end
30
+ end
31
+
32
+ end
@@ -0,0 +1,78 @@
1
+ # encoding: utf-8
2
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
3
+ require 'yogo/rack/model_lookup'
4
+
5
+ # Testing the middleware and how it modifies the environment
6
+ describe "Model lookup" do
7
+ include Rack::Test::Methods
8
+
9
+ def app
10
+ setup_rack()
11
+ end
12
+
13
+ describe 'with an existing configuration' do
14
+
15
+ before(:all) do
16
+ @configuration = Factory.create(:schema)
17
+ end
18
+
19
+ after(:all) do
20
+ @configuration.destroy
21
+ end
22
+
23
+ it "should add a yogo.resource key to the environment hash" do
24
+ env = env_with_params("/schema/#{@configuration.name}")
25
+ response = app.call(env)
26
+ env.should be_a Hash
27
+ env.should have_key('yogo.resource')
28
+ end
29
+
30
+ it "should add a yogo.schema key to the environment hash" do
31
+ env = env_with_params("/schema/#{@configuration.name}")
32
+ response = app().call(env)
33
+ env.should be_a Hash
34
+ env.should have_key('yogo.schema')
35
+ end
36
+
37
+ it "should point to a datamapper model" do
38
+ env = env_with_params("/schema/#{@configuration.name}")
39
+ response = app.call(env)
40
+ env['yogo.resource'].should be_kind_of(DataMapper::Model)
41
+ end
42
+
43
+ it "should set a model when more then a path was specified" do
44
+ env = env_with_params("/schema/#{@configuration.name}/more_path")
45
+ response = app.call(env)
46
+ env['yogo.resource'].should be_kind_of(DataMapper::Model)
47
+ end
48
+ end
49
+
50
+ it "should not change the keys environment without a proper URI path" do
51
+ env = env_with_params('/')
52
+ lambda {
53
+ app.call(env)
54
+ }.should_not change(env, :keys)
55
+ end
56
+
57
+
58
+ it "should not set a model if no model id was specified" do
59
+ env = env_with_params('/schema')
60
+ lambda {
61
+ app.call(env)
62
+ }.should_not change(env, :keys)
63
+ end
64
+
65
+ it "should not set a model if a model id was specified but doesn't exist" do
66
+ env = env_with_params('/schema/some%20sort%20of%20model')
67
+ app.call(env)
68
+ env['yogo.resource'].should be_nil
69
+ env['yogo.schema'].should be_nil
70
+ end
71
+
72
+ # This test feels funny here.
73
+ it "should respond with a 404 if a model id was specified but doesn't exist" do
74
+ get '/schema/with_bad_id'
75
+ last_response.should_not be_ok
76
+ last_response.status.should eql(404)
77
+ end
78
+ end
@@ -0,0 +1,105 @@
1
+ # encoding: utf-8
2
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
3
+ require 'yogo/schema_app'
4
+
5
+ # Testing potential endpoints
6
+ describe Yogo::SchemaApp do
7
+ include Rack::Test::Methods
8
+
9
+ def app
10
+ setup_rack(Yogo::SchemaApp)
11
+ end
12
+
13
+ describe "when retrieving /schema" do
14
+
15
+ it "should retrive a list of all schemas" do
16
+ header 'accept', 'application/json'
17
+ get '/schema'
18
+
19
+ last_response.should be_ok
20
+ last_response.headers['content-type'].should eql 'application/json;charset=utf-8'
21
+ end
22
+ end
23
+
24
+ describe "when retriving /schema/:id" do
25
+ it "should retrieve retrieve a particular schema" do
26
+ schema = Factory.create(:schema)
27
+ header 'accept', 'application/json'
28
+ get "/schema/#{schema.name}"
29
+ last_response.should be_ok
30
+ last_response.body.should eql( { :content => schema }.to_json )
31
+ end
32
+
33
+ it "should give a 404 error when the schema does not exist" do
34
+ get '/schema/with_bad_id'
35
+ last_response.should_not be_ok
36
+ last_response.status.should eql(404)
37
+ end
38
+ end
39
+
40
+ describe "when posting to /schema" do
41
+ it "should create a new schema with the provided id" do
42
+ post '/schema', {:name => 'test_item',
43
+ :operations => [['add/property', :id, 'Serial'],['add/property', :name, 'String']]}.to_json
44
+
45
+ last_response.status.should eql(201)
46
+
47
+ get '/schema/test_item'
48
+ last_response.should be_ok
49
+ end
50
+
51
+ it "should not create a new schema with invalid data" do
52
+ post '/schema', {:name => 'test_item',
53
+ :bad_op => 42}.to_json
54
+
55
+ last_response.status.should eql(401)
56
+ last_response.body.should eql("Invalid Format")
57
+ end
58
+ end
59
+
60
+ describe "when putting to /schema/:id" do
61
+ before(:all) do
62
+ @cur_schema = Factory.create(:schema)
63
+ end
64
+
65
+ after(:all) do
66
+ @cur_schema.destroy
67
+ end
68
+
69
+ it "should replace the schema with the given payload" do
70
+ updated_schema = {'name' => @cur_schema.name,
71
+ 'operations' => [['add/property', 'id', 'Integer'],['add/property', 'description', 'Text'] ]}
72
+ put "/schema/#{@cur_schema.name}", updated_schema.to_json
73
+
74
+ last_response.status.should eql(200)
75
+ JSON.parse(last_response.body)["content"].should eql updated_schema.merge('guid' => "/schema/#{@cur_schema.name}")
76
+ end
77
+
78
+ it "should not update when given an invalid payload" do
79
+ put "/schema/#{@cur_schema.name}", "some really bad data"
80
+
81
+ last_response.should_not be_ok
82
+ end
83
+ it "should return an error when an invalid ID is given" do
84
+ put '/schema/a_bad_id', "not so good data"
85
+
86
+ last_response.should_not be_ok
87
+ last_response.status.should eql(404)
88
+ end
89
+ end
90
+
91
+ describe "when deleting /schema/:id" do
92
+ it "should delete the schema of the given id" do
93
+ schema = Factory.create(:schema)
94
+ delete "/schema/#{schema.name}"
95
+
96
+ last_response.should be_ok
97
+ end
98
+ it "should not delete anything when an invalid ID is given" do
99
+ delete "/schema/a_bad_id"
100
+
101
+ last_response.should_not be_ok
102
+ last_response.status.should eql 404
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,115 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{yogo-db}
8
+ s.version = "0.2.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Ryan Heimbuch"]
12
+ s.date = %q{2010-10-29}
13
+ s.description = %q{Restful interface to yogo data components}
14
+ s.email = %q{rheimbuch@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ ".rspec",
23
+ "Gemfile",
24
+ "Gemfile.lock",
25
+ "LICENSE",
26
+ "README.rdoc",
27
+ "Rakefile",
28
+ "VERSION",
29
+ "config.ru",
30
+ "config/database.yml",
31
+ "config/datamapper.rb",
32
+ "features/step_definitions/yogo-db_steps.rb",
33
+ "features/support/env.rb",
34
+ "features/yogo-db.feature",
35
+ "lib/yogo-db.rb",
36
+ "lib/yogo/data/default_methods.rb",
37
+ "lib/yogo/data_app.rb",
38
+ "lib/yogo/db/.gitdir",
39
+ "lib/yogo/model/schema.rb",
40
+ "lib/yogo/operations.rb",
41
+ "lib/yogo/operations/basic.rb",
42
+ "lib/yogo/operations/file.rb",
43
+ "lib/yogo/rack/model_lookup.rb",
44
+ "lib/yogo/schema_app.rb",
45
+ "spec/factories/schema.rb",
46
+ "spec/helpers/request_helper.rb",
47
+ "spec/model/schema_spec.rb",
48
+ "spec/spec_helper.rb",
49
+ "spec/yogo/data_app_spec.rb",
50
+ "spec/yogo/model_lookup_spec.rb",
51
+ "spec/yogo/schema_app_spec.rb",
52
+ "yogo-db.gemspec"
53
+ ]
54
+ s.homepage = %q{http://github.com/yogo/yogo-db}
55
+ s.rdoc_options = ["--charset=UTF-8"]
56
+ s.require_paths = ["lib"]
57
+ s.rubygems_version = %q{1.3.7}
58
+ s.summary = %q{Yogo DB Rest components}
59
+ s.test_files = [
60
+ "spec/factories/schema.rb",
61
+ "spec/helpers/request_helper.rb",
62
+ "spec/model/schema_spec.rb",
63
+ "spec/spec_helper.rb",
64
+ "spec/yogo/data_app_spec.rb",
65
+ "spec/yogo/model_lookup_spec.rb",
66
+ "spec/yogo/schema_app_spec.rb"
67
+ ]
68
+
69
+ if s.respond_to? :specification_version then
70
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
71
+ s.specification_version = 3
72
+
73
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
74
+ s.add_runtime_dependency(%q<sinatra>, [">= 0"])
75
+ s.add_runtime_dependency(%q<rack>, [">= 0"])
76
+ s.add_runtime_dependency(%q<activesupport>, [">= 0"])
77
+ s.add_runtime_dependency(%q<dm-core>, [">= 0"])
78
+ s.add_runtime_dependency(%q<dm-migrations>, [">= 0"])
79
+ s.add_runtime_dependency(%q<dm-serializer>, [">= 0"])
80
+ s.add_runtime_dependency(%q<dm-timestamps>, [">= 0"])
81
+ s.add_runtime_dependency(%q<dm-validations>, [">= 0"])
82
+ s.add_runtime_dependency(%q<dm-sqlite-adapter>, [">= 0"])
83
+ s.add_runtime_dependency(%q<dm-postgres-adapter>, [">= 0"])
84
+ s.add_runtime_dependency(%q<json>, [">= 0"])
85
+ s.add_runtime_dependency(%q<carrierwave>, [">= 0"])
86
+ else
87
+ s.add_dependency(%q<sinatra>, [">= 0"])
88
+ s.add_dependency(%q<rack>, [">= 0"])
89
+ s.add_dependency(%q<activesupport>, [">= 0"])
90
+ s.add_dependency(%q<dm-core>, [">= 0"])
91
+ s.add_dependency(%q<dm-migrations>, [">= 0"])
92
+ s.add_dependency(%q<dm-serializer>, [">= 0"])
93
+ s.add_dependency(%q<dm-timestamps>, [">= 0"])
94
+ s.add_dependency(%q<dm-validations>, [">= 0"])
95
+ s.add_dependency(%q<dm-sqlite-adapter>, [">= 0"])
96
+ s.add_dependency(%q<dm-postgres-adapter>, [">= 0"])
97
+ s.add_dependency(%q<json>, [">= 0"])
98
+ s.add_dependency(%q<carrierwave>, [">= 0"])
99
+ end
100
+ else
101
+ s.add_dependency(%q<sinatra>, [">= 0"])
102
+ s.add_dependency(%q<rack>, [">= 0"])
103
+ s.add_dependency(%q<activesupport>, [">= 0"])
104
+ s.add_dependency(%q<dm-core>, [">= 0"])
105
+ s.add_dependency(%q<dm-migrations>, [">= 0"])
106
+ s.add_dependency(%q<dm-serializer>, [">= 0"])
107
+ s.add_dependency(%q<dm-timestamps>, [">= 0"])
108
+ s.add_dependency(%q<dm-validations>, [">= 0"])
109
+ s.add_dependency(%q<dm-sqlite-adapter>, [">= 0"])
110
+ s.add_dependency(%q<dm-postgres-adapter>, [">= 0"])
111
+ s.add_dependency(%q<json>, [">= 0"])
112
+ s.add_dependency(%q<carrierwave>, [">= 0"])
113
+ end
114
+ end
115
+