yogo-db 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.
@@ -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
+