stone 0.1.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/History.txt +3 -0
- data/License.txt +20 -0
- data/Manifest.txt +50 -0
- data/README.txt +52 -0
- data/Rakefile +22 -0
- data/bin/stone-gen +70 -0
- data/config/hoe.rb +70 -0
- data/config/requirements.rb +15 -0
- data/lib/stone/callbacks.rb +50 -0
- data/lib/stone/core_ext/string.rb +9 -0
- data/lib/stone/core_ext/symbol.rb +22 -0
- data/lib/stone/data_store.rb +80 -0
- data/lib/stone/query.rb +44 -0
- data/lib/stone/resource.rb +424 -0
- data/lib/stone/version.rb +9 -0
- data/lib/stone.rb +55 -0
- data/log/debug.log +0 -0
- data/sandbox_for_specs/datastore/.stone_metadata +2 -0
- data/sandbox_for_specs/datastore/authors/1.yml +12 -0
- data/sandbox_for_specs/datastore/authors/2.yml +12 -0
- data/sandbox_for_specs/datastore/authors/3.yml +12 -0
- data/sandbox_for_specs/datastore/authors/4.yml +12 -0
- data/sandbox_for_specs/datastore/authors/5.yml +12 -0
- data/sandbox_for_specs/datastore/posts/1.yml +8 -0
- data/sandbox_for_specs/datastore/posts/2.yml +8 -0
- data/sandbox_for_specs/sample_resources/author.rb +24 -0
- data/sandbox_for_specs/sample_resources/comment.rb +9 -0
- data/sandbox_for_specs/sample_resources/person.rb +6 -0
- data/sandbox_for_specs/sample_resources/post.rb +9 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +74 -0
- data/setup.rb +0 -0
- data/spec/callbacks_spec.rb +43 -0
- data/spec/query_spec.rb +19 -0
- data/spec/resource_spec.rb +190 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/stone_spec.rb +12 -0
- data/spec/string_spec.rb +16 -0
- data/spec/symbol_spec.rb +16 -0
- data/tasks/deployment.rake +34 -0
- data/tasks/environment.rake +7 -0
- data/tasks/website.rake +17 -0
- data/website/images/stone.png +0 -0
- data/website/index.html +392 -0
- data/website/index.txt +245 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +150 -0
- data/website/template.html.erb +48 -0
- metadata +143 -0
data/script/txt2html
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
begin
|
5
|
+
require 'newgem'
|
6
|
+
rescue LoadError
|
7
|
+
puts "\n\nGenerating the website requires the newgem RubyGem"
|
8
|
+
puts "Install: gem install newgem\n\n"
|
9
|
+
exit(1)
|
10
|
+
end
|
11
|
+
require 'redcloth'
|
12
|
+
require 'syntax/convertors/html'
|
13
|
+
require 'erb'
|
14
|
+
require File.dirname(__FILE__) + '/../lib/stone/version.rb'
|
15
|
+
|
16
|
+
version = Stone::VERSION::STRING
|
17
|
+
download = 'http://rubyforge.org/projects/stone'
|
18
|
+
|
19
|
+
class Fixnum
|
20
|
+
def ordinal
|
21
|
+
# teens
|
22
|
+
return 'th' if (10..19).include?(self % 100)
|
23
|
+
# others
|
24
|
+
case self % 10
|
25
|
+
when 1: return 'st'
|
26
|
+
when 2: return 'nd'
|
27
|
+
when 3: return 'rd'
|
28
|
+
else return 'th'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Time
|
34
|
+
def pretty
|
35
|
+
return "#{mday}#{mday.ordinal} #{strftime('%B')} #{year}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def convert_syntax(syntax, source)
|
40
|
+
return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')
|
41
|
+
end
|
42
|
+
|
43
|
+
if ARGV.length >= 1
|
44
|
+
src, template = ARGV
|
45
|
+
template ||= File.join(File.dirname(__FILE__), '/../website/template.html.erb')
|
46
|
+
|
47
|
+
else
|
48
|
+
puts("Usage: #{File.split($0).last} source.txt [template.html.erb] > output.html")
|
49
|
+
exit!
|
50
|
+
end
|
51
|
+
|
52
|
+
template = ERB.new(File.open(template).read)
|
53
|
+
|
54
|
+
title = nil
|
55
|
+
body = nil
|
56
|
+
File.open(src) do |fsrc|
|
57
|
+
title_text = fsrc.readline
|
58
|
+
body_text = fsrc.read
|
59
|
+
syntax_items = []
|
60
|
+
body_text.gsub!(%r!<(pre|code)[^>]*?syntax=['"]([^'"]+)[^>]*>(.*?)</\1>!m){
|
61
|
+
ident = syntax_items.length
|
62
|
+
element, syntax, source = $1, $2, $3
|
63
|
+
syntax_items << "<#{element} class='syntax'>#{convert_syntax(syntax, source)}</#{element}>"
|
64
|
+
"syntax-temp-#{ident}"
|
65
|
+
}
|
66
|
+
title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip
|
67
|
+
body = RedCloth.new(body_text).to_html
|
68
|
+
body.gsub!(%r!(?:<pre><code>)?syntax-temp-(\d+)(?:</code></pre>)?!){ syntax_items[$1.to_i] }
|
69
|
+
end
|
70
|
+
stat = File.stat(src)
|
71
|
+
created = stat.ctime
|
72
|
+
modified = stat.mtime
|
73
|
+
|
74
|
+
$stdout << template.result(binding)
|
data/setup.rb
ADDED
File without changes
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "spec_helper")
|
2
|
+
|
3
|
+
describe Stone::Callbacks do
|
4
|
+
before(:all) do
|
5
|
+
get_resources
|
6
|
+
Stone.start(STONE_ROOT/"sandbox_for_specs", @resources)
|
7
|
+
|
8
|
+
class Dude
|
9
|
+
include Stone::Resource
|
10
|
+
|
11
|
+
def raise_hell
|
12
|
+
raise "Zomgz!"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
before(:each) do
|
18
|
+
@c = Stone::Callbacks.new
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should register a class for callbacks" do
|
22
|
+
@c.register_klass(Dude)
|
23
|
+
@c.include?(:dude).should be_true
|
24
|
+
@c[:dude].include?(:before_save).should be_true
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should register a method to execute for a given callback" do
|
28
|
+
@c.register_klass(Dude)
|
29
|
+
@c.register(:before_save, :raise_hell, Dude)
|
30
|
+
@c[:dude][:before_save].include?(:raise_hell).should be_true
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should fire the correct method when a callback is executed" do
|
34
|
+
# had to define say_hello to raise an error because fire() always
|
35
|
+
# returns true
|
36
|
+
|
37
|
+
@c.register_klass(Dude)
|
38
|
+
@c.register(:before_save, :raise_hell, Dude)
|
39
|
+
|
40
|
+
# raises "Zomgz!"
|
41
|
+
Dude.class_eval {fire(:before_save)}.should raise_error
|
42
|
+
end
|
43
|
+
end
|
data/spec/query_spec.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "spec_helper")
|
2
|
+
|
3
|
+
describe Stone::Query do
|
4
|
+
before(:all) do
|
5
|
+
get_resources
|
6
|
+
Stone.start(STONE_ROOT/"sandbox_for_specs", @resources)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should craft a correct Query when initialized" do
|
10
|
+
q = Stone::Query.new("email", :lt)
|
11
|
+
q.field.should == "email"
|
12
|
+
q.op.should == ".<"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should craft a proper expression for a given argument" do
|
16
|
+
q = Stone::Query.new("email", :not)
|
17
|
+
q.expression_for("nick@cladby.com").should == "email.!=('nick@cladby.com')"
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,190 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "spec_helper")
|
2
|
+
|
3
|
+
describe Stone::Resource do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
get_resources
|
7
|
+
Stone.start(STONE_ROOT/"sandbox_for_specs", @resources)
|
8
|
+
end
|
9
|
+
|
10
|
+
before(:each) do
|
11
|
+
@author = Author.new
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should extend any class in which it is included" do
|
15
|
+
class Blah #:nodoc:
|
16
|
+
include Stone::Resource
|
17
|
+
end
|
18
|
+
Blah.new.respond_to?(:field).should be_true
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should be valid when validates_ methods are fulfilled" do
|
22
|
+
@author.name = "Nick DeMonner"
|
23
|
+
@author.email = "nick@cladby.com"
|
24
|
+
@author.should be_valid
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should be invalid when validates_ methods are not fulfilled" do
|
28
|
+
@author.name = "Nick DeMonner"
|
29
|
+
@author.should_not be_valid
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should be invalid when a field's class does not match its declaration" do
|
33
|
+
@author.name = 3
|
34
|
+
@author.email = "nick@cladby.com"
|
35
|
+
@author.save.should_not be_true
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should create a yaml file for each saved object" do
|
39
|
+
@author.name = "Nick DeMonner"
|
40
|
+
@author.email = "nick@cladby.com"
|
41
|
+
@author.save
|
42
|
+
File.exists?(Stone::DataStore.local_dir/"authors"/"1.yml").should be_true
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should create an object whose id is last object.id + 1" do
|
46
|
+
@author.id.should == 2
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should not save unless all validations pass" do
|
50
|
+
@author.name = "Heyo McGee"
|
51
|
+
@author.save.should_not be_true
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should find and return an object using get" do
|
55
|
+
@author.name = "Mike McMichaels"
|
56
|
+
@author.email = "heyo@something.com"
|
57
|
+
@author.save
|
58
|
+
person = Author.get(@author.id)
|
59
|
+
person.name.should == "Mike McMichaels"
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should find and return an object using []" do
|
63
|
+
@author.name = "Mary Poppins"
|
64
|
+
@author.email = "weyo@something.com"
|
65
|
+
@author.save
|
66
|
+
person = Author[@author.id]
|
67
|
+
person.name.should == "Mary Poppins"
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should accept Resource.find(hash) form" do
|
71
|
+
author = Author.first(:name => "Nick DeMonner")
|
72
|
+
author.should be_instance_of(Author)
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should accept be able to find an object using a regex" do
|
76
|
+
author = Author.first(:name.matches => /nick/i)
|
77
|
+
author.should be_instance_of(Author)
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should raise an exception anything other than a Hash is provided for find" do
|
81
|
+
lambda {Author.first("Nick")}.should raise_error
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should find and return all objects that match conditions provided" do
|
85
|
+
@author.name = "Nick Hicklesby"
|
86
|
+
@author.email = "nick@gmail.com"
|
87
|
+
@author.save
|
88
|
+
people = Author.all(:name.includes => "Nick")
|
89
|
+
people.size.should == 2
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should find and return the first object that matches conditions provided" do
|
93
|
+
person = Author.first(:name.equals => 'Nick DeMonner')
|
94
|
+
person.id.should == 1
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should let .first and .all work with fields that aren't Strings" do
|
98
|
+
@author.name = "Higglesby Wordsworth"
|
99
|
+
@author.email = "higglebear@higgly.com"
|
100
|
+
@author.favorite_number = 3
|
101
|
+
@author.save
|
102
|
+
Author.first(:favorite_number.equals => 3).should be_instance_of(Author)
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should perform a put if the object already exists on save" do
|
106
|
+
author = Author.first(:name.equals => 'Nick DeMonner')
|
107
|
+
author.email = "nick@bzzybee.com"
|
108
|
+
author.save
|
109
|
+
Author.get(author.id).email.should == "nick@bzzybee.com"
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should delete an object and it's yaml file upon Resource.delete" do
|
113
|
+
author = Author.first(:favorite_number.equals => 3)
|
114
|
+
Author.delete(author.id).should be_true
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should execute Resource callbacks" do
|
118
|
+
@author.name = "ben hurr"
|
119
|
+
@author.email = "chariot_guy@hotmail.com"
|
120
|
+
@author.save
|
121
|
+
@author.name.should == "Ben Hurr"
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should not save if there is a duplicate and the field is unique" do
|
125
|
+
@author.name = "John Doe"
|
126
|
+
@author.email = "nick@bzzybee.com"
|
127
|
+
@author.save.should_not be_true
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should retrieve a parent object if belongs_to has been set" do
|
131
|
+
@post = Post.new
|
132
|
+
@post.title = "Stone is Cool"
|
133
|
+
@post.body = "Stone is cool because..."
|
134
|
+
author = Author.first(:name.equals => 'Nick DeMonner')
|
135
|
+
@post.author_id = author.id
|
136
|
+
@post.save
|
137
|
+
@post.author.should be_instance_of(Author)
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should retrieve children objects id has_many has been set" do
|
141
|
+
@post = Post.new
|
142
|
+
@post.title = "Stone is Awesome"
|
143
|
+
@post.body = "Stone is awesome because..."
|
144
|
+
author = Author.first(:name.equals => 'Nick DeMonner')
|
145
|
+
@post.author_id = author.id
|
146
|
+
@post.save
|
147
|
+
author.posts.size.should == 2
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should accept Resource.new(hash) form" do
|
151
|
+
@author = Author.new(:name => "Ron DeMonner", :email => "ron@cladby.com")
|
152
|
+
@author.should be_valid
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should accept Resource.new(params[:resource]) form" do
|
156
|
+
params = {}
|
157
|
+
params[:author] = {:name => "Ron DeMonner", :email => "ron@cladby.com"}
|
158
|
+
@author = Author.new(params[:author])
|
159
|
+
@author.should be_valid
|
160
|
+
end
|
161
|
+
|
162
|
+
it "should accept Resource.update_attributes(hash)" do
|
163
|
+
params = {}
|
164
|
+
params[:author] = {:name => "Ron DeMonner", :email => "ron@cladby.com"}
|
165
|
+
|
166
|
+
plain_hash = {:name => "Nick DeMonner", :email => "nick@cladby.com"}
|
167
|
+
|
168
|
+
author = Author.first(:name => "Nick DeMonner")
|
169
|
+
author.update_attributes(params[:author]).should be_true
|
170
|
+
author.update_attributes(plain_hash).should be_true
|
171
|
+
end
|
172
|
+
|
173
|
+
it "should allow an attribute to accessed via obj[attribute]" do
|
174
|
+
author = Author.first(:name => "Nick DeMonner")
|
175
|
+
author[:id].should == 1
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should allow for DateTime queries" do
|
179
|
+
# bring back all authors who were created before a month from now
|
180
|
+
# i.e., bring all of them back
|
181
|
+
authors = Author.all(:created_at.lt => DateTime.now>>1)
|
182
|
+
authors.size.should == 5
|
183
|
+
end
|
184
|
+
|
185
|
+
it "should allow for complex queries" do
|
186
|
+
authors = Author.all(:name.matches => /o/, :created_at.lt => DateTime.now>>1)
|
187
|
+
authors.size.should == 2
|
188
|
+
end
|
189
|
+
|
190
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/spec/stone_spec.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "spec_helper")
|
2
|
+
|
3
|
+
describe Stone do
|
4
|
+
before(:all) do
|
5
|
+
get_resources
|
6
|
+
Stone.start(STONE_ROOT/"sandbox_for_specs", @resources)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should create a new, blank datastore at a given path" do
|
10
|
+
File.exists?(STONE_ROOT/"sandbox_for_specs"/"datastore").should be_true
|
11
|
+
end
|
12
|
+
end
|
data/spec/string_spec.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "spec_helper")
|
2
|
+
|
3
|
+
describe String do
|
4
|
+
before(:all) do
|
5
|
+
get_resources
|
6
|
+
Stone.start(STONE_ROOT/"sandbox_for_specs", @resources)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should correctly form paths using /" do
|
10
|
+
("this"/"should"/"work").should == "this/should/work"
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should make a proper key given a stringified class" do
|
14
|
+
String.to_s.make_key.should == :string
|
15
|
+
end
|
16
|
+
end
|
data/spec/symbol_spec.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "spec_helper")
|
2
|
+
|
3
|
+
describe Symbol do
|
4
|
+
before(:all) do
|
5
|
+
get_resources
|
6
|
+
Stone.start(STONE_ROOT/"sandbox_for_specs", @resources)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should return a correct Query when a comparison method is used" do
|
10
|
+
:name.gt.should be_instance_of(Stone::Query)
|
11
|
+
:name.gt.op.should == ".>"
|
12
|
+
|
13
|
+
:name.matches.should be_instance_of(Stone::Query)
|
14
|
+
:name.matches.op.should == ".=~"
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
desc 'Release the website and new gem version'
|
2
|
+
task :deploy => [:check_version, :website, :release] do
|
3
|
+
puts "Remember to create SVN tag:"
|
4
|
+
puts "svn copy svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/trunk " +
|
5
|
+
"svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/tags/REL-#{VERS} "
|
6
|
+
puts "Suggested comment:"
|
7
|
+
puts "Tagging release #{CHANGES}"
|
8
|
+
end
|
9
|
+
|
10
|
+
desc 'Runs tasks website_generate and install_gem as a local deployment of the gem'
|
11
|
+
task :local_deploy => [:website_generate, :install_gem]
|
12
|
+
|
13
|
+
task :check_version do
|
14
|
+
unless ENV['VERSION']
|
15
|
+
puts 'Must pass a VERSION=x.y.z release version'
|
16
|
+
exit
|
17
|
+
end
|
18
|
+
unless ENV['VERSION'] == VERS
|
19
|
+
puts "Please update your version.rb to match the release version, currently #{VERS}"
|
20
|
+
exit
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
desc 'Install the package as a gem, without generating documentation(ri/rdoc)'
|
25
|
+
task :install_gem_no_doc => [:clean, :package] do
|
26
|
+
sh "#{'sudo ' unless Hoe::WINDOZE }gem install pkg/*.gem --no-rdoc --no-ri"
|
27
|
+
end
|
28
|
+
|
29
|
+
namespace :manifest do
|
30
|
+
desc 'Recreate Manifest.txt to include ALL files'
|
31
|
+
task :refresh do
|
32
|
+
`rake check_manifest | patch -p0 > Manifest.txt`
|
33
|
+
end
|
34
|
+
end
|
data/tasks/website.rake
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
desc 'Generate website files'
|
2
|
+
task :website_generate => :ruby_env do
|
3
|
+
(Dir['website/**/*.txt'] - Dir['website/version*.txt']).each do |txt|
|
4
|
+
sh %{ #{RUBY_APP} script/txt2html #{txt} > #{txt.gsub(/txt$/,'html')} }
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
desc 'Upload website files to rubyforge'
|
9
|
+
task :website_upload do
|
10
|
+
host = "#{rubyforge_username}@rubyforge.org"
|
11
|
+
remote_dir = "/var/www/gforge-projects/#{PATH}/"
|
12
|
+
local_dir = 'website'
|
13
|
+
sh %{rsync -aCv #{local_dir}/ #{host}:#{remote_dir}}
|
14
|
+
end
|
15
|
+
|
16
|
+
desc 'Generate and upload website files'
|
17
|
+
task :website => [:website_generate, :website_upload, :publish_docs]
|
Binary file
|