matic 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.
@@ -0,0 +1,3 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color --format documentation
data/.rvmrc ADDED
@@ -0,0 +1,2 @@
1
+ rvm --create use 1.9.2@matic
2
+ rvm wrapper 1.9.2@matic
@@ -0,0 +1,3 @@
1
+ = 0.1.0
2
+
3
+ * Initial release
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in matic.gemspec
4
+ gemspec
@@ -0,0 +1,50 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ matic (0.1.0)
5
+ activemodel (~> 3.0.0)
6
+ activesupport (~> 3.0.0)
7
+ mongomatic (~> 0.6.0)
8
+
9
+ GEM
10
+ remote: http://rubygems.org/
11
+ specs:
12
+ activemodel (3.0.1)
13
+ activesupport (= 3.0.1)
14
+ builder (~> 2.1.2)
15
+ i18n (~> 0.4.1)
16
+ activesupport (3.0.1)
17
+ bson (1.1.2)
18
+ bson_ext (1.1.2)
19
+ builder (2.1.2)
20
+ diff-lcs (1.1.2)
21
+ i18n (0.4.2)
22
+ mongo (1.1.2)
23
+ bson (>= 1.1.1)
24
+ mongomatic (0.6.1)
25
+ activesupport (>= 2.3.5)
26
+ bson (~> 1.1)
27
+ mongo (~> 1.1)
28
+ rake (0.8.7)
29
+ rspec (2.0.1)
30
+ rspec-core (~> 2.0.1)
31
+ rspec-expectations (~> 2.0.1)
32
+ rspec-mocks (~> 2.0.1)
33
+ rspec-core (2.0.1)
34
+ rspec-expectations (2.0.1)
35
+ diff-lcs (>= 1.1.2)
36
+ rspec-mocks (2.0.1)
37
+ rspec-core (~> 2.0.1)
38
+ rspec-expectations (~> 2.0.1)
39
+
40
+ PLATFORMS
41
+ ruby
42
+
43
+ DEPENDENCIES
44
+ activemodel (~> 3.0.0)
45
+ activesupport (~> 3.0.0)
46
+ bson_ext (~> 1.1.0)
47
+ matic!
48
+ mongomatic (~> 0.6.0)
49
+ rake (~> 0.8.7)
50
+ rspec (~> 2.0.0)
@@ -0,0 +1,31 @@
1
+ # Matic
2
+
3
+ Matic adds attribute accessors and dirty tracking to Mongomatic.
4
+
5
+ ## Examples
6
+
7
+ class Person < Mongomatic::Base
8
+ include Matic
9
+
10
+ field :name
11
+ end
12
+
13
+ person = Person.new
14
+ person.name = "John Doe"
15
+
16
+ person.name_changed?
17
+ => true
18
+
19
+ person.changes["name"]
20
+ => [nil, "John Doe"]
21
+
22
+ person.insert
23
+
24
+ person.name_changed?
25
+ => false
26
+
27
+ person.changes["name"]
28
+ => nil
29
+
30
+ person.previous_changes["name"]
31
+ => [nil, "John Doe"]
@@ -0,0 +1,11 @@
1
+ require "bundler"
2
+ require "rspec/core/rake_task"
3
+
4
+ Bundler::GemHelper.install_tasks
5
+
6
+ desc "Run all specs in spec directory"
7
+ RSpec::Core::RakeTask.new(:spec) do |spec|
8
+ spec.pattern = "spec/**/*_spec.rb"
9
+ end
10
+
11
+ task :default => :spec
@@ -0,0 +1,71 @@
1
+ require "active_model"
2
+
3
+ module Matic
4
+ extend ActiveSupport::Concern
5
+ include ActiveModel::Dirty
6
+
7
+ module ClassMethods
8
+ def collection_name
9
+ self.name.tableize
10
+ end
11
+
12
+ def field(attr_name)
13
+ # Plagiarized from ActiveModel
14
+ attribute_method_matchers.each do |matcher|
15
+ unless instance_method_already_implemented?(matcher.method_name(attr_name))
16
+ generate_method = "define_method_#{matcher.prefix}attribute#{matcher.suffix}"
17
+
18
+ if respond_to?(generate_method)
19
+ send(generate_method, attr_name)
20
+ else
21
+ method_name = matcher.method_name(attr_name)
22
+
23
+ generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
24
+ if method_defined?(:#{method_name})
25
+ undef :#{method_name}
26
+ end
27
+ def #{method_name}(*args)
28
+ send(:#{matcher.method_missing_target}, '#{attr_name}', *args)
29
+ end
30
+ STR
31
+ end
32
+ end
33
+ end
34
+
35
+ define_method(attr_name) do
36
+ self[attr_name.to_s]
37
+ end
38
+
39
+ define_method("#{attr_name}=") do |val|
40
+ eval("#{attr_name}_will_change!") unless val == self[attr_name.to_s]
41
+ self[attr_name.to_s] = val
42
+ end
43
+ end
44
+ end
45
+
46
+ def insert(opts={})
47
+ if super
48
+ @previously_changed = changes
49
+ @changed_attributes.clear
50
+ end
51
+ end
52
+
53
+ def insert!(opts={})
54
+ insert(opts.merge(:safe => true))
55
+ end
56
+
57
+ def update(opts={}, update_doc=@doc)
58
+ if super
59
+ @previously_changed = changes
60
+ @changed_attributes.clear
61
+ end
62
+ end
63
+
64
+ def update!(opts={}, update_doc=@doc)
65
+ update(opts.merge(:safe => true), update_doc)
66
+ end
67
+
68
+ def save
69
+ is_new ? insert : update
70
+ end
71
+ end
@@ -0,0 +1,3 @@
1
+ module Matic
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "matic/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "matic"
7
+ s.version = Matic::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Hakan Ensari", "Gerhard Lazu"]
10
+ s.email = ["code@papercavalier.com"]
11
+ s.homepage = "http://github.com/papercavalier/matic"
12
+ s.summary = %q{Mongomatic with attribute accessors and dirty tracking}
13
+ s.description = %q{Matic adds attribute accessors and dirty tracking to Mongomatic.}
14
+
15
+ s.rubyforge_project = "matic"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_dependency("mongomatic", "~> 0.6.0")
23
+ s.add_dependency("activemodel", "~> 3.0.0")
24
+ s.add_dependency("activesupport", "~> 3.0.0")
25
+ s.add_development_dependency("bson_ext", "~> 1.1.0")
26
+ s.add_development_dependency("rake", "~> 0.8.7")
27
+ s.add_development_dependency("rspec", "~> 2.0.0")
28
+ #s.add_development_dependency("ruby-debug19", "~> 0.11.0")
29
+ end
@@ -0,0 +1,139 @@
1
+ require "spec_helper"
2
+
3
+ describe "A matic model" do
4
+
5
+ let(:person) { Person.new }
6
+
7
+ it "has a collection first_name" do
8
+ person.class.collection_name.should eql "people"
9
+ end
10
+
11
+ describe ".field" do
12
+ it "defines a getter" do
13
+ person["first_name"] = "John"
14
+
15
+ person.first_name.should eql "John"
16
+ lambda { person.foo }.should raise_error NoMethodError
17
+ end
18
+
19
+ it "defines a setter" do
20
+ person.first_name = "John"
21
+
22
+ person["first_name"].should eql "John"
23
+ lambda { person.foo= "bar" }.should raise_error NoMethodError
24
+ end
25
+ end
26
+
27
+ context "dirty tracking" do
28
+
29
+ shared_examples_for "a dirty-tracking command" do
30
+
31
+ it "marks a current change as previous" do
32
+ person.first_name_changed?.should be_false
33
+ person.previous_changes["first_name"].should eql [nil, "John"]
34
+
35
+ person.last_name_changed?.should be_false
36
+ person.previous_changes["last_name"].should eql [nil, "Doe"]
37
+ end
38
+
39
+ it "does callbacks" do
40
+ person.instance_variable_get(:@called_back).should be_true
41
+ end
42
+
43
+ end
44
+
45
+ shared_examples_for "a dirty object" do
46
+
47
+ it "tells if an attribute changed" do
48
+ person.first_name_changed?.should be_true
49
+ person.last_name_changed?.should be_true
50
+ end
51
+
52
+ it "remembers changes to an attribute" do
53
+ person.changes["first_name"].should eql [nil, "John"]
54
+ person.changes["last_name"].should eql [nil, "Doe"]
55
+ end
56
+
57
+ end
58
+
59
+ context "when object is new" do
60
+
61
+ before do
62
+ person.first_name = "John"
63
+ person.last_name = "Doe"
64
+ end
65
+
66
+ it_behaves_like "a dirty object"
67
+
68
+ describe "#insert" do
69
+
70
+ before { person.insert }
71
+
72
+ it_behaves_like "a dirty-tracking command"
73
+
74
+ end
75
+
76
+ describe "#insert!" do
77
+
78
+ before { person.insert! }
79
+
80
+ it_behaves_like "a dirty-tracking command"
81
+
82
+ end
83
+
84
+ describe "#save" do
85
+
86
+ before { person.save }
87
+
88
+ it_behaves_like "a dirty-tracking command"
89
+
90
+ end
91
+
92
+ end
93
+
94
+ context "when object is not new" do
95
+
96
+ before do
97
+ person.insert
98
+ person.instance_variable_set(:@called_back, false)
99
+ person.first_name = "John"
100
+ person.last_name = "Doe"
101
+ end
102
+
103
+ it_behaves_like "a dirty object"
104
+
105
+ describe "#update" do
106
+
107
+ before { person.update }
108
+
109
+ it_behaves_like "a dirty-tracking command"
110
+
111
+ end
112
+
113
+ describe "#update!" do
114
+
115
+ before { person.update! }
116
+
117
+ it_behaves_like "a dirty-tracking command"
118
+
119
+ end
120
+
121
+ end
122
+
123
+ context "when object is not valid" do
124
+
125
+ before do
126
+ person.stub!(:valid?).and_return(false)
127
+ person.first_name = "John"
128
+ end
129
+
130
+ it "does not clear changes" do
131
+ person.save
132
+ person.first_name_changed?.should be_true
133
+ end
134
+
135
+ end
136
+
137
+ end
138
+
139
+ end
@@ -0,0 +1,16 @@
1
+ class Person < Mongomatic::Base
2
+ include Matic
3
+
4
+ field :first_name
5
+ field :last_name
6
+
7
+ private
8
+
9
+ def before_update
10
+ @called_back = true
11
+ end
12
+
13
+ def before_insert
14
+ @called_back = true
15
+ end
16
+ end
@@ -0,0 +1,10 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+ require "rspec"
4
+
5
+ require File.expand_path("../../lib/matic", __FILE__)
6
+
7
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
8
+
9
+ Dir["#{File.dirname(__FILE__)}/models/**/*.rb"].each { |f| require f }
10
+
@@ -0,0 +1,3 @@
1
+ require "mongomatic"
2
+
3
+ Mongomatic.db = Mongo::Connection.new.db("matic_test")
@@ -0,0 +1,2 @@
1
+ rvm ree@matic,1.9.2@matic exec bundle install
2
+ rvm ree@matic,1.9.2@matic rake
metadata ADDED
@@ -0,0 +1,182 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: matic
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Hakan Ensari
14
+ - Gerhard Lazu
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2010-11-11 00:00:00 +00:00
20
+ default_executable:
21
+ dependencies:
22
+ - !ruby/object:Gem::Dependency
23
+ name: mongomatic
24
+ prerelease: false
25
+ requirement: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ hash: 7
31
+ segments:
32
+ - 0
33
+ - 6
34
+ - 0
35
+ version: 0.6.0
36
+ type: :runtime
37
+ version_requirements: *id001
38
+ - !ruby/object:Gem::Dependency
39
+ name: activemodel
40
+ prerelease: false
41
+ requirement: &id002 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ hash: 7
47
+ segments:
48
+ - 3
49
+ - 0
50
+ - 0
51
+ version: 3.0.0
52
+ type: :runtime
53
+ version_requirements: *id002
54
+ - !ruby/object:Gem::Dependency
55
+ name: activesupport
56
+ prerelease: false
57
+ requirement: &id003 !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ~>
61
+ - !ruby/object:Gem::Version
62
+ hash: 7
63
+ segments:
64
+ - 3
65
+ - 0
66
+ - 0
67
+ version: 3.0.0
68
+ type: :runtime
69
+ version_requirements: *id003
70
+ - !ruby/object:Gem::Dependency
71
+ name: bson_ext
72
+ prerelease: false
73
+ requirement: &id004 !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ~>
77
+ - !ruby/object:Gem::Version
78
+ hash: 19
79
+ segments:
80
+ - 1
81
+ - 1
82
+ - 0
83
+ version: 1.1.0
84
+ type: :development
85
+ version_requirements: *id004
86
+ - !ruby/object:Gem::Dependency
87
+ name: rake
88
+ prerelease: false
89
+ requirement: &id005 !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ~>
93
+ - !ruby/object:Gem::Version
94
+ hash: 49
95
+ segments:
96
+ - 0
97
+ - 8
98
+ - 7
99
+ version: 0.8.7
100
+ type: :development
101
+ version_requirements: *id005
102
+ - !ruby/object:Gem::Dependency
103
+ name: rspec
104
+ prerelease: false
105
+ requirement: &id006 !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ hash: 15
111
+ segments:
112
+ - 2
113
+ - 0
114
+ - 0
115
+ version: 2.0.0
116
+ type: :development
117
+ version_requirements: *id006
118
+ description: Matic adds attribute accessors and dirty tracking to Mongomatic.
119
+ email:
120
+ - code@papercavalier.com
121
+ executables: []
122
+
123
+ extensions: []
124
+
125
+ extra_rdoc_files: []
126
+
127
+ files:
128
+ - .gitignore
129
+ - .rspec
130
+ - .rvmrc
131
+ - CHANGELOG.md
132
+ - Gemfile
133
+ - Gemfile.lock
134
+ - README.md
135
+ - Rakefile
136
+ - lib/matic.rb
137
+ - lib/matic/version.rb
138
+ - matic.gemspec
139
+ - spec/matic_spec.rb
140
+ - spec/models/person.rb
141
+ - spec/spec_helper.rb
142
+ - spec/support/mongomatic.rb
143
+ - spec_rubies
144
+ has_rdoc: true
145
+ homepage: http://github.com/papercavalier/matic
146
+ licenses: []
147
+
148
+ post_install_message:
149
+ rdoc_options: []
150
+
151
+ require_paths:
152
+ - lib
153
+ required_ruby_version: !ruby/object:Gem::Requirement
154
+ none: false
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ hash: 3
159
+ segments:
160
+ - 0
161
+ version: "0"
162
+ required_rubygems_version: !ruby/object:Gem::Requirement
163
+ none: false
164
+ requirements:
165
+ - - ">="
166
+ - !ruby/object:Gem::Version
167
+ hash: 3
168
+ segments:
169
+ - 0
170
+ version: "0"
171
+ requirements: []
172
+
173
+ rubyforge_project: matic
174
+ rubygems_version: 1.3.7
175
+ signing_key:
176
+ specification_version: 3
177
+ summary: Mongomatic with attribute accessors and dirty tracking
178
+ test_files:
179
+ - spec/matic_spec.rb
180
+ - spec/models/person.rb
181
+ - spec/spec_helper.rb
182
+ - spec/support/mongomatic.rb