concord 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.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ /tmp
2
+ /Gemfile.lock
3
+ /.bundle
4
+ /vendor
data/.rspec ADDED
@@ -0,0 +1,5 @@
1
+ --color
2
+ --format progress
3
+ --profile
4
+ --order random
5
+ --fail-fast
data/.travis.yml ADDED
@@ -0,0 +1,18 @@
1
+ language: ruby
2
+ script: 'bundle exec rake ci'
3
+ rvm:
4
+ - ree
5
+ - 1.8.7
6
+ - 1.9.2
7
+ - 1.9.3
8
+ - 2.0.0
9
+ - ruby-head
10
+ - jruby-18mode
11
+ - jruby-19mode
12
+ - jruby-head
13
+ - rbx-18mode
14
+ - rbx-19mode
15
+ notifications:
16
+ irc: "irc.freenode.org#datamapper"
17
+ email:
18
+ - mbj@seonic.net
data/Changelog.md ADDED
@@ -0,0 +1,3 @@
1
+ # v0.0.1 2013-03-06
2
+
3
+ * First public release!
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'devtools', :git => 'https://github.com/datamapper/devtools.git'
6
+ eval File.read('Gemfile.devtools')
data/Gemfile.devtools ADDED
@@ -0,0 +1,64 @@
1
+ # encoding: utf-8
2
+
3
+ group :development do
4
+ gem 'rake', '~> 10.0.3'
5
+ gem 'rspec', '~> 2.13.0'
6
+ gem 'yard', '~> 0.8.5'
7
+ end
8
+
9
+ group :yard do
10
+ gem 'kramdown', '~> 0.14.2'
11
+ end
12
+
13
+ group :guard do
14
+ gem 'guard', '~> 1.6.2'
15
+ gem 'guard-bundler', '~> 1.0.0'
16
+ gem 'guard-rspec', '~> 2.4.1'
17
+
18
+ # file system change event handling
19
+ gem 'rb-fchange', '~> 0.0.6', :require => false
20
+ gem 'rb-fsevent', '~> 0.9.3', :require => false
21
+ gem 'rb-inotify', '~> 0.9.0', :require => false
22
+
23
+ gem 'listen', '~> 0.7.3'
24
+
25
+ # notification handling
26
+ gem 'libnotify', '~> 0.8.0', :require => false
27
+ gem 'rb-notifu', '~> 0.0.4', :require => false
28
+ gem 'terminal-notifier-guard', '~> 1.5.3', :require => false
29
+ end
30
+
31
+ group :metrics do
32
+ gem 'flay', '~> 2.1.0'
33
+ gem 'flog', '~> 3.2.2'
34
+ gem 'reek', '~> 1.3.1', :git => 'https://github.com/troessner/reek.git'
35
+ gem 'metric_fu-roodi', '~> 2.2.1'
36
+ gem 'yardstick', '~> 0.9.4'
37
+
38
+ platforms :ruby_18, :ruby_19 do
39
+ # this indirectly depends on ffi which does not build on ruby-head
40
+ gem 'yard-spellcheck', '~> 0.1.5'
41
+ end
42
+
43
+ platforms :mri_19, :rbx do
44
+ gem 'mutant', '~> 0.2.20'
45
+ end
46
+
47
+ platforms :mri_19 do
48
+ gem 'simplecov', '~> 0.7.1'
49
+ end
50
+
51
+ platforms :rbx do
52
+ gem 'pelusa', '~> 0.2.2'
53
+ end
54
+ end
55
+
56
+ group :benchmarks do
57
+ gem 'rbench', '~> 0.2.3'
58
+ end
59
+
60
+ platform :jruby do
61
+ group :jruby do
62
+ gem 'jruby-openssl', '~> 0.8.2'
63
+ end
64
+ end
data/Guardfile ADDED
@@ -0,0 +1,8 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec' do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+ end
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Markus Schirp
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.
data/README.md ADDED
@@ -0,0 +1,79 @@
1
+ concord
2
+ =======
3
+
4
+ [![Build Status](https://secure.travis-ci.org/mbj/concord.png?branch=master)](http://travis-ci.org/mbj/concord)
5
+ [![Dependency Status](https://gemnasium.com/mbj/concord.png)](https://gemnasium.com/mbj/concord)
6
+ [![Code Climate](https://codeclimate.com/github/mbj/concord.png)](https://codeclimate.com/github/mbj/concord)
7
+
8
+ Library to transform this:
9
+
10
+ ```ruby
11
+ class ComposedObject
12
+ include Equalizer.new(:foo, :bar)
13
+
14
+ # Return foo
15
+ #
16
+ # @return [Foo]
17
+ #
18
+ # @api private
19
+ #
20
+ attr_reader :foo
21
+
22
+ # Return bar
23
+ #
24
+ # @return [Bar]
25
+ #
26
+ # @api private
27
+ #
28
+ attr_reader :bar
29
+
30
+ # Initialize object
31
+ #
32
+ # @param [Foo] foo
33
+ # @param [Bar] bar
34
+ #
35
+ # @return [undefined]
36
+ #
37
+ # @api private
38
+ #
39
+ def initialize(foo, bar)
40
+ @foo, @bar = foo, bar
41
+ end
42
+ end
43
+ ```
44
+
45
+ Into shorter and easier to parse by eyes:
46
+
47
+ ```ruby
48
+ class ComposedObject
49
+ include Concord.new(:foo, :bar)
50
+ end
51
+ ```
52
+
53
+ Sure the replacement is missing YARD docs, but IMHO it is better.
54
+
55
+ Installation
56
+ ------------
57
+
58
+ Install the gem `concord` via your prefered method.
59
+
60
+ Credits
61
+ -------
62
+
63
+ * [mbj](https://github.com/mbj)
64
+
65
+ Contributing
66
+ -------------
67
+
68
+ * Fork the project.
69
+ * Make your feature addition or bug fix.
70
+ * Add tests for it. This is important so I don't break it in a
71
+ future version unintentionally.
72
+ * Commit, do not mess with Rakefile or version
73
+ (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)
74
+ * Send me a pull request. Bonus points for topic branches.
75
+
76
+ License
77
+ -------
78
+
79
+ See LICENSE
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'devtools'
2
+ Devtools.init_rake_tasks
data/concord.gemspec ADDED
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'concord'
5
+ s.version = '0.0.1'
6
+ s.authors = ['Markus Schirp']
7
+ s.email = ['mbj@seonic.net']
8
+ s.homepage = 'https://github.com/mbj/composition'
9
+ s.summary = %q{Helper for object composition}
10
+ s.description = s.summary
11
+
12
+ s.files = `git ls-files`.split("\n")
13
+ s.test_files = `git ls-files -- {spec}/*`.split("\n")
14
+ s.executables = []
15
+ s.require_paths = ['lib']
16
+
17
+ s.add_dependency('backports', '~> 3.0.3')
18
+ s.add_dependency('adamantium', '~> 0.0.7')
19
+ s.add_dependency('equalizer', '~> 0.0.5')
20
+ end
data/config/flay.yml ADDED
@@ -0,0 +1,3 @@
1
+ ---
2
+ threshold: 2
3
+ total_score: 8.0
data/config/flog.yml ADDED
@@ -0,0 +1,2 @@
1
+ ---
2
+ threshold: 10.0
data/config/mutant.yml ADDED
@@ -0,0 +1,2 @@
1
+ name: concord
2
+ namespace: Concord
data/config/roodi.yml ADDED
@@ -0,0 +1,20 @@
1
+ ---
2
+ AbcMetricMethodCheck:
3
+ score: 25.1
4
+ AssignmentInConditionalCheck: { }
5
+ CaseMissingElseCheck: { }
6
+ ClassLineCountCheck: { line_count: 317 }
7
+ ClassNameCheck:
8
+ pattern: !ruby/regexp /\A(?:[A-Z]+|[A-Z][a-z](?:[A-Z]?[a-z])+)\z/
9
+ ClassVariableCheck: { }
10
+ CyclomaticComplexityBlockCheck: { complexity: 3 }
11
+ CyclomaticComplexityMethodCheck: { complexity: 4 }
12
+ EmptyRescueBodyCheck: { }
13
+ ForLoopCheck: { }
14
+ MethodLineCountCheck: { line_count: 14 }
15
+ MethodNameCheck:
16
+ pattern: !ruby/regexp /\A(?:[a-z\d](?:_?[a-z\d])+[?!=]?|\[\]=?|==|<=>|<<|[+*&|-])\z/
17
+ ModuleLineCountCheck: { line_count: 320 }
18
+ ModuleNameCheck:
19
+ pattern: !ruby/regexp /\A(?:[A-Z]+|[A-Z][a-z](?:[A-Z]?[a-z])+)\z/
20
+ ParameterNumberCheck: { parameter_count: 3 }
data/config/site.reek ADDED
@@ -0,0 +1,90 @@
1
+ UncommunicativeParameterName:
2
+ accept: []
3
+ exclude: []
4
+ enabled: true
5
+ reject:
6
+ - !ruby/regexp /^.$/
7
+ - !ruby/regexp /[0-9]$/
8
+ - !ruby/regexp /[A-Z]/
9
+ LargeClass:
10
+ max_methods: 14
11
+ enabled: true
12
+ exclude: []
13
+ max_instance_variables: 4
14
+ UncommunicativeMethodName:
15
+ accept: []
16
+ exclude: []
17
+ enabled: true
18
+ reject:
19
+ - !ruby/regexp /^[a-z]$/
20
+ - !ruby/regexp /[0-9]$/
21
+ - !ruby/regexp /[A-Z]/
22
+ LongParameterList:
23
+ max_params: 2
24
+ exclude: []
25
+ enabled: true
26
+ overrides: {}
27
+ FeatureEnvy:
28
+ exclude:
29
+ - Concord#define_readers
30
+ enabled: true
31
+ ClassVariable:
32
+ exclude: []
33
+ enabled: true
34
+ BooleanParameter:
35
+ exclude: []
36
+ enabled: true
37
+ IrresponsibleModule:
38
+ exclude: []
39
+ enabled: true
40
+ UncommunicativeModuleName:
41
+ accept: []
42
+ exclude: []
43
+ enabled: true
44
+ reject:
45
+ - !ruby/regexp /^.$/
46
+ - !ruby/regexp /[0-9]$/
47
+ NestedIterators:
48
+ ignore_iterators: []
49
+ exclude: []
50
+ enabled: true
51
+ max_allowed_nesting: 1
52
+ LongMethod:
53
+ max_statements: 5
54
+ exclude: []
55
+ enabled: true
56
+ Duplication:
57
+ allow_calls: []
58
+ exclude: []
59
+ enabled: true
60
+ max_calls: 1
61
+ UtilityFunction:
62
+ max_helper_calls: 0
63
+ exclude: []
64
+ enabled: true
65
+ Attribute:
66
+ exclude: []
67
+ enabled: false
68
+ UncommunicativeVariableName:
69
+ accept: []
70
+ exclude: []
71
+ enabled: true
72
+ reject:
73
+ - !ruby/regexp /^.$/
74
+ - !ruby/regexp /[0-9]$/
75
+ - !ruby/regexp /[A-Z]/
76
+ SimulatedPolymorphism:
77
+ enabled: true
78
+ max_ifs: 1
79
+ DataClump:
80
+ exclude: []
81
+ enabled: true
82
+ max_copies: 0
83
+ min_clump_size: 2
84
+ ControlCouple:
85
+ exclude: []
86
+ enabled: true
87
+ LongYieldList:
88
+ max_params: 0
89
+ exclude: []
90
+ enabled: true
@@ -0,0 +1,2 @@
1
+ ---
2
+ threshold: 100
data/lib/concord.rb ADDED
@@ -0,0 +1,108 @@
1
+ require 'adamantium'
2
+ require 'equalizer'
3
+
4
+ # A mixin to define a composition
5
+ class Concord < Module
6
+ include Adamantium::Flat, Equalizer.new(:names)
7
+
8
+ # Return names
9
+ #
10
+ # @return [Enumerable<Symbol>]
11
+ #
12
+ # @api private
13
+ #
14
+ attr_reader :names
15
+
16
+ private
17
+
18
+ # Initialize object
19
+ #
20
+ # @return [undefined]
21
+ #
22
+ # @api private
23
+ #
24
+ def initialize(*names)
25
+ if names.length > 3
26
+ raise 'Composition of more than three objects is not allowed'
27
+ end
28
+
29
+ @names = names
30
+ end
31
+
32
+ # Hook run when module is included
33
+ #
34
+ # @param [Class|Module] descendant
35
+ #
36
+ # @return [undefined]
37
+ #
38
+ # @api private
39
+ #
40
+ def included(descendant)
41
+ define_initializer(descendant)
42
+ define_readers(descendant)
43
+ define_equalizer(descendant)
44
+ end
45
+
46
+ # Define equalizer
47
+ #
48
+ # @param [Class|Module] descendant
49
+ #
50
+ # @return [undefined]
51
+ #
52
+ # @api private
53
+ #
54
+ def define_equalizer(descendant)
55
+ descendant.send(:include, Equalizer.new(*@names))
56
+ end
57
+
58
+ # Define readers
59
+ #
60
+ # @param [Class|Module] descendant
61
+ #
62
+ # @return [undefined]
63
+ #
64
+ # @api private
65
+ #
66
+ def define_readers(descendant)
67
+ attribute_names = names
68
+ descendant.send(:attr_reader, *attribute_names)
69
+ end
70
+
71
+ # Define initializer
72
+ #
73
+ # @param [Class|Module] descendant
74
+ #
75
+ # @return [undefined]
76
+ #
77
+ # @api private
78
+ #
79
+ def define_initializer(descendant)
80
+ names = argument_names
81
+ descendant.class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
82
+ def initialize(#{names}) # def initialize(foo, bar)
83
+ #{instance_variable_names} = #{names} # @foo, @bar = foo, bar
84
+ end # end
85
+ RUBY
86
+ end
87
+
88
+ # Return instance variable names
89
+ #
90
+ # @return [String]
91
+ #
92
+ # @api private
93
+ #
94
+ def instance_variable_names
95
+ names.map { |name| "@#{name}" }.join(', ')
96
+ end
97
+
98
+ # Return param names
99
+ #
100
+ # @return [String]
101
+ #
102
+ # @api private
103
+ #
104
+ def argument_names
105
+ names.join(', ')
106
+ end
107
+
108
+ end
@@ -0,0 +1,3 @@
1
+ require 'devtools'
2
+ require 'concord'
3
+ Devtools.init_spec_helper
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ describe Concord do
4
+
5
+ let(:class_under_test) do
6
+ Class.new do
7
+ include Concord.new(:foo, :bar)
8
+ end
9
+ end
10
+
11
+ let(:instance_a) { class_under_test.new(foo, bar) }
12
+ let(:instance_b) { class_under_test.new(foo, bar) }
13
+ let(:instance_c) { class_under_test.new(foo, mock('Baz')) }
14
+
15
+ let(:foo) { mock('Foo') }
16
+ let(:bar) { mock('Bar') }
17
+
18
+ context 'initializer lines' do
19
+ unless Devtools.jruby?
20
+ it 'sets initializer correctly' do
21
+ klass = Class.new
22
+ # Nicher way to assert this?
23
+ klass.should_receive(:class_eval) do |code, file, line|
24
+ file.should eql(File.expand_path('../../../../lib/concord.rb', __FILE__))
25
+ line.should be(82)
26
+ end
27
+ klass.send(:include, Concord.new)
28
+ end
29
+ end
30
+ end
31
+
32
+ context 'attribute behavior' do
33
+ subject { instance_a }
34
+
35
+ its(:foo) { should be(foo) }
36
+ its(:bar) { should be(bar) }
37
+ end
38
+
39
+ context 'equalization behavior' do
40
+ specify 'composed objects are equalized on attributes' do
41
+ instance_a.should == instance_b
42
+ instance_a.hash.should == instance_b.hash
43
+ instance_a.should eql(instance_b)
44
+
45
+ instance_a.should_not == instance_c
46
+ instance_a.should_not eql(instance_c)
47
+ end
48
+ end
49
+
50
+ context 'to much composition behavior' do
51
+ specify 'it raises an error' do
52
+ expect { Concord.new(:a, :b, :c, :d) }.to raise_error(RuntimeError, 'Composition of more than three objects is not allowed')
53
+ end
54
+ end
55
+ end
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: concord
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Markus Schirp
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-06 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: backports
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 3.0.3
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 3.0.3
30
+ - !ruby/object:Gem::Dependency
31
+ name: adamantium
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 0.0.7
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 0.0.7
46
+ - !ruby/object:Gem::Dependency
47
+ name: equalizer
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 0.0.5
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.0.5
62
+ description: Helper for object composition
63
+ email:
64
+ - mbj@seonic.net
65
+ executables: []
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - .gitignore
70
+ - .rspec
71
+ - .travis.yml
72
+ - Changelog.md
73
+ - Gemfile
74
+ - Gemfile.devtools
75
+ - Guardfile
76
+ - LICENSE
77
+ - README.md
78
+ - Rakefile
79
+ - concord.gemspec
80
+ - config/flay.yml
81
+ - config/flog.yml
82
+ - config/mutant.yml
83
+ - config/roodi.yml
84
+ - config/site.reek
85
+ - config/yardstick.yml
86
+ - lib/concord.rb
87
+ - spec/spec_helper.rb
88
+ - spec/unit/concord/universal_spec.rb
89
+ homepage: https://github.com/mbj/composition
90
+ licenses: []
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ! '>='
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ none: false
103
+ requirements:
104
+ - - ! '>='
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubyforge_project:
109
+ rubygems_version: 1.8.23
110
+ signing_key:
111
+ specification_version: 3
112
+ summary: Helper for object composition
113
+ test_files: []
114
+ has_rdoc: