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.
Files changed (51) hide show
  1. data/History.txt +3 -0
  2. data/License.txt +20 -0
  3. data/Manifest.txt +50 -0
  4. data/README.txt +52 -0
  5. data/Rakefile +22 -0
  6. data/bin/stone-gen +70 -0
  7. data/config/hoe.rb +70 -0
  8. data/config/requirements.rb +15 -0
  9. data/lib/stone/callbacks.rb +50 -0
  10. data/lib/stone/core_ext/string.rb +9 -0
  11. data/lib/stone/core_ext/symbol.rb +22 -0
  12. data/lib/stone/data_store.rb +80 -0
  13. data/lib/stone/query.rb +44 -0
  14. data/lib/stone/resource.rb +424 -0
  15. data/lib/stone/version.rb +9 -0
  16. data/lib/stone.rb +55 -0
  17. data/log/debug.log +0 -0
  18. data/sandbox_for_specs/datastore/.stone_metadata +2 -0
  19. data/sandbox_for_specs/datastore/authors/1.yml +12 -0
  20. data/sandbox_for_specs/datastore/authors/2.yml +12 -0
  21. data/sandbox_for_specs/datastore/authors/3.yml +12 -0
  22. data/sandbox_for_specs/datastore/authors/4.yml +12 -0
  23. data/sandbox_for_specs/datastore/authors/5.yml +12 -0
  24. data/sandbox_for_specs/datastore/posts/1.yml +8 -0
  25. data/sandbox_for_specs/datastore/posts/2.yml +8 -0
  26. data/sandbox_for_specs/sample_resources/author.rb +24 -0
  27. data/sandbox_for_specs/sample_resources/comment.rb +9 -0
  28. data/sandbox_for_specs/sample_resources/person.rb +6 -0
  29. data/sandbox_for_specs/sample_resources/post.rb +9 -0
  30. data/script/console +10 -0
  31. data/script/destroy +14 -0
  32. data/script/generate +14 -0
  33. data/script/txt2html +74 -0
  34. data/setup.rb +0 -0
  35. data/spec/callbacks_spec.rb +43 -0
  36. data/spec/query_spec.rb +19 -0
  37. data/spec/resource_spec.rb +190 -0
  38. data/spec/spec_helper.rb +7 -0
  39. data/spec/stone_spec.rb +12 -0
  40. data/spec/string_spec.rb +16 -0
  41. data/spec/symbol_spec.rb +16 -0
  42. data/tasks/deployment.rake +34 -0
  43. data/tasks/environment.rake +7 -0
  44. data/tasks/website.rake +17 -0
  45. data/website/images/stone.png +0 -0
  46. data/website/index.html +392 -0
  47. data/website/index.txt +245 -0
  48. data/website/javascripts/rounded_corners_lite.inc.js +285 -0
  49. data/website/stylesheets/screen.css +150 -0
  50. data/website/template.html.erb +48 -0
  51. 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
@@ -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
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+ require 'lib/stone'
4
+
5
+ def get_resources
6
+ @resources = Dir.glob(STONE_ROOT/"sandbox_for_specs"/"sample_resources/*")
7
+ end
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,7 @@
1
+ task :ruby_env do
2
+ RUBY_APP = if RUBY_PLATFORM =~ /java/
3
+ "jruby"
4
+ else
5
+ "ruby"
6
+ end unless defined? RUBY_APP
7
+ end
@@ -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