concord 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: