immutability 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+
3
+ # Checks whether the instance is truly (deeply) immutable
4
+ #
5
+ # @example
6
+ # expect(instance).to be_immutable
7
+ #
8
+ # @api public
9
+ #
10
+ RSpec::Matchers.define :be_immutable do
11
+ match do |instance|
12
+ if instance.class.respond_to? :new
13
+ expect(instance).to be_frozen
14
+ instance
15
+ .instance_variables.map(&instance.method(:instance_variable_get))
16
+ .each { |ivar| expect(ivar).to be_immutable }
17
+ else
18
+ expect(true).to be_truthy
19
+ end
20
+ end
21
+
22
+ failure_message do |instance|
23
+ "expected that #{instance.inspect} to be immutable"
24
+ end
25
+ end
@@ -0,0 +1,101 @@
1
+ # encoding: utf-8
2
+ describe Immutability::WithMemory do
3
+
4
+ include_context :user
5
+ before { User.send :include, described_class }
6
+
7
+ let(:user) { User.new "Andrew", 44 }
8
+
9
+ describe ".new" do
10
+ subject { user }
11
+
12
+ it { is_expected.to be_immutable }
13
+
14
+ it "doesn't add hidden variables" do
15
+ expect(subject.instance_variables).to contain_exactly(
16
+ :@name, :@age, :@version, :@parent
17
+ )
18
+ end
19
+ end # describe .new
20
+
21
+ describe "#methods" do
22
+ subject { user.methods - Object.instance_methods }
23
+
24
+ it "are expected" do
25
+ expect(subject).to contain_exactly(
26
+ :name, :age, :version, :parent, :update, :forget_history
27
+ )
28
+ end
29
+ end # describe #methods
30
+
31
+ describe "#version" do
32
+ subject { user.version }
33
+
34
+ it { is_expected.to eql 0 }
35
+ end # describe #version
36
+
37
+ describe "#parent" do
38
+ subject { user.parent }
39
+
40
+ it { is_expected.to be_nil }
41
+ end # describe #parent
42
+
43
+ describe "#update" do
44
+ subject { user.update { @age = 45 } }
45
+
46
+ it "creates new immutable instance" do
47
+ expect(subject).to be_kind_of User
48
+ expect(subject).to be_immutable
49
+ end
50
+
51
+ it "sets parent" do
52
+ expect(subject.parent).to eql user
53
+ end
54
+
55
+ it "increments version" do
56
+ expect(subject.version).to eql 1
57
+ expect(subject.update.version).to eql 2
58
+ end
59
+
60
+ it "applies the block" do
61
+ expect(subject.age).to eql 45
62
+ end
63
+
64
+ it "preserves other variables" do
65
+ expect(subject.name).to eql user.name
66
+ end
67
+
68
+ it "doesn't add hidden variables" do
69
+ expect(subject.instance_variables).to eql user.instance_variables
70
+ end
71
+ end # describe #update
72
+
73
+ describe "#forget_history" do
74
+ subject { new_user.forget_history }
75
+
76
+ let(:new_user) { user.update { @age = 45 } }
77
+
78
+ it "creates new immutable instance" do
79
+ expect(subject).to be_kind_of User
80
+ expect(subject).to be_immutable
81
+ end
82
+
83
+ it "resets parent" do
84
+ expect(subject.parent).to be_nil
85
+ end
86
+
87
+ it "resets version" do
88
+ expect(subject.version).to eql 0
89
+ end
90
+
91
+ it "preserves other variables" do
92
+ expect(subject.name).to eql new_user.name
93
+ expect(subject.age).to eql new_user.age
94
+ end
95
+
96
+ it "doesn't add hidden variables" do
97
+ expect(subject.instance_variables).to eql new_user.instance_variables
98
+ end
99
+ end # describe #forget_history
100
+
101
+ end # describe Immutability::WithMemory
@@ -0,0 +1,63 @@
1
+ # encoding: utf-8
2
+ describe Immutability do
3
+
4
+ include_context :user
5
+ before { User.send :include, described_class }
6
+
7
+ let(:user) { User.new name, 44 }
8
+ let(:name) { "Andrew" }
9
+
10
+ describe "::with_memory" do
11
+ subject { described_class.with_memory }
12
+
13
+ it { is_expected.to eql Immutability::WithMemory }
14
+ end # describe .with_memory
15
+
16
+ describe ".new" do
17
+ subject { user }
18
+
19
+ it { is_expected.to be_immutable }
20
+ end # describe .new
21
+
22
+ describe "#methods" do
23
+ subject { user.methods - Object.instance_methods }
24
+
25
+ it { is_expected.to contain_exactly(:name, :age, :update) }
26
+ end # describe #methods
27
+
28
+ describe "#update" do
29
+ subject { user.update { @age = 45 } }
30
+
31
+ it "creates new immutable instance" do
32
+ expect(subject).to be_kind_of User
33
+ expect(subject).to be_immutable
34
+ end
35
+
36
+ it "applies the block" do
37
+ expect(subject.age).to eql 45
38
+ end
39
+
40
+ it "preserves other variables" do
41
+ expect(subject.name).to eql user.name
42
+ end
43
+
44
+ it "doesn't add hidden variables" do
45
+ expect(subject.instance_variables).to eql user.instance_variables
46
+ end
47
+
48
+ context "without block" do
49
+ subject { user.update }
50
+
51
+ it "creates new immutable instance" do
52
+ expect(subject).not_to be_equal(user)
53
+ expect(subject).to be_immutable
54
+ end
55
+
56
+ it "preservers all variables" do
57
+ expect(subject.age).to eql user.age
58
+ expect(subject.name).to eql user.name
59
+ end
60
+ end
61
+ end # describe #update
62
+
63
+ end # describe Immutability
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: immutability
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Andrew Kozin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-09-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ice_nine
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 0.11.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 0.11.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: hexx-rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '0.5'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '0.5'
41
+ description:
42
+ email: andrew.kozin@gmail.com
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files:
46
+ - README.md
47
+ - LICENSE
48
+ files:
49
+ - .coveralls.yml
50
+ - .gitignore
51
+ - .metrics
52
+ - .rspec
53
+ - .rubocop.yml
54
+ - .travis.yml
55
+ - .yardopts
56
+ - CHANGELOG.md
57
+ - Gemfile
58
+ - Guardfile
59
+ - LICENSE
60
+ - README.md
61
+ - Rakefile
62
+ - config/metrics/STYLEGUIDE
63
+ - config/metrics/cane.yml
64
+ - config/metrics/churn.yml
65
+ - config/metrics/flay.yml
66
+ - config/metrics/metric_fu.yml
67
+ - config/metrics/reek.yml
68
+ - config/metrics/roodi.yml
69
+ - config/metrics/rubocop.yml
70
+ - config/metrics/saikuro.yml
71
+ - config/metrics/simplecov.yml
72
+ - config/metrics/yardstick.yml
73
+ - immutability.gemspec
74
+ - lib/immutability.rb
75
+ - lib/immutability/rspec.rb
76
+ - lib/immutability/version.rb
77
+ - lib/immutability/with_memory.rb
78
+ - spec/shared/user.rb
79
+ - spec/spec_helper.rb
80
+ - spec/support/immutable.rb
81
+ - spec/unit/immutability/with_memory_spec.rb
82
+ - spec/unit/immutability_spec.rb
83
+ homepage: https://github.com/nepalez/immutability
84
+ licenses:
85
+ - MIT
86
+ metadata: {}
87
+ post_install_message:
88
+ rdoc_options: []
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: 1.9.3
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ! '>='
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ requirements: []
102
+ rubyforge_project:
103
+ rubygems_version: 2.4.6
104
+ signing_key:
105
+ specification_version: 4
106
+ summary: Make instances immutable (deeply frozen) and versioned
107
+ test_files:
108
+ - spec/spec_helper.rb
109
+ - spec/unit/immutability_spec.rb
110
+ - spec/unit/immutability/with_memory_spec.rb
111
+ - spec/support/immutable.rb
112
+ - spec/shared/user.rb
113
+ has_rdoc: