Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
Checking mergeability… Don't worry, you can still create the pull request.
  • 13 commits
  • 25 files changed
  • 0 commit comments
  • 1 contributor
Commits on Feb 12, 2012
@jnunemaker Move reloading out of attributes and into its own module. d9527d8
@jnunemaker Autoload in preparation for the changes to come. b24169b
@jnunemaker Just require all core extentions.
The paths change in some versions of AS. This should make TS handle those a bit better.
cd65655
@jnunemaker Kill the operation logging.
I'd rather log this at the adapter or adapter client level.
f70ecc8
Commits on Feb 13, 2012
@jnunemaker Rename Dolly to Cloneable.
Smart names aren't smart.
bf0b30b
@jnunemaker Require identity map. Some weirdness when autoloading. b426edc
@jnunemaker Minor: formatting. d8c12f4
@jnunemaker Hookup guard. 9522e87
@jnunemaker Separate dirty tracking of plain objects verse (persistable and query…
…able) stored objects.
0756e3d
@jnunemaker Old file. 7d14698
@jnunemaker Kill watchr. bd70b67
@jnunemaker Adding gemfile lock back in.
Found setting project up on new machine a pain without the lock. I could put development dependencies in gemspec, but that is not as handy as bundler.
d6a4f5b
@jnunemaker Kill autotest. b466556
View
11 .autotest
@@ -1,11 +0,0 @@
-require 'autotest/growl'
-
-Autotest.add_hook(:initialize) {|at|
- at.add_exception %r{^\.git} # ignore Version Control System
- at.add_exception %r{^./tmp} # ignore temp files, lest autotest will run again, and again...
- # at.clear_mappings # take out the default (test/test*rb)
- at.add_mapping(%r{^lib/.*\.rb$}) {|f, _|
- Dir['spec/**/*.rb']
- }
- nil
-}
View
3  .gitignore
@@ -4,5 +4,4 @@ testing/
log
tmp
pkg
-.bundle
-Gemfile.lock
+.bundle
View
5 Gemfile
@@ -2,6 +2,11 @@ source :rubygems
gemspec
group(:development) do
+ gem 'guard'
+ gem 'guard-rspec'
+ gem 'guard-bundler'
+ gem 'growl'
+
gem 'rake', '~> 0.8.7'
gem 'rspec', '~> 2.3'
gem 'timecop', '~> 0.3.5'
View
71 Gemfile.lock
@@ -0,0 +1,71 @@
+PATH
+ remote: .
+ specs:
+ toystore (0.8.3)
+ activemodel (~> 3.0, < 3.2)
+ activesupport (~> 3.0, < 3.2)
+ adapter (~> 0.5.1)
+ simple_uuid (~> 0.1.1)
+
+GEM
+ remote: http://rubygems.org/
+ specs:
+ activemodel (3.1.3)
+ activesupport (= 3.1.3)
+ builder (~> 3.0.0)
+ i18n (~> 0.6)
+ activesupport (3.1.3)
+ multi_json (~> 1.0)
+ adapter (0.5.2)
+ bson (1.5.2)
+ bson_ext (1.5.2)
+ bson (= 1.5.2)
+ builder (3.0.0)
+ diff-lcs (1.1.3)
+ ffi (1.0.11)
+ growl (1.0.3)
+ guard (1.0.0)
+ ffi (>= 0.5.0)
+ thor (~> 0.14.6)
+ guard-bundler (0.1.3)
+ bundler (>= 1.0.0)
+ guard (>= 0.2.2)
+ guard-rspec (0.6.0)
+ guard (>= 0.10.0)
+ i18n (0.6.0)
+ log_buddy (0.5.0)
+ multi_json (1.0.4)
+ rack (1.4.0)
+ rack-test (0.6.1)
+ rack (>= 1.0)
+ rake (0.8.7)
+ rspec (2.8.0)
+ rspec-core (~> 2.8.0)
+ rspec-expectations (~> 2.8.0)
+ rspec-mocks (~> 2.8.0)
+ rspec-core (2.8.0)
+ rspec-expectations (2.8.0)
+ diff-lcs (~> 1.1.2)
+ rspec-mocks (2.8.0)
+ simple_uuid (0.1.2)
+ thor (0.14.6)
+ timecop (0.3.5)
+ tzinfo (0.3.31)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ bson
+ bson_ext
+ growl
+ guard
+ guard-bundler
+ guard-rspec
+ log_buddy (~> 0.5.0)
+ rack-test
+ rake (~> 0.8.7)
+ rspec (~> 2.3)
+ timecop (~> 0.3.5)
+ toystore!
+ tzinfo (~> 0.3.23)
View
15 Guardfile
@@ -0,0 +1,15 @@
+rspec_options = {
+ :all_after_pass => false,
+ :all_on_start => false,
+}
+
+guard 'rspec', rspec_options do
+ watch(%r{^spec/.+_spec\.rb$})
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
+ watch('spec/spec_helper.rb') { "spec" }
+end
+
+guard 'bundler' do
+ watch('Gemfile')
+ watch(/^.+\.gemspec/)
+end
View
12 LOGGING.rdoc
@@ -1,12 +0,0 @@
-What the 3 letter codes mean when they show up in logging:
-
- SET: write to store
- GET: read from store
- DEL: delete from store
- KEY: check if key exists in store
-
- IMG: read from identity map
- IMS: write to identity map
- IMD: delete from identity map
-
- IEM: invalid embedded document
View
68 lib/toy.rb
@@ -9,11 +9,7 @@
require 'simple_uuid'
require 'active_model'
require 'active_support/json'
-require 'active_support/core_ext/object'
-require 'active_support/core_ext/hash/keys'
-require 'active_support/core_ext/class/inheritable_attributes'
-require 'active_support/core_ext/string/conversions'
-require 'active_support/core_ext/string/inflections'
+require 'active_support/core_ext'
extensions_path = root_path.join('lib', 'toy', 'extensions')
Dir[extensions_path + '**/*.rb'].each { |file| require(file) }
@@ -65,36 +61,42 @@ def key_factory
module Middleware
autoload 'IdentityMap', 'toy/middleware/identity_map'
end
+
+ autoload 'Attribute', 'toy/attribute'
+ autoload 'Attribute', 'toy/attribute'
+ autoload 'Attributes', 'toy/attributes'
+ autoload 'Caching', 'toy/caching'
+ autoload 'Callbacks', 'toy/callbacks'
+ autoload 'Dirty', 'toy/dirty'
+ autoload 'DirtyStore', 'toy/dirty_store'
+ autoload 'Cloneable', 'toy/cloneable'
+ autoload 'Equality', 'toy/equality'
+ autoload 'Inspect', 'toy/inspect'
+ autoload 'Logger', 'toy/logger'
+ autoload 'MassAssignmentSecurity', 'toy/mass_assignment_security'
+ autoload 'Persistence', 'toy/persistence'
+ autoload 'Querying', 'toy/querying'
+ autoload 'Reloadable', 'toy/reloadable'
+ autoload 'Serialization', 'toy/serialization'
+ autoload 'Timestamps', 'toy/timestamps'
+ autoload 'Validations', 'toy/validations'
+
+ autoload 'Collection', 'toy/collection'
+ autoload 'EmbeddedList', 'toy/embedded_list'
+ autoload 'EmbeddedLists', 'toy/embedded_lists'
+ autoload 'List', 'toy/list'
+ autoload 'Lists', 'toy/lists'
+ autoload 'Reference', 'toy/reference'
+ autoload 'References', 'toy/references'
+ autoload 'Identity', 'toy/identity'
+
+ module Identity
+ autoload 'AbstractKeyFactory', 'toy/identity/abstract_key_factory'
+ autoload 'UUIDKeyFactory', 'toy/identity/uuid_key_factory'
+ end
end
+require 'toy/identity_map'
require 'toy/exceptions'
-require 'toy/attribute'
-require 'toy/attributes'
-require 'toy/callbacks'
-require 'toy/dirty'
-require 'toy/dolly'
-require 'toy/equality'
-require 'toy/inspect'
-require 'toy/persistence'
-require 'toy/mass_assignment_security'
require 'toy/plugins'
require 'toy/store'
-require 'toy/serialization'
-require 'toy/timestamps'
-require 'toy/validations'
-require 'toy/querying'
-require 'toy/identity_map'
-
-require 'toy/collection'
-require 'toy/embedded_list'
-require 'toy/embedded_lists'
-require 'toy/list'
-require 'toy/lists'
-require 'toy/reference'
-require 'toy/references'
-
-require 'toy/identity/abstract_key_factory'
-require 'toy/identity/uuid_key_factory'
-require 'toy/identity'
-require 'toy/caching'
-require 'toy/logger'
View
14 lib/toy/attributes.rb
@@ -38,20 +38,6 @@ def initialize_from_database(attrs={})
self
end
- def reload
- if attrs = adapter.read(id)
- attrs['id'] = id
- instance_variables.each { |ivar| instance_variable_set(ivar, nil) }
- initialize_attributes_with_defaults
- send(:attributes=, attrs, new_record?)
- self.class.lists.each_key { |name| send(name).reset }
- self.class.references.each_key { |name| send(name).reset }
- else
- raise NotFound.new(id)
- end
- self
- end
-
def id
read_attribute(:id)
end
View
2  lib/toy/dolly.rb → lib/toy/cloneable.rb
@@ -1,5 +1,5 @@
module Toy
- module Dolly
+ module Cloneable
extend ActiveSupport::Concern
def initialize_copy(other)
View
23 lib/toy/dirty.rb
@@ -5,13 +5,8 @@ module Dirty
def initialize(*)
super
- if new_record?
- # never register initial id assignment as a change
- @changed_attributes.delete('id')
- else
- @previously_changed = {}
- @changed_attributes.clear if @changed_attributes
- end
+ # never register initial id assignment as a change
+ @changed_attributes.delete('id') if @changed_attributes
end
def initialize_copy(*)
@@ -21,20 +16,6 @@ def initialize_copy(*)
end
end
- def reload
- super.tap do
- @previously_changed = {}
- @changed_attributes = {}
- end
- end
-
- def save(*)
- super.tap do
- @previously_changed = changes
- @changed_attributes.clear if @changed_attributes
- end
- end
-
def write_attribute(name, value)
name = name.to_s
current = read_attribute(name)
View
32 lib/toy/dirty_store.rb
@@ -0,0 +1,32 @@
+module Toy
+ module DirtyStore
+ extend ActiveSupport::Concern
+ include ActiveModel::Dirty
+ include Reloadable
+ include Persistence
+ include Querying
+
+ def initialize(*)
+ super
+
+ if persisted?
+ @previously_changed = {}
+ @changed_attributes.clear if @changed_attributes
+ end
+ end
+
+ def reload
+ super.tap do
+ @previously_changed = {}
+ @changed_attributes = {}
+ end
+ end
+
+ def save(*)
+ super.tap do
+ @previously_changed = changes
+ @changed_attributes.clear if @changed_attributes
+ end
+ end
+ end
+end
View
7 lib/toy/identity_map.rb
@@ -47,10 +47,7 @@ def get(id)
def get_from_identity_map(id)
return nil unless identity_map_on?
- if record = identity_map[id]
- log_operation(:img, self.name, adapter, id)
- record
- end
+ identity_map[id]
end
def load(id, attrs)
@@ -81,13 +78,11 @@ def delete(*)
def add_to_identity_map
return unless self.class.identity_map_on?
identity_map[id] = self
- log_operation(:ims, self.class.name, adapter, id)
end
def remove_from_identity_map
return unless self.class.identity_map_on?
identity_map.delete(id)
- log_operation(:imd, self.class.name, adapter, id)
end
private
View
13 lib/toy/logger.rb
@@ -3,26 +3,13 @@ module Logger
extend ActiveSupport::Concern
module ClassMethods
- OperationsToLogValueFor = [:get, :set, :del]
-
def logger
Toy.logger
end
-
- def log_operation(operation, model, adapter, key, value=nil)
- if logger && logger.debug?
- logger.debug("TOYSTORE #{operation.to_s.upcase} #{model} :#{adapter.name} #{key.inspect}")
- logger.debug(" #{value.inspect}") if !value.nil? && OperationsToLogValueFor.include?(operation)
- end
- end
end
def logger
Toy.logger
end
-
- def log_operation(*args)
- self.class.log_operation(*args)
- end
end
end
View
2  lib/toy/persistence.rb
@@ -86,7 +86,6 @@ def destroy
def delete
@_destroyed = true
- log_operation(:del, self.class.name, adapter, id)
adapter.delete(id)
end
@@ -108,7 +107,6 @@ def persist!
attrs = persisted_attributes
attrs.delete('id') # no need to persist id as that is key
adapter.write(id, attrs)
- log_operation(:set, self.class.name, adapter, id, attrs)
persist
each_embedded_object { |doc| doc.send(:persist) }
true
View
2  lib/toy/querying.rb
@@ -4,7 +4,6 @@ module Querying
module ClassMethods
def get(id)
- log_operation(:get, self, adapter, id)
load(id, adapter.read(id))
end
@@ -25,7 +24,6 @@ def get_or_create(id)
end
def key?(id)
- log_operation(:key, self, adapter, id)
adapter.key?(id)
end
alias :has_key? :key?
View
17 lib/toy/reloadable.rb
@@ -0,0 +1,17 @@
+module Toy
+ module Reloadable
+ def reload
+ if attrs = adapter.read(id)
+ attrs['id'] = id
+ instance_variables.each { |ivar| instance_variable_set(ivar, nil) }
+ initialize_attributes_with_defaults
+ send(:attributes=, attrs, new_record?)
+ self.class.lists.each_key { |name| send(name).reset }
+ self.class.references.each_key { |name| send(name).reset }
+ else
+ raise NotFound.new(id)
+ end
+ self
+ end
+ end
+end
View
4 lib/toy/store.rb
@@ -10,11 +10,13 @@ module Store
include Identity
include Persistence
include MassAssignmentSecurity
- include Dolly
+ include Cloneable
include Dirty
+ include DirtyStore
include Equality
include Inspect
include Querying
+ include Reloadable
include Callbacks
include Validations
View
1  lib/toy/validations.rb
@@ -20,7 +20,6 @@ def validates_embedded(*names)
invalid.each do |obj|
invalid_messages << [obj.attributes, obj.errors.full_messages]
end
- log_operation(:iem, self.name, adapter, record.id, invalid_messages)
end
end
end
View
76 spec/toy/attributes_spec.rb
@@ -338,82 +338,6 @@
end
end
- describe "#reload" do
- before do
- User.attribute(:name, String)
- @user = User.create(:name => 'John')
- end
- let(:user) { @user }
-
- it "reloads id from database" do
- id = user.id
- user.reload
- user.id.should == id
- end
-
- it "reloads record from the database" do
- user.name = 'Steve'
- user.reload
- user.name.should == 'John'
- end
-
- it "is still persisted" do
- user.should be_persisted
- user.reload
- user.should be_persisted
- end
-
- it "returns the record" do
- user.name = 'Steve'
- user.reload.should equal(user)
- end
-
- it "resets instance variables" do
- user.instance_variable_set("@foo", true)
- user.reload
- user.instance_variable_get("@foo").should be_nil
- end
-
- it "resets lists" do
- User.list(:games)
- game = Game.create
- user.update_attributes(:games => [game])
- user.games = []
- user.games.should == []
- user.reload
- user.games.should == [game]
- end
-
- it "resets references" do
- Game.reference(:user)
- game = Game.create(:user => user)
- game.user = nil
- game.user.should be_nil
- game.reload
- game.user.should == user
- end
-
- it "raises NotFound if does not exist" do
- user.destroy
- lambda { user.reload }.should raise_error(Toy::NotFound)
- end
-
- it "reloads defaults" do
- User.attribute(:skills, Array)
- @user.reload
- @user.skills.should == []
- end
-
- it "reloads attributes protected from mass assignment" do
- User.attribute(:admin, Boolean)
- User.attr_accessible(:name)
- user = User.new(:name => 'John')
- user.admin = true
- user.save
- user.reload.admin.should be_true
- end
- end
-
describe "Initialization of array attributes" do
before do
User.attribute(:skills, Array)
View
2  spec/toy/dolly_spec.rb → spec/toy/cloneable_spec.rb
@@ -1,6 +1,6 @@
require 'helper'
-describe Toy::Dolly do
+describe Toy::Cloneable do
uses_constants('User', 'Game', 'Move')
before do
View
48 spec/toy/dirty_spec.rb
@@ -29,49 +29,11 @@
end
it "knows when attribute did not change" do
- user = User.create(:name => 'Geoffrey')
- user.name = 'Geoffrey'
+ user = User.new
+ user.name = nil
user.should_not be_changed
end
- describe "#save" do
- before { @user = User.create(:name => 'Geoffrey') }
- let(:user) { @user }
-
- it "clears changes" do
- user.name = 'John'
- user.should be_changed
- user.save
- user.should_not be_changed
- end
-
- it "sets previous changes" do
- user.previous_changes.should == {'name' => [nil, 'Geoffrey']}
- end
- end
-
- it "does not have changes when loaded from database" do
- user = User.create
- loaded = User.get(user.id)
- loaded.should_not be_changed
- end
-
- describe "#reload" do
- before { @user = User.create(:name => 'John') }
- let(:user) { @user }
-
- it "clears changes" do
- user.name = 'Steve'
- user.reload
- user.should_not be_changed
- end
-
- it "clears previously changed" do
- user.reload
- user.previous_changes.should be_empty
- end
- end
-
it "has attribute changed? method" do
user = User.new
user.should_not be_name_changed
@@ -80,19 +42,19 @@
end
it "has attribute was method" do
- user = User.create(:name => 'John')
+ user = User.new(:name => 'John')
user.name = 'Steve'
user.name_was.should == 'John'
end
it "has attribute change method" do
- user = User.create(:name => 'John')
+ user = User.new(:name => 'John')
user.name = 'Steve'
user.name_change.should == ['John', 'Steve']
end
it "has attribute will change! method" do
- user = User.create
+ user = User.new
user.name_will_change!
user.should be_changed
end
View
47 spec/toy/dirty_store_spec.rb
@@ -0,0 +1,47 @@
+require 'helper'
+
+describe Toy::DirtyStore do
+ uses_constants('User')
+
+ before do
+ User.attribute(:name, String)
+ end
+
+ it "does not have changes when loaded from database" do
+ user = User.create
+ loaded = User.get(user.id)
+ loaded.should_not be_changed
+ end
+
+ describe "#reload" do
+ before { @user = User.create(:name => 'John') }
+ let(:user) { @user }
+
+ it "clears changes" do
+ user.name = 'Steve'
+ user.reload
+ user.should_not be_changed
+ end
+
+ it "clears previously changed" do
+ user.reload
+ user.previous_changes.should be_empty
+ end
+ end
+
+ describe "#save" do
+ before { @user = User.create(:name => 'Geoffrey') }
+ let(:user) { @user }
+
+ it "clears changes" do
+ user.name = 'John'
+ user.should be_changed
+ user.save
+ user.should_not be_changed
+ end
+
+ it "sets previous changes" do
+ user.previous_changes.should == {'name' => [nil, 'Geoffrey']}
+ end
+ end
+end
View
28 spec/toy/logger_spec.rb
@@ -18,32 +18,4 @@
it "should use Toy.logger for instance" do
User.new.logger.should == Toy.logger
end
-
- describe ".log_operation" do
- let(:adapter) { Adapter[:memory].new({}) }
-
- it "logs operation" do
- Toy.logger = stub(:debug? => true)
- User.logger.should_receive(:debug).with('TOYSTORE GET User :memory "foo"')
- User.logger.should_receive(:debug).with(' "bar"')
- User.log_operation(:get, User, adapter, 'foo', 'bar')
- end
-
- it "ignores operations that should not be logged" do
- Toy.logger = stub(:debug? => true)
- User.logger.should_receive(:debug).with('TOYSTORE IMG User :memory "foo"')
- User.log_operation(:img, User, adapter, 'foo', 'bar')
- end
- end
-
- describe "#log_operation" do
- let(:adapter) { Adapter[:memory].new({}) }
-
- it "logs operation" do
- Toy.logger = stub(:debug? => true)
- User.logger.should_receive(:debug).with('TOYSTORE GET User :memory "foo"')
- User.logger.should_receive(:debug).with(' "bar"')
- User.log_operation(:get, User, adapter, 'foo', 'bar')
- end
- end
end
View
86 spec/toy/reloadable_spec.rb
@@ -0,0 +1,86 @@
+require 'helper'
+
+describe Toy::Reloadable do
+ uses_constants('User', 'Game', 'Move', 'Tile')
+
+ before do
+ Game.embedded_list(:moves)
+ Move.embedded_list(:tiles)
+ end
+
+ describe "#reload" do
+ before do
+ User.attribute(:name, String)
+ @user = User.create(:name => 'John')
+ end
+ let(:user) { @user }
+
+ it "reloads id from database" do
+ id = user.id
+ user.reload
+ user.id.should == id
+ end
+
+ it "reloads record from the database" do
+ user.name = 'Steve'
+ user.reload
+ user.name.should == 'John'
+ end
+
+ it "is still persisted" do
+ user.should be_persisted
+ user.reload
+ user.should be_persisted
+ end
+
+ it "returns the record" do
+ user.name = 'Steve'
+ user.reload.should equal(user)
+ end
+
+ it "resets instance variables" do
+ user.instance_variable_set("@foo", true)
+ user.reload
+ user.instance_variable_get("@foo").should be_nil
+ end
+
+ it "resets lists" do
+ User.list(:games)
+ game = Game.create
+ user.update_attributes(:games => [game])
+ user.games = []
+ user.games.should == []
+ user.reload
+ user.games.should == [game]
+ end
+
+ it "resets references" do
+ Game.reference(:user)
+ game = Game.create(:user => user)
+ game.user = nil
+ game.user.should be_nil
+ game.reload
+ game.user.should == user
+ end
+
+ it "raises NotFound if does not exist" do
+ user.destroy
+ lambda { user.reload }.should raise_error(Toy::NotFound)
+ end
+
+ it "reloads defaults" do
+ User.attribute(:skills, Array)
+ @user.reload
+ @user.skills.should == []
+ end
+
+ it "reloads attributes protected from mass assignment" do
+ User.attribute(:admin, Boolean)
+ User.attr_accessible(:name)
+ user = User.new(:name => 'John')
+ user.admin = true
+ user.save
+ user.reload.admin.should be_true
+ end
+ end
+end
View
52 specs.watchr
@@ -1,52 +0,0 @@
-def growl(title, msg, img)
- %x{growlnotify -m #{ msg.inspect} -t #{title.inspect} --image ~/.watchr/#{img}.png}
-end
-
-def form_growl_message(str)
- msg = str.split("\n").last
- if msg =~ /(\d)\sfailure/
- img = $1.to_i > 0 ? 'fail' : 'pass'
- end
- growl 'Results', msg, img
-end
-
-def run(cmd)
- puts cmd
- output = ""
- IO.popen(cmd) do |com|
- com.each_char do |c|
- print c
- output << c
- $stdout.flush
- end
- end
- form_growl_message output
-end
-
-def run_all
- run('bundle exec rake')
-end
-
-def run_spec(path)
- path.gsub!('lib/', 'spec/')
- path.gsub!('_spec', '')
- file_name = File.basename(path, '.rb')
- path.gsub!(file_name, file_name + "_spec")
- if File.exists?(path)
- system('clear')
- run(%Q(bundle exec rspec #{path}))
- end
-end
-
-watch('spec/helper\.rb') { run_all }
-watch('lib/.*\.rb') { |m| run_spec(m[0]) }
-watch('spec/.*_spec\.rb') { |m| run_spec(m[0]) }
-
-# Ctrl-\
-Signal.trap('QUIT') do
- puts " --- Running all tests ---\n\n"
- run_all
-end
-
-# Ctrl-C
-Signal.trap('INT') { abort("\n") }

No commit comments for this range

Something went wrong with that request. Please try again.