resource_mapper 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.autotest ADDED
@@ -0,0 +1,23 @@
1
+ require 'autotest'
2
+ require 'autotest/fsevent'
3
+
4
+ Autotest.add_hook :initialize do |at|
5
+ at.clear_mappings
6
+ at.failed_results_re = /^\d+\)\n(?:\e\[\d*m)?(?:.*?Error in )?'([^\n]*)'(?: FAILED)?(?:\e\[\d*m)?\n(.*?)\n\n/m
7
+ at.completed_re = /\n(?:\e\[\d*m)?\d* examples?/m
8
+
9
+ at.add_mapping(%r%^examples/.*_example.rb$%) { |filename, _|
10
+ filename
11
+ }
12
+
13
+ at.add_mapping(%r%^lib/droplet/(.*)\.rb$%) { |filename, m|
14
+ ["examples/lib/#{m[1]}_example.rb"]
15
+ }
16
+
17
+ at.add_mapping(%r%^examples/(example_helper|shared/.*)\.rb$%) {
18
+ at.files_matching %r%^examples/.*_example\.rb$%
19
+ }
20
+
21
+ at.testlib = 'examples/example_helper.rb'
22
+ end
23
+
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Adam Elliot
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,17 @@
1
+ = ResourceMapper
2
+
3
+ This project is a derivative of ResourceController. It's modified to run on Sinatra, and is used primarily to create consumable resources, not provide content directly. It's somewhat functional, but not complete and has lots of missing features.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2010 Adam Elliot. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,84 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "resource_mapper"
8
+ gem.summary = %Q{A resource_controller derivate that brings similar functionality to Sinatra, but provides a simple way to create restful APIs}
9
+ gem.description = %Q{Creates a resource for a model in sinatra}
10
+ gem.email = "adam@adamelliot.com"
11
+ gem.homepage = "http://github.com/adamelliot/resource_mapper"
12
+ gem.authors = ["Adam Elliot"]
13
+ gem.add_dependency "sinatra", ">= 1.0"
14
+ gem.add_dependency "activesupport", ">= 2.3.5"
15
+ gem.add_dependency "mongo_mapper", ">= 0.7.6"
16
+ gem.add_development_dependency "micronaut", ">= 0.3.0"
17
+ gem.add_development_dependency "rack-test", ">= 0.5.3"
18
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
19
+ end
20
+ Jeweler::GemcutterTasks.new
21
+ rescue LoadError
22
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
23
+ end
24
+
25
+ begin
26
+ require 'micronaut/rake_task'
27
+ Micronaut::RakeTask.new(:examples) do |examples|
28
+ examples.pattern = 'examples/**/*_example.rb'
29
+ examples.ruby_opts << '-Ilib -Iexamples -rexamples/example_helper.rb'
30
+ end
31
+
32
+ Micronaut::RakeTask.new(:rcov) do |examples|
33
+ examples.pattern = 'examples/**/*_example.rb'
34
+ examples.rcov_opts = %[--exclude "examples/*,gems/*,db/*,/Library/Ruby/*,config/*" --text-summary --sort coverage]
35
+ examples.rcov = true
36
+ end
37
+ rescue
38
+ task :examples do
39
+ abort "Micronaut is not available. In order to run reek, you must: sudo gem install micronaut"
40
+ end
41
+
42
+ task :rcov do
43
+ abort "Micronaut is not available. In order to run reek, you must: sudo gem install micronaut"
44
+ end
45
+ end
46
+
47
+ task :examples => :check_dependencies
48
+
49
+ begin
50
+ require 'reek/adapters/rake_task'
51
+ Reek::RakeTask.new do |t|
52
+ t.fail_on_error = true
53
+ t.verbose = false
54
+ t.source_files = 'lib/**/*.rb'
55
+ end
56
+ rescue LoadError
57
+ task :reek do
58
+ abort "Reek is not available. In order to run reek, you must: sudo gem install reek"
59
+ end
60
+ end
61
+
62
+ begin
63
+ require 'roodi'
64
+ require 'roodi_task'
65
+ RoodiTask.new do |t|
66
+ t.verbose = false
67
+ end
68
+ rescue LoadError
69
+ task :roodi do
70
+ abort "Roodi is not available. In order to run roodi, you must: sudo gem install roodi"
71
+ end
72
+ end
73
+
74
+ task :default => :examples
75
+
76
+ require 'rake/rdoctask'
77
+ Rake::RDocTask.new do |rdoc|
78
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
79
+
80
+ rdoc.rdoc_dir = 'rdoc'
81
+ rdoc.title = "resource_mapper #{version}"
82
+ rdoc.rdoc_files.include('README*')
83
+ rdoc.rdoc_files.include('lib/**/*.rb')
84
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,42 @@
1
+ require 'rubygems'
2
+ require 'micronaut'
3
+
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+
7
+ require 'resource_mapper'
8
+ require 'sinatra/base'
9
+ require 'rack/test'
10
+
11
+
12
+ require File.expand_path(File.dirname(__FILE__)) + '/models'
13
+
14
+ def not_in_editor?
15
+ !(ENV.has_key?('TM_MODE') || ENV.has_key?('EMACS') || ENV.has_key?('VIM'))
16
+ end
17
+
18
+ Micronaut.configure do |config|
19
+ config.color_enabled = not_in_editor?
20
+ config.filter_run :focused => true
21
+
22
+ config.include Rack::Test::Methods
23
+ end
24
+
25
+ # json gem is borked, this will suit our needs
26
+ class Array
27
+ def to_json(*args)
28
+ "[#{self.collect { |v| v.to_json }.join ','}]"
29
+ end
30
+ end
31
+
32
+ class Fixnum
33
+ def to_json(*args)
34
+ self.to_s
35
+ end
36
+ end
37
+
38
+ class String
39
+ def to_json(*args)
40
+ self.to_s
41
+ end
42
+ end
@@ -0,0 +1,150 @@
1
+ describe Sinatra::Resource do
2
+
3
+ class BasicApp < Sinatra::Base
4
+ register Sinatra::Resource
5
+ resource Person
6
+
7
+ get '/normal' do
8
+ puts "Normal"
9
+ end
10
+ end
11
+
12
+ describe "basic resource" do
13
+ def app
14
+ BasicApp
15
+ end
16
+
17
+ before :each do
18
+ Person.reset!
19
+ end
20
+
21
+ it "returns all people in JSON" do
22
+ get '/people'
23
+ last_response.body.should == Person.all.to_json
24
+ end
25
+
26
+ it "returns a specific person as a JSON object" do
27
+ get '/person/2'
28
+ last_response.body.should == Person.find(2).to_json
29
+ end
30
+
31
+ it "creates a new person and return the JSON object" do
32
+ len = Person.all.length
33
+ post '/person.json', {:person => {:id => 4, :name => 'Seth'}}
34
+ Person.all.length.should == len + 1
35
+ last_response.body.should == Person.find(4).to_json
36
+ end
37
+
38
+ it "updates an existing person and returns the JSON object" do
39
+ put '/person/3.json', {:person => {:id => 3, :name => 'Seth'}}
40
+ Person.find(3).name.should == 'Seth'
41
+ last_response.body.should == Person.find(3).to_json
42
+ end
43
+
44
+ it "deletes a record and return it's content in JSON" do
45
+ len = Person.all.length
46
+ delete '/person/3.json'
47
+ last_response.body.should == ""
48
+ Person.all.length.should == len - 1
49
+ end
50
+
51
+ it "fails when requesting an invalid resource" do
52
+ get '/error'
53
+ last_response.should_not be_ok
54
+ end
55
+ end
56
+
57
+ class ActionsRemovedApp < Sinatra::Base
58
+ register Sinatra::Resource
59
+
60
+ helpers do
61
+ def authorized!
62
+ true
63
+ end
64
+ end
65
+
66
+ resource Person do
67
+ actions :all, :except => [:destroy]
68
+
69
+ create.before do
70
+ object.name = object.name.upcase
71
+ end
72
+
73
+ update.before do
74
+ authorized!
75
+ end
76
+ end
77
+ end
78
+
79
+ describe "resource with actions removed" do
80
+ def app
81
+ ActionsRemovedApp
82
+ end
83
+
84
+ before :each do
85
+ Person.reset!
86
+ end
87
+
88
+ it "errors and the records don't get altered" do
89
+ len = Person.all.length
90
+ delete '/person/1.json'
91
+ last_response.should_not be_ok
92
+ Person.all.length.should == len
93
+ end
94
+
95
+ it "sets the name to upper case in the before create section" do
96
+ post '/person.json', {:person => {:id => 4, :name => 'Adam'}}
97
+ last_response.should be_ok
98
+ Person.find(4).name.should == 'ADAM'
99
+ end
100
+
101
+ it "allows calling of sinatra helpers from the actions in the resource" do
102
+ put '/person/1.json', {:person => {:name => 'Astro'}}
103
+ last_response.should be_ok
104
+ Person.find(1).name.should == 'Astro'
105
+ end
106
+ end
107
+
108
+
109
+ class BeforeAndAfterSetsApp < Sinatra::Base
110
+ register Sinatra::Resource
111
+
112
+ helpers do
113
+ def authorized!
114
+ true
115
+ end
116
+ end
117
+
118
+ resource Person do
119
+ before :create, :update do
120
+ object_params[:name].upcase!
121
+ end
122
+
123
+ after :show, :index do
124
+ Person.clear!
125
+ end
126
+ end
127
+ end
128
+
129
+ describe "before and after sets" do
130
+ def app
131
+ BeforeAndAfterSetsApp
132
+ end
133
+
134
+ before :each do
135
+ Person.reset!
136
+ end
137
+
138
+ it "sets the same before action for create and update" do
139
+ post '/person.json', {:person => {:id => 4, :name => 'Adam'}}
140
+ last_response.should be_ok
141
+ Person.find(4).name.should == 'ADAM'
142
+
143
+ put '/person/4.json', {:person => {:id => 4, :name => 'Sandra'}}
144
+ last_response.should be_ok
145
+ Person.find(4).name.should == 'SANDRA'
146
+ end
147
+
148
+ end
149
+
150
+ end
@@ -0,0 +1,77 @@
1
+ # Shamelessly take from sinatra-rest, adjusted for JSON
2
+ require 'active_support/json'
3
+
4
+ class Person
5
+ attr_accessor :id
6
+ attr_accessor :name
7
+
8
+ def initialize(*args)
9
+ if args.size == 0
10
+ @id = nil
11
+ @name = nil
12
+ elsif args.size == 2
13
+ @id = args[0].to_i
14
+ @name = args[1]
15
+ else args.size == 1
16
+ update_attributes(args[0])
17
+ end
18
+ end
19
+
20
+ def save
21
+ if Person.find(self.id)
22
+ Person.delete(self.id)
23
+ else
24
+ self.id = self.id || @@people.size
25
+ end
26
+
27
+ @@people << self
28
+ end
29
+
30
+ def destroy
31
+ Person.delete(self.id)
32
+ end
33
+
34
+ def update_attributes(hash)
35
+ #puts "update_attributes #{hash.inspect}"
36
+ unless hash.empty?
37
+ @id = hash['id'].to_i if hash.include?('id')
38
+ @name = hash['name'] if hash.include?('name')
39
+ end
40
+ end
41
+
42
+ def to_json(_=nil, _=nil)
43
+ "{\"id\":#{id.to_json},\"name\":#{name.to_json}}"
44
+ end
45
+ alias_method :as_json, :to_json
46
+
47
+ def self.delete(id)
48
+ @@people.delete_if {|person| person.id == id.to_i}
49
+ end
50
+
51
+ @@people = []
52
+
53
+ def self.all(criteria={})
54
+ @@people
55
+ end
56
+
57
+ def self.find(arg)
58
+ id = arg.class == Hash ? arg[:id] : arg
59
+ @@people.find {|f| f.id == id.to_i}
60
+ end
61
+ class << self
62
+ alias_method :first, :find
63
+ end
64
+
65
+ def self.clear!
66
+ @@people = []
67
+ end
68
+
69
+ def self.reset!
70
+ clear!
71
+ Person.new(1, 'Al').save
72
+ Person.new(2, 'Sol').save
73
+ Person.new(3, 'Alma').save
74
+ end
75
+ end
76
+
77
+