virtus-dirty_attribute 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 04a13c469b7cb547616f8aa120ff80cd43ab0c41
4
+ data.tar.gz: 772354eeb7ea3e9d6368e73a1b962c17a2b4a55b
5
+ SHA512:
6
+ metadata.gz: 7f717a6aeff6769d21babd8b8cfa6e556845cd279feb93e7473106b2134de0da68a8e2a1c03f83c368430bef5c0499244eba039f652bcfbeaf978e79f1db193c
7
+ data.tar.gz: 57ce59a0d9840c0e64a5af9ac0268eb6465798aa8d189b903f72d81f250c130c179b51c6de634ff83aeec668d7dd760b99351a285b464d564b156cba99059893
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
5
+ - 1.9.3
6
+ notifications:
7
+ email:
8
+ - jingweno@gmail.com
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Jingwen Owen Ou
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.
@@ -0,0 +1,46 @@
1
+ = Virtus::DirtyAttribute
2
+
3
+ Support for dirty tracking of virtus attributes.
4
+
5
+ == Usage
6
+
7
+ require 'virtus-drity_attribute'
8
+
9
+ class Post
10
+ include Virtus.model
11
+ include Virtus::DirtyAttribute
12
+
13
+ attribute :title, String
14
+ attribute :content, String
15
+ attribute :meta, Hash
16
+ end
17
+
18
+ post = Post.new(:title => 'Foo', :meta => { :tags => ['red', 'green'] })
19
+
20
+ post.dirty? # => false
21
+
22
+ post.title = 'Bar'
23
+
24
+ post.dirty? # => true
25
+
26
+ post.attribute_dirty?(:title) # => true
27
+
28
+ post.meta[:tags] << 'blue'
29
+
30
+ post.attribute_dirty?(:meta) # => true
31
+
32
+ post.dirty_attributes # => {:title => 'Bar', :meta=>{:tags=>["red", "green", "blue"]}}
33
+
34
+ == Note on Patches/Pull Requests
35
+
36
+ * Fork the project.
37
+ * Make your feature addition or bug fix.
38
+ * Add tests for it. This is important so I don't break it in a
39
+ future version unintentionally.
40
+ * Commit, do not mess with rakefile, version, or history.
41
+ (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)
42
+ * Send me a pull request. Bonus points for topic branches.
43
+
44
+ == Copyright
45
+
46
+ Copyright (c) 2011 Jingwen Owen Ou. See LICENSE for details.
@@ -0,0 +1,10 @@
1
+ require 'bundler/setup'
2
+ require 'bundler/gem_tasks'
3
+ require 'rake'
4
+ require 'rspec/core/rake_task'
5
+
6
+ desc "Run specs"
7
+ RSpec::Core::RakeTask.new
8
+
9
+ desc 'Default: run specs'
10
+ task :default => :spec
@@ -0,0 +1,3 @@
1
+ require 'virtus/dirty_attribute/version'
2
+
3
+ require_relative 'virtus/dirty_attribute'
@@ -0,0 +1,86 @@
1
+ require 'virtus'
2
+ require_relative 'dirty_attribute/session'
3
+
4
+ module Virtus
5
+ # == Dirty Tracking
6
+ #
7
+ # Dirty Tracking is an optional module that you include only if you need it.
8
+ module DirtyAttribute
9
+ module ClassMethods
10
+ def attribute(name, type, options = {})
11
+ _create_writer_with_dirty_tracking(name)
12
+ super
13
+ end
14
+
15
+ private
16
+ def _create_writer_with_dirty_tracking(name)
17
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
18
+ def #{name}=(new_regular_object)
19
+ prev_object = #{name}
20
+ new_virtus_object = super
21
+
22
+ if attribute_dirty?(:#{name}) && original_attributes[:#{name}] == new_virtus_object
23
+ attribute_clean!(:#{name})
24
+ elsif prev_object != new_virtus_object
25
+ unless original_attributes.key?(:#{name})
26
+ original_attributes[:#{name}] = prev_object
27
+ end
28
+
29
+ attribute_dirty!(:#{name}, new_regular_object)
30
+ end
31
+
32
+ new_virtus_object
33
+ end
34
+ RUBY
35
+ end
36
+ end
37
+
38
+ module InitiallyClean
39
+ def initialize(*args)
40
+ super(*args)
41
+ clean!
42
+ end
43
+ end
44
+
45
+ def self.included(base)
46
+ base.extend ClassMethods
47
+ end
48
+
49
+ def dirty?
50
+ dirty_session.dirty?
51
+ end
52
+
53
+ def clean?
54
+ !dirty?
55
+ end
56
+
57
+ def attribute_dirty?(name)
58
+ dirty_session.dirty?(name)
59
+ end
60
+
61
+ def clean!
62
+ dirty_session.clean!
63
+ end
64
+
65
+ def dirty_attributes
66
+ dirty_session.dirty_attributes
67
+ end
68
+
69
+ def original_attributes
70
+ dirty_session.original_attributes
71
+ end
72
+
73
+ private
74
+ def attribute_dirty!(name, value)
75
+ dirty_session.dirty!(name, value)
76
+ end
77
+
78
+ def attribute_clean!(name)
79
+ dirty_session.attribute_clean!(name)
80
+ end
81
+
82
+ def dirty_session
83
+ @_dirty_session ||= Session.new(self)
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,37 @@
1
+ module Virtus
2
+ module DirtyAttribute
3
+ class Session
4
+ attr_reader :subject
5
+
6
+ def initialize(subject)
7
+ @subject = subject
8
+ end
9
+
10
+ def original_attributes
11
+ @_original_attributes ||= subject.attributes.dup
12
+ end
13
+
14
+ def dirty_attributes
15
+ @_dirty_attributes ||= {}
16
+ end
17
+
18
+ def dirty!(name, value)
19
+ dirty_attributes[name] = value
20
+ end
21
+
22
+ def attribute_clean!(name)
23
+ dirty_attributes.delete name
24
+ original_attributes.delete name
25
+ end
26
+
27
+ def dirty?(name = nil)
28
+ name ? dirty_attributes.key?(name) : dirty_attributes.any?
29
+ end
30
+
31
+ def clean!
32
+ original_attributes.clear
33
+ dirty_attributes.clear
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,5 @@
1
+ module Virtus
2
+ module DirtyAttribute
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,98 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Dirty tracking" do
4
+ let(:attribute) { :title }
5
+ let(:initial_value) { 'Virtus' }
6
+ let(:other_value) { 'Virtus *dirty* '}
7
+
8
+ let(:model) do
9
+ model = Class.new do
10
+ include Virtus.model
11
+ include Virtus::DirtyAttribute
12
+ include Virtus::DirtyAttribute::InitiallyClean
13
+ end
14
+
15
+ model.attribute attribute, String
16
+
17
+ model
18
+ end
19
+
20
+ subject { model.new }
21
+
22
+ it { should be_clean }
23
+
24
+ it "should not be dirty after instantiating with attributes" do
25
+ object = model.new attribute => initial_value
26
+ object.should be_clean
27
+ end
28
+
29
+ context "when object is dirty" do
30
+ it "should become clean again" do
31
+ subject[attribute] = initial_value
32
+ subject.clean!
33
+
34
+ subject.should be_clean
35
+
36
+ subject.original_attributes.should be_empty
37
+ subject.dirty_attributes.should be_empty
38
+ end
39
+
40
+ it "should become clean when the attribute goes back to the initial value" do
41
+ subject[attribute] = initial_value
42
+ subject.clean!
43
+
44
+ subject[attribute] = other_value
45
+
46
+ subject.should be_dirty
47
+ subject.dirty_attributes.should include(attribute)
48
+
49
+ subject[attribute] = initial_value
50
+
51
+ subject.should be_clean
52
+ subject.dirty_attributes.should be_empty
53
+ subject.original_attributes.should be_empty
54
+ end
55
+ end
56
+
57
+ context "when value is set on a new object" do
58
+ before do
59
+ subject[attribute] = initial_value
60
+ end
61
+
62
+ it { should be_dirty }
63
+
64
+ it "marks the attribute as dirty" do
65
+ subject.attribute_dirty?(attribute).should be(true)
66
+ end
67
+
68
+ it "sets new value in dirty_attributes hash" do
69
+ subject.dirty_attributes[attribute].should == initial_value
70
+ end
71
+ end
72
+
73
+ context "when other value is set on a new object with attribute already set" do
74
+ let(:subject) { model.new attribute => initial_value }
75
+
76
+ before do
77
+ subject[attribute] = other_value
78
+ end
79
+
80
+ it "should have different values" do
81
+ initial_value.should_not == other_value
82
+ end
83
+
84
+ it { should be_dirty }
85
+
86
+ it "marks the attribute as dirty" do
87
+ subject.attribute_dirty?(attribute).should be_true
88
+ end
89
+
90
+ it "sets new value in dirty_attributes hash" do
91
+ subject.dirty_attributes[attribute].should == other_value
92
+ end
93
+
94
+ it "sets original value" do
95
+ subject.original_attributes[attribute].should == initial_value
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,2 @@
1
+ require 'bundler/setup'
2
+ require 'virtus-dirty_attribute'
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'virtus/dirty_attribute/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "virtus-dirty_attribute"
8
+ spec.version = Virtus::DirtyAttribute::VERSION
9
+ spec.authors = ["Adam Hawkins"]
10
+ spec.email = ["adam@hawkins.io"]
11
+ spec.description = %q{Dirty Tracking for Virtus objects}
12
+ spec.summary = %q{}
13
+ spec.homepage = "https://github.com/ahawkins/virtus-dirty_attribute"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency 'virtus', "~> 1.0.0"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "rspec"
25
+ spec.add_development_dependency "rake"
26
+ end
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: virtus-dirty_attribute
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Adam Hawkins
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-01-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: virtus
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Dirty Tracking for Virtus objects
70
+ email:
71
+ - adam@hawkins.io
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - ".travis.yml"
78
+ - Gemfile
79
+ - LICENSE
80
+ - README.rdoc
81
+ - Rakefile
82
+ - lib/virtus-dirty_attribute.rb
83
+ - lib/virtus/dirty_attribute.rb
84
+ - lib/virtus/dirty_attribute/session.rb
85
+ - lib/virtus/dirty_attribute/version.rb
86
+ - spec/acceptance_spec.rb
87
+ - spec/spec_helper.rb
88
+ - virtus-dirty.gemspec
89
+ homepage: https://github.com/ahawkins/virtus-dirty_attribute
90
+ licenses:
91
+ - MIT
92
+ metadata: {}
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubyforge_project:
109
+ rubygems_version: 2.2.0
110
+ signing_key:
111
+ specification_version: 4
112
+ summary: ''
113
+ test_files:
114
+ - spec/acceptance_spec.rb
115
+ - spec/spec_helper.rb