undo-wrapper 0.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9759604e0e526194d8a1cc83679ac6f6fac72fba
4
+ data.tar.gz: abc741709de1f3b969e7a37febe767c4f537af53
5
+ SHA512:
6
+ metadata.gz: 9325f22f5ee6c3e8e4891433f255319a1c1fdbdb30d6b5bc37d9c3afb858b7c1febd3821d60b4342ae17e360eb0a38c5f58ac37711408d056b8177baa48e2db6
7
+ data.tar.gz: 14b729afe94b46bbbfadfda1ba2f3910ac3aeec212968aff39800866f528c1f3e0c126b3111f20935ff9688774ad2e2ffe4b09a78dbdb571a86a20c6bf093c13
data/.coveralls.yml ADDED
@@ -0,0 +1 @@
1
+ service_name: travis-ci
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ /tags
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --colour
2
+ --format documentation
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ undo-wrapper
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.1.1
data/.travis.yml ADDED
@@ -0,0 +1,19 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1
4
+ - 2.0
5
+ - 1.9.3
6
+ - ruby-head
7
+ - rbx
8
+ - jruby-19mode
9
+ - jruby-head
10
+
11
+ matrix:
12
+ allow_failures:
13
+ - rvm: ruby-head
14
+ - rvm: rbx
15
+ - rvm: jruby-19mode
16
+ - rvm: jruby-head
17
+
18
+ script:
19
+ - "bundle exec rake ci:all"
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+
4
+ group :test do
5
+ if !!ENV['CI']
6
+ gem "coveralls"
7
+ else
8
+ gem "pry"
9
+ gem "pry-plus" if "ruby" == RUBY_ENGINE
10
+ end
11
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Alexander Paramonov
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,111 @@
1
+ Undo
2
+ ==========
3
+ [![Build Status](https://travis-ci.org/AlexParamonov/undo-wrapper.png?branch=master)](https://travis-ci.org/AlexParamonov/undo-wrapper)
4
+ [![Coverage Status](https://coveralls.io/repos/AlexParamonov/undo-wrapper/badge.png?branch=master)](https://coveralls.io/r/AlexParamonov/undo-wrapper?branch=master)
5
+ [![Code Climate](https://codeclimate.com/github/AlexParamonov/undo-wrapper.png)](https://codeclimate.com/github/AlexParamonov/undo-wrapper)
6
+ [![Gemnasium Build Status](https://gemnasium.com/AlexParamonov/undo-wrapper.png)](http://gemnasium.com/AlexParamonov/undo-wrapper)
7
+ [![Gem Version](https://badge.fury.io/rb/undo-wrapper.png)](http://badge.fury.io/rb/undo-wrapper)
8
+
9
+ Wrapper for [Undo gem](https://github.com/AlexParamonov/undo).
10
+ Observe changes and stores object state before the change.
11
+
12
+ Contents
13
+ ---------
14
+ 1. Installation
15
+ 1. Usage
16
+ 1. Requirements
17
+ 1. Contacts
18
+ 1. Compatibility
19
+ 1. Contributing
20
+ 1. Copyright
21
+
22
+ Installation
23
+ ------------
24
+
25
+ Add this line to your application's Gemfile:
26
+
27
+ gem 'undo-wrapper'
28
+
29
+ And then execute:
30
+
31
+ $ bundle
32
+
33
+ Or install it yourself as:
34
+
35
+ $ gem install undo-wrapper
36
+
37
+
38
+ Usage
39
+ -----
40
+
41
+ `Undo::wrapper` allows to wrap object in decorator:
42
+
43
+ decorated_object = Undo.wrap object
44
+ decorated_object.destroy
45
+ Undo.restore decorated_object.uuid
46
+
47
+ decorated_object is a pure decorator, so it quacks like original
48
+ object. The Undo will store object state on each hit to mutation
49
+ methods such as `update`, `delete`, `destroy`. Those methods can be
50
+ changed either in place or using global configuration.
51
+
52
+ `store_on` defines a list of methods which may mutate object state.
53
+ For each hit to such methods `Undo.store` will be called.
54
+
55
+ By default `store_on` are `update`, `delete`, `destroy`. To
56
+ append custom `store_on` use:
57
+
58
+ Undo::Wrapper.configure do |config|
59
+ config.store_on += [:put, :push, :pop]
60
+ end
61
+
62
+ Undo.wrap object, store_on: [:delete, :destroy]
63
+
64
+ Or in place:
65
+
66
+ Undo.wrap object, store_on: :save
67
+
68
+ Any option, that is not recognized by the Undo as configuration
69
+ option, will be bypass to the serializer and storage adapter:
70
+
71
+ Undo.wrap post, include: :comments, expires_in: 1.hour
72
+
73
+
74
+ Requirements
75
+ ------------
76
+ 1. Ruby 1.9 or above
77
+ 1. Undo gem
78
+
79
+ Contacts
80
+ --------
81
+ Have questions or recommendations? Contact me via `alexander.n.paramonov@gmail.com`
82
+ Found a bug or have enhancement request? You are welcome at [Github bugtracker](https://github.com/AlexParamonov/undo-wrapper/issues)
83
+
84
+
85
+ Compatibility
86
+ -------------
87
+ tested with Ruby
88
+
89
+ * 2.1
90
+ * 2.0
91
+ * 1.9.3
92
+ * ruby-head
93
+ * rbx
94
+ * jruby-19mode
95
+ * jruby-head
96
+
97
+ See [build history](http://travis-ci.org/#!/AlexParamonov/undo-wrapper/builds)
98
+
99
+
100
+ ## Contributing
101
+
102
+ 1. [Fork repository](http://github.com/AlexParamonov/undo-wrapper/fork)
103
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
104
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
105
+ 4. Push to the branch (`git push origin my-new-feature`)
106
+ 5. Create new Pull Request
107
+
108
+ Copyright
109
+ ---------
110
+ Copyright © 2014 Alexander Paramonov.
111
+ Released under the MIT License. See the LICENSE file for further details.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rspec/core/rake_task'
4
+ namespace :ci do
5
+ desc "Run tests on CI"
6
+ RSpec::Core::RakeTask.new('all') do |t|
7
+ t.rspec_opts = '-fprogress'
8
+ t.verbose = true
9
+ end
10
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,41 @@
1
+ require "undo"
2
+ require_relative "wrapper/configuration"
3
+ require_relative "wrapper_integration"
4
+ require "forwardable"
5
+
6
+ module Undo
7
+ class Wrapper < SimpleDelegator
8
+ def self.configure
9
+ yield config
10
+ end
11
+
12
+ def self.config
13
+ @config ||= Configuration.new
14
+ end
15
+
16
+ extend Forwardable
17
+ def_delegators :object, :class, :kind_of?
18
+
19
+ attr_reader :undo_uuid, :config
20
+
21
+ def initialize(object, options)
22
+ @object = object
23
+ @config = Undo::Wrapper.config.with options
24
+ @options = options
25
+
26
+ super object
27
+ end
28
+
29
+ def method_missing(method, *args, &block)
30
+ store if config.store_on.include? method
31
+ super method, *args, &block
32
+ end
33
+
34
+ private
35
+ attr_reader :object, :options
36
+
37
+ def store
38
+ @undo_uuid = Undo.store object, options
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,15 @@
1
+ module Undo
2
+ class Wrapper < SimpleDelegator
3
+ class Configuration
4
+ attr_accessor :store_on
5
+
6
+ def initialize(attributes = {})
7
+ @store_on = attributes.fetch :store_on, [:delete, :destroy]
8
+ end
9
+
10
+ def with(attribute_updates = {})
11
+ self.class.new store_on: (attribute_updates.delete(:store_on) || store_on)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ module Undo
2
+ def self.wrap(object, options = {})
3
+ Wrapper.new object, options
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ require "spec_helper_lite"
2
+ require "undo"
3
+ require 'undo/wrapper'
4
+ require 'undo/integration/shared_undo_integration_examples.rb'
5
+
6
+ describe Undo do
7
+ include_examples "undo integration"
8
+ end
@@ -0,0 +1,5 @@
1
+ require 'rspec'
2
+ require_relative "support/ci_helper"
3
+ require 'undo/wrapper'
4
+
5
+ $: << File.expand_path('../lib', File.dirname(__FILE__))
@@ -0,0 +1,16 @@
1
+ if !!ENV["CI"]
2
+ require 'simplecov'
3
+ require 'coveralls'
4
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
5
+ SimpleCov::Formatter::HTMLFormatter,
6
+ Coveralls::SimpleCov::Formatter
7
+ ]
8
+
9
+ SimpleCov.start do
10
+ add_filter '/spec/'
11
+ add_filter '/vendor/'
12
+ minimum_coverage(90)
13
+ end
14
+ else
15
+ require "pry"
16
+ end
@@ -0,0 +1,28 @@
1
+ require "spec_helper_lite"
2
+
3
+ describe Undo::Wrapper do
4
+ subject do
5
+ described_class.new(
6
+ object,
7
+ store_on: [:change]
8
+ )
9
+ end
10
+
11
+ let(:object) { double :object, change: "changed" }
12
+
13
+ describe "when mutation method is called" do
14
+ it "calls the method and returns result" do
15
+ expect(subject.change).to eq "changed"
16
+ end
17
+
18
+ it "stores object state" do
19
+ expect(Undo).to receive(:store).with(object, anything)
20
+ subject.change
21
+ end
22
+
23
+ it "does not store object state on another methods call" do
24
+ expect(Undo).not_to receive(:store)
25
+ subject.object_id
26
+ end
27
+ end
28
+ end
data/spec/undo_spec.rb ADDED
@@ -0,0 +1,74 @@
1
+ require "spec_helper_lite"
2
+
3
+ describe Undo do
4
+ let(:object) { double :object, change: true }
5
+ subject { described_class }
6
+
7
+ describe "pass through options to serializer" do
8
+ let(:serializer) { double :serializer }
9
+
10
+ specify "from #wrap" do
11
+ expect(serializer).to receive(:serialize).with(object, foo: :bar)
12
+
13
+ wrapper = subject.wrap object,
14
+ serializer: serializer,
15
+ store_on: [:change],
16
+ foo: :bar
17
+
18
+ wrapper.change
19
+ end
20
+ end
21
+
22
+ describe "pass through options to storage" do
23
+ let(:storage) { double :storage }
24
+
25
+ specify "from #wrap" do
26
+ expect(storage).to receive(:store).with(anything, object, foo: :bar)
27
+
28
+ wrapper = subject.wrap object,
29
+ storage: storage,
30
+ store_on: [:change],
31
+ foo: :bar
32
+
33
+ wrapper.change
34
+ end
35
+ end
36
+
37
+ describe "#wrap" do
38
+ before do
39
+ subject::Wrapper.configure do |config|
40
+ config.store_on = [:change]
41
+ end
42
+ end
43
+
44
+ it "is a decorator" do
45
+ object = %w[hello world]
46
+
47
+ decorator = subject.wrap object
48
+ expect(object).to receive(:some_method)
49
+ decorator.some_method
50
+
51
+ expect(decorator.class).to eq Array
52
+ expect(decorator).to be_a Array
53
+ end
54
+
55
+ describe "restores" do
56
+ specify "using provided uuid" do
57
+ uuid = "uniq_identifier"
58
+ model = subject.wrap object, uuid: uuid
59
+ model.change
60
+
61
+ expect(subject.restore uuid).to eq object
62
+ end
63
+
64
+ specify "using gerenated uuid" do
65
+ uuid = object.object_id
66
+ model = subject.wrap object, uuid_generator: -> object { object.object_id }
67
+ model.change
68
+
69
+ expect(model.undo_uuid).to eq uuid
70
+ expect(subject.restore uuid).to eq object
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "undo-wrapper"
7
+ spec.version = IO.read("VERSION")
8
+ spec.authors = ["Alexander Paramonov"]
9
+ spec.email = ["alexander.n.paramonov@gmail.com"]
10
+ spec.summary = %q{Observes changes and stores object state before the change}
11
+ spec.description = %q{Observes changes and stores object state before the change}
12
+ spec.homepage = "http://github.com/AlexParamonov/undo-wrapper"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_dependency "undo", "~> 1.0"
21
+ spec.add_development_dependency "bundler", "~> 1.0"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec", ">= 3.0.0.beta1"
24
+ end
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: undo-wrapper
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Alexander Paramonov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-05-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: undo
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.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'
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.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
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: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 3.0.0.beta1
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 3.0.0.beta1
69
+ description: Observes changes and stores object state before the change
70
+ email:
71
+ - alexander.n.paramonov@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".coveralls.yml"
77
+ - ".gitignore"
78
+ - ".rspec"
79
+ - ".ruby-gemset"
80
+ - ".ruby-version"
81
+ - ".travis.yml"
82
+ - Gemfile
83
+ - LICENSE.txt
84
+ - README.md
85
+ - Rakefile
86
+ - VERSION
87
+ - lib/undo/wrapper.rb
88
+ - lib/undo/wrapper/configuration.rb
89
+ - lib/undo/wrapper_integration.rb
90
+ - spec/integration/undo_spec.rb
91
+ - spec/spec_helper_lite.rb
92
+ - spec/support/ci_helper.rb
93
+ - spec/undo/wrapper_spec.rb
94
+ - spec/undo_spec.rb
95
+ - undo-wrapper.gemspec
96
+ homepage: http://github.com/AlexParamonov/undo-wrapper
97
+ licenses:
98
+ - MIT
99
+ metadata: {}
100
+ post_install_message:
101
+ rdoc_options: []
102
+ require_paths:
103
+ - lib
104
+ required_ruby_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ requirements: []
115
+ rubyforge_project:
116
+ rubygems_version: 2.1.11
117
+ signing_key:
118
+ specification_version: 4
119
+ summary: Observes changes and stores object state before the change
120
+ test_files:
121
+ - spec/integration/undo_spec.rb
122
+ - spec/spec_helper_lite.rb
123
+ - spec/support/ci_helper.rb
124
+ - spec/undo/wrapper_spec.rb
125
+ - spec/undo_spec.rb
126
+ has_rdoc: