immutability 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ ---
2
+ abc_max: "10"
3
+ line_length: "80"
4
+ no_doc: "y"
5
+ no_readme: "y"
@@ -0,0 +1,6 @@
1
+ ---
2
+ ignore_files:
3
+ - spec
4
+ - config
5
+ minimum_churn_count: 0
6
+ start_date: "1 year ago"
@@ -0,0 +1,2 @@
1
+ ---
2
+ minimum_score: 8
@@ -0,0 +1,14 @@
1
+ ---
2
+ folders: # The list of folders to be used by any metric.
3
+ - lib
4
+ metrics: # The list of allowed metrics. The other metrics are disabled.
5
+ - cane
6
+ - churn
7
+ - flay
8
+ - flog
9
+ - reek
10
+ - roodi
11
+ - saikuro
12
+ format: html
13
+ output: tmp/metric_fu
14
+ verbose: false
@@ -0,0 +1 @@
1
+ ---
@@ -0,0 +1,24 @@
1
+ ---
2
+ AssignmentInConditionalCheck:
3
+ CaseMissingElseCheck:
4
+ ClassLineCountCheck:
5
+ line_count: 100
6
+ ClassNameCheck:
7
+ pattern: !ruby/regexp /^[A-Z][a-zA-Z0-9]*$/
8
+ ClassVariableCheck:
9
+ CyclomaticComplexityBlockCheck:
10
+ complexity: 2
11
+ CyclomaticComplexityMethodCheck:
12
+ complexity: 3
13
+ EmptyRescueBodyCheck:
14
+ ForLoopCheck:
15
+ MethodLineCountCheck:
16
+ line_count: 6
17
+ MethodNameCheck:
18
+ pattern: !ruby/regexp /^[\||\^|\&|\!]$|^[_a-z<>=\[|+-\/\*`]+[_a-z0-9_<>=~@\[\]]*[=!\?]?$/
19
+ ModuleLineCountCheck:
20
+ line_count: 120
21
+ ModuleNameCheck:
22
+ pattern: !ruby/regexp /^[A-Z][a-zA-Z0-9]*$/
23
+ ParameterNumberCheck:
24
+ parameter_count: 4
@@ -0,0 +1,71 @@
1
+ ---
2
+ AllCops:
3
+ Exclude:
4
+ - '**/db/schema.rb'
5
+
6
+ Lint/HandleExceptions:
7
+ Exclude:
8
+ - '**/*_spec.rb'
9
+
10
+ Lint/RescueException:
11
+ Exclude:
12
+ - '**/*_spec.rb'
13
+
14
+ Style/AccessorMethodName:
15
+ Exclude:
16
+ - '**/*_spec.rb'
17
+
18
+ Style/AsciiComments:
19
+ Enabled: false
20
+
21
+ Style/ClassAndModuleChildren:
22
+ Enabled: false
23
+
24
+ Style/Documentation:
25
+ Enabled: false
26
+
27
+ Style/EmptyLinesAroundBlockBody:
28
+ Enabled: false
29
+
30
+ Style/EmptyLinesAroundClassBody:
31
+ Enabled: false
32
+
33
+ Style/EmptyLinesAroundMethodBody:
34
+ Enabled: false
35
+
36
+ Style/EmptyLinesAroundModuleBody:
37
+ Enabled: false
38
+
39
+ Style/EmptyLineBetweenDefs:
40
+ Enabled: false
41
+
42
+ Style/FileName:
43
+ Enabled: false
44
+
45
+ Style/NumericLiterals:
46
+ Enabled: false
47
+
48
+ Style/RaiseArgs:
49
+ EnforcedStyle: compact
50
+
51
+ Style/SingleLineMethods:
52
+ Exclude:
53
+ - '**/*_spec.rb'
54
+
55
+ Style/SingleSpaceBeforeFirstArg:
56
+ Enabled: false
57
+
58
+ Style/SpecialGlobalVars:
59
+ Exclude:
60
+ - '**/Gemfile'
61
+ - '**/*.gemspec'
62
+
63
+ Style/StringLiterals:
64
+ EnforcedStyle: double_quotes
65
+
66
+ Style/StringLiteralsInInterpolation:
67
+ EnforcedStyle: double_quotes
68
+
69
+ Style/TrivialAccessors:
70
+ Exclude:
71
+ - '**/*_spec.rb'
@@ -0,0 +1,3 @@
1
+ ---
2
+ warn_cyclo: 3
3
+ error_cyclo: 4
@@ -0,0 +1,6 @@
1
+ ---
2
+ output: tmp/coverage
3
+ filters: # The list of paths to be excluded from coverage checkup
4
+ - "spec/"
5
+ - "config/"
6
+ groups: []
@@ -0,0 +1,37 @@
1
+ ---
2
+ # Settings added by the 'hexx-suit' gem
3
+ output: "tmp/yardstick/output.log"
4
+ path: "lib/**/*.rb"
5
+ rules:
6
+ ApiTag::Presence:
7
+ enabled: true
8
+ exclude: []
9
+ ApiTag::Inclusion:
10
+ enabled: true
11
+ exclude: []
12
+ ApiTag::ProtectedMethod:
13
+ enabled: true
14
+ exclude: []
15
+ ApiTag::PrivateMethod:
16
+ enabled: false
17
+ exclude: []
18
+ ExampleTag:
19
+ enabled: true
20
+ exclude: []
21
+ ReturnTag:
22
+ enabled: true
23
+ exclude: []
24
+ Summary::Presence:
25
+ enabled: true
26
+ exclude: []
27
+ Summary::Length:
28
+ enabled: true
29
+ exclude: []
30
+ Summary::Delimiter:
31
+ enabled: true
32
+ exclude: []
33
+ Summary::SingleLine:
34
+ enabled: true
35
+ exclude: []
36
+ threshold: 100
37
+ verbose: false
@@ -0,0 +1,25 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+ require "immutability/version"
3
+
4
+ Gem::Specification.new do |gem|
5
+
6
+ gem.name = "immutability"
7
+ gem.version = Immutability::VERSION.dup
8
+ gem.author = "Andrew Kozin"
9
+ gem.email = "andrew.kozin@gmail.com"
10
+ gem.homepage = "https://github.com/nepalez/immutability"
11
+ gem.summary = "Make instances immutable (deeply frozen) and versioned"
12
+ gem.license = "MIT"
13
+
14
+ gem.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
15
+ gem.test_files = Dir["spec/**/*.rb"]
16
+ gem.extra_rdoc_files = Dir["README.md", "LICENSE"]
17
+ gem.require_paths = ["lib"]
18
+
19
+ gem.required_ruby_version = ">= 1.9.3"
20
+
21
+ gem.add_runtime_dependency "ice_nine", "~> 0.11.1"
22
+
23
+ gem.add_development_dependency "hexx-rspec", "~> 0.5"
24
+
25
+ end # Gem::Specification
@@ -0,0 +1,126 @@
1
+ # encoding: utf-8
2
+
3
+ require "ice_nine"
4
+
5
+ require_relative "immutability/with_memory"
6
+
7
+ # Makes the object immutable (deeply frozen) with possibility to remember
8
+ # and forget previous states (snapshots).
9
+ #
10
+ # Uses 'ice_nine' to freeze object deeply by the initializer
11
+ #
12
+ # @example Without memory
13
+ # require "immutability"
14
+ #
15
+ # class User
16
+ # include Immutability
17
+ #
18
+ # attr_reader :name
19
+ #
20
+ # def initialize(name)
21
+ # @name = name
22
+ # end
23
+ # end
24
+ #
25
+ # user = User.new "Andre"
26
+ # user.name # => "Andre"
27
+ # # It is frozen deeply
28
+ # user.frozen? # => true
29
+ # user.name.frozen? # => true
30
+ #
31
+ # new_user = user.update { @name = "Andrew" }
32
+ # new_user.name # => "Andrew"
33
+ # # It is frozen deeply
34
+ # new_user.frozen? # => true
35
+ # new_user.name.frozen? # => true
36
+ #
37
+ # @example With memory
38
+ # class User
39
+ # include Immutability.with_memory
40
+ #
41
+ # attr_reader :name
42
+ #
43
+ # def initialize(name)
44
+ # @name = name
45
+ # end
46
+ # end
47
+ #
48
+ # user = User.new "Andre"
49
+ # user.name # => "Andre"
50
+ # # It has version and reference to the parent (nil for the first version)
51
+ # user.version # => 0
52
+ # user.parent # => nil
53
+ #
54
+ # new_user = user.update { @name = "Andrew" }
55
+ # new_user.name # => "Andrew"
56
+ # # It stores current version and reference to the parent
57
+ # new_user.version # => 1
58
+ # new_user.parent # => #<User @name="Andre">
59
+ #
60
+ # mankurt = new_user.forget_history
61
+ # mankurt.name # => "Andrew"
62
+ # # It doesn't refer to previous states (they can be garbage collected)
63
+ # mankurt.version # => 0
64
+ # mankurt.parent # => nil
65
+ #
66
+ # @author Andrew Kozin <Andrew.Kozin@gmail.com>
67
+ #
68
+ module Immutability
69
+
70
+ # Methods to be added to class, that included the `Immutability` module
71
+ #
72
+ # @api private
73
+ #
74
+ module ClassMethods
75
+
76
+ # Reloads instance's constructor to make it immutable
77
+ #
78
+ # @api private
79
+ #
80
+ # @param [Object, Array<Object>] args
81
+ #
82
+ # @return [Object]
83
+ #
84
+ def new(*args)
85
+ IceNine.deep_freeze __new__(*args)
86
+ end
87
+
88
+ private
89
+
90
+ def __new__(*args, &block)
91
+ allocate.tap do |instance|
92
+ instance.__send__(:initialize, *args)
93
+ instance.instance_eval(&block) if block_given?
94
+ end
95
+ end
96
+
97
+ end # module ClassMethods
98
+
99
+ # Returns the new immutable instances that preserves old variables and
100
+ # updates some of them from inside the block
101
+ #
102
+ # @param [Proc] block
103
+ # The block to be evaluated by new instance's "initializer"
104
+ #
105
+ # @return [Object] the updated instance
106
+ #
107
+ def update(&block)
108
+ instance = dup
109
+ instance.instance_eval(&block) if block_given?
110
+ IceNine.deep_freeze(instance)
111
+ end
112
+
113
+ # @private
114
+ def self.included(klass)
115
+ klass.instance_exec(ClassMethods) { |mod| extend(mod) }
116
+ end
117
+
118
+ # Returns the module extended by features to record history
119
+ #
120
+ # @return [Module]
121
+ #
122
+ def self.with_memory
123
+ WithMemory
124
+ end
125
+
126
+ end # module Immutability
@@ -0,0 +1,4 @@
1
+ # encoding: utf-8
2
+
3
+ # Loads spec matcher to check the immutability
4
+ require_relative "../../spec/support/immutable"
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+
3
+ module Immutability
4
+
5
+ # The semantic version of the gem.
6
+ # @see http://semver.org/ Semantic versioning 2.0
7
+ VERSION = "0.0.1".freeze
8
+
9
+ end # module Immutability
@@ -0,0 +1,70 @@
1
+ # encoding: utf-8
2
+
3
+ module Immutability
4
+
5
+ # Extends +Immutability+ to remember version and previous state of instance.
6
+ #
7
+ # @author Andrew Kozin <Andrew.Kozin@gmail.com>
8
+ #
9
+ module WithMemory
10
+
11
+ # @private
12
+ class << self
13
+ private
14
+
15
+ def included(klass)
16
+ klass.__send__ :include, Immutability
17
+ klass.__send__ :extend, ClassMethods
18
+ klass.__send__ :define_method, :update, update
19
+ end
20
+
21
+ # Redefines the +update+ so that it increment version and refer
22
+ # to the previous snapshot of the continuous object
23
+ #
24
+ def update
25
+ proc do |&block|
26
+ current = [(version + 1), self]
27
+ super() do
28
+ @version, @parent = current
29
+ instance_eval(&block) if block
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ # Adds version and parent variables to newly created instance
36
+ #
37
+ module ClassMethods
38
+ private
39
+
40
+ def __new__(*args)
41
+ super(*args) { @version, @parent = 0 }
42
+ end
43
+ end
44
+
45
+ # @!attribute [r] version
46
+ #
47
+ # @return [Integer] the current version number of the instance
48
+ #
49
+ attr_reader :version
50
+
51
+ # @!attribute [r] parent
52
+ #
53
+ # @return [Object] the previous version (immutable instance)
54
+ #
55
+ attr_reader :parent
56
+
57
+ # Forgets the previous history of the object
58
+ #
59
+ # Returns a new instance with the same variables,
60
+ # except for [#version] and [#parent] that are set to +0+ and +nil+.
61
+ #
62
+ # @return [Object]
63
+ #
64
+ def forget_history
65
+ update { @version, @parent = 0 }
66
+ end
67
+
68
+ end # module WithMemory
69
+
70
+ end # module Immutability
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+
3
+ shared_examples :user do
4
+ before do
5
+ class User
6
+ attr_reader :name, :age
7
+
8
+ def initialize(name, age)
9
+ @name = name
10
+ @age = age
11
+ end
12
+ end
13
+ end
14
+
15
+ after { Object.send :remove_const, :User }
16
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+
3
+ begin
4
+ require "hexx-suit"
5
+ Hexx::Suit.load_metrics_for(self)
6
+ rescue LoadError
7
+ require "hexx-rspec"
8
+ Hexx::RSpec.load_metrics_for(self)
9
+ end
10
+
11
+ # Loads the code under test
12
+ require "immutability"
13
+
14
+ # Loads custom matchers
15
+ require "immutability/rspec"
16
+
17
+ # Loads shared examples
18
+ require_relative "shared/user"