modularity 2.0.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 5bd19df6610f9cadb9ba1bd5a88552537c32245d
4
- data.tar.gz: cf2bf788602724e9927093685a0474b8fe3d8397
2
+ SHA256:
3
+ metadata.gz: 429e10c8fecef4d2111b5ca35805fe7d034869422e3ab1c098378e6f970f8caa
4
+ data.tar.gz: e0cecc3bda150b73fb39b7fff2eef48d328dba303bb8842b5aa28be09287f26f
5
5
  SHA512:
6
- metadata.gz: f1d52d9653cded8e868156da655f6d020d63473d3e5b4b95dfd0071b504c1a811997077d79ca642100271885739b2ceac8be4de08a706ae87ebbc93f739cc248
7
- data.tar.gz: 3d46ef0be45c6f6beefe09f99c17b8c0c67d82494b822c988074b025eb5b065c41f772b522db016adeca357ec3d90acd3b794faba316a4069c91e499c3561013
6
+ metadata.gz: 4526b4df0b655e0eb5de00b82a65f8081bd51390bbb71e2ac3ff38c670b8b541e9b24df7935d563e51d7f07d8a6a3fc8af83c0e803321d5fef47238cd640f080
7
+ data.tar.gz: bd2ba2ab6fe3ba0150d07c43022d8eccd9f7bf17f669d1d4c6f6df129b5bdc42e22d9212c56886dff34c5f2d41217360fcbd3fb91ebd02e9984162b8d2aa93c7
@@ -0,0 +1,36 @@
1
+ ---
2
+ name: Tests
3
+ 'on':
4
+ push:
5
+ branches:
6
+ - master
7
+ pull_request:
8
+ branches:
9
+ - master
10
+ jobs:
11
+ test:
12
+ runs-on: ubuntu-20.04
13
+ strategy:
14
+ fail-fast: false
15
+ matrix:
16
+ include:
17
+ - ruby: 2.5.7
18
+ gemfile: Gemfile
19
+ - ruby: 2.7.4
20
+ gemfile: Gemfile
21
+ - ruby: 3.0.2
22
+ gemfile: Gemfile
23
+ env:
24
+ BUNDLE_GEMFILE: "${{ matrix.gemfile }}"
25
+ steps:
26
+ - uses: actions/checkout@v2
27
+ - name: Install ruby
28
+ uses: ruby/setup-ruby@v1
29
+ with:
30
+ ruby-version: "${{ matrix.ruby }}"
31
+ - name: Bundle
32
+ run: |
33
+ gem install bundler:2.2.22
34
+ bundle install --no-deployment
35
+ - name: Run tests
36
+ run: bundle exec rspec
data/.gitignore CHANGED
@@ -2,4 +2,3 @@ doc
2
2
  pkg
3
3
  *.gem
4
4
  .idea
5
- Gemfile.lock
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.5.7
data/CHANGELOG.md ADDED
@@ -0,0 +1,22 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
5
+
6
+ ## Unreleased
7
+
8
+ ### Breaking changes
9
+
10
+ ### Compatible changes
11
+
12
+
13
+ ## 3.0.0 - 2021-08-24
14
+
15
+ ### Breaking changes
16
+
17
+ - Removed migration guide for modularity version 1.
18
+ - Removed support for Ruby < `2.5.0`.
19
+
20
+ ### Compatible changes
21
+
22
+ - Added this CHANGELOG file.
data/Gemfile CHANGED
@@ -1,3 +1,8 @@
1
- source "http://rubygems.org"
1
+ source 'http://rubygems.org'
2
2
 
3
3
  gemspec
4
+
5
+ gem 'rake'
6
+ gem 'rspec'
7
+ gem 'pry-byebug'
8
+ gem 'gemika'
data/Gemfile.lock ADDED
@@ -0,0 +1,47 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ modularity (3.0.0)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ byebug (11.1.3)
10
+ coderay (1.1.3)
11
+ diff-lcs (1.4.4)
12
+ gemika (0.6.1)
13
+ method_source (1.0.0)
14
+ pry (0.13.1)
15
+ coderay (~> 1.1)
16
+ method_source (~> 1.0)
17
+ pry-byebug (3.9.0)
18
+ byebug (~> 11.0)
19
+ pry (~> 0.13.0)
20
+ rake (13.0.6)
21
+ rspec (3.10.0)
22
+ rspec-core (~> 3.10.0)
23
+ rspec-expectations (~> 3.10.0)
24
+ rspec-mocks (~> 3.10.0)
25
+ rspec-core (3.10.1)
26
+ rspec-support (~> 3.10.0)
27
+ rspec-expectations (3.10.1)
28
+ diff-lcs (>= 1.2.0, < 2.0)
29
+ rspec-support (~> 3.10.0)
30
+ rspec-mocks (3.10.2)
31
+ diff-lcs (>= 1.2.0, < 2.0)
32
+ rspec-support (~> 3.10.0)
33
+ rspec-support (3.10.2)
34
+
35
+ PLATFORMS
36
+ ruby
37
+ x86_64-linux
38
+
39
+ DEPENDENCIES
40
+ gemika
41
+ modularity!
42
+ pry-byebug
43
+ rake
44
+ rspec
45
+
46
+ BUNDLED WITH
47
+ 2.2.26
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2009 Henning Koch
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
- Modularity 2 - Traits and partial classes for Ruby
2
- ==================================================
1
+ [![Tests](https://github.com/makandra/modularity/workflows/Tests/badge.svg)](https://github.com/makandra/modularity/actions)
2
+
3
+ # Modularity 2 - Traits and partial classes for Ruby
3
4
 
4
5
  Modularity enhances Ruby's [`Module`](http://apidock.com/ruby/Module) so it can be used traits and partial classes.
5
6
  This allows very simple definition of meta-programming macros like the
@@ -8,13 +9,17 @@ This allows very simple definition of meta-programming macros like the
8
9
  Modularity also lets you organize large models into multiple source files
9
10
  in a way that is less awkward than using modules.
10
11
 
11
- Note that this is **Modularity 2**, which has a different syntax older version.
12
- Modularity 1 users can use [a script to migrate their code](#migrating-from-modularity-1)
13
- or use the [modularity1 branch](https://github.com/makandra/modularity/tree/modularity1).
12
+ ## Installation
13
+
14
+ Add the following to your `Gemfile`:
14
15
 
16
+ ```
17
+ gem 'modularity'
18
+ ```
19
+
20
+ Now run `bundle install`.
15
21
 
16
- Example 1: Easy meta-programming macros
17
- ----------------------------------------
22
+ ## Example 1: Easy meta-programming macros
18
23
 
19
24
  Ruby allows you to construct classes using meta-programming macros like
20
25
  `acts_as_tree` or `has_many :items`. These macros will add methods,
@@ -27,81 +32,83 @@ and macros.
27
32
 
28
33
  Here is an example of a `strip_field` macro, which created setter methods that remove leading and trailing whitespace from newly assigned values:
29
34
 
30
- # app/models/article.rb
31
- class Article < ActiveRecord::Base
32
- include DoesStripFields[:name, :brand]
33
- end
34
-
35
- # app/models/shared/does_strip_fields.rb
36
- module DoesStripFields
37
- as_trait do |*fields|
38
- fields.each do |field|
39
- define_method("#{field}=") do |value|
40
- self[field] = value.strip
41
- end
42
- end
35
+ ```
36
+ # app/models/article.rb
37
+ class Article < ActiveRecord::Base
38
+ include DoesStripFields[:name, :brand]
39
+ end
40
+
41
+ # app/models/shared/does_strip_fields.rb
42
+ module DoesStripFields
43
+ as_trait do |*fields|
44
+ fields.each do |field|
45
+ define_method("#{field}=") do |value|
46
+ self[field] = value.strip
43
47
  end
44
48
  end
49
+ end
50
+ end
51
+ ```
45
52
 
46
53
  Notice the `as_trait` block.
47
54
 
48
55
  We like to add `app/models/shared` and `app/controllers/shared` to the load paths of our Rails projects.
49
56
  These are great places to store macros that are re-used from multiple classes.
50
57
 
51
-
52
- Example 2: Mixins with class methods
53
- ------------------------------------
58
+ ## Example 2: Mixins with class methods
54
59
 
55
60
  Using a module to add both instance methods and class methods is
56
61
  [very awkward](http://redcorundum.blogspot.com/2006/06/mixing-in-class-methods.html).
57
62
  Modularity does away with the clutter and lets you say this:
58
63
 
59
- # app/models/model.rb
60
- class Model
61
- include Mixin
64
+ ```
65
+ # app/models/model.rb
66
+ class Model
67
+ include Mixin
68
+ end
69
+
70
+ # app/models/mixin.rb
71
+ module Mixin
72
+ as_trait do
73
+ def instance_method
74
+ # ...
62
75
  end
63
-
64
- # app/models/mixin.rb
65
- module Mixin
66
- as_trait do
67
- def instance_method
68
- # ...
69
- end
70
- def self.class_method
71
- # ..
72
- end
73
- end
76
+ def self.class_method
77
+ # ..
74
78
  end
79
+ end
80
+ end
81
+ ```
75
82
 
76
83
  `private` and `protected` will also work as expected when defining a trait.
77
84
 
78
-
79
- Example 3: Splitting a model into multiple source files
80
- -------------------------------------------------------
85
+ ## Example 3: Splitting a model into multiple source files
81
86
 
82
87
  Models are often concerned with multiple themes like "authentication", "contact info" or "permissions", each requiring
83
88
  a couple of validations and callbacks here, and some method there. Modularity lets you organize your model into multiple
84
89
  partial classes, so each file can deal with a single aspect of your model:
85
90
 
86
- # app/models/user.rb
87
- class User < ActiveRecord::Base
88
- include DoesAuthentication
89
- include DoesPermissions
90
- end
91
-
92
- # app/models/user/does_authentication.rb
93
- module User::DoesAuthentication
94
- as_trait do
95
- # methods, validations, etc. regarding usernames and passwords go here
96
- end
97
- end
98
-
99
- # app/models/user/does_permissions.rb
100
- module User::DoesPermissions
101
- as_trait do
102
- # methods, validations, etc. regarding contact information go here
103
- end
104
- end
91
+ ```
92
+ # app/models/user.rb
93
+ class User < ActiveRecord::Base
94
+ include DoesAuthentication
95
+ include DoesPermissions
96
+ end
97
+
98
+ # app/models/user/does_authentication.rb
99
+ module User::DoesAuthentication
100
+ as_trait do
101
+ # methods, validations, etc. regarding usernames and passwords go here
102
+ end
103
+ end
104
+
105
+ # app/models/user/does_permissions.rb
106
+ module User::DoesPermissions
107
+ as_trait do
108
+ # methods, validations, etc. regarding contact information go here
109
+ end
110
+ end
111
+ ```
105
112
 
106
113
  Some criticism has been raised for splitting large models into files like this.
107
114
  Essentially, even though have an easier time navigating your code, you will still
@@ -110,41 +117,12 @@ have one giant model with many side effects.
110
117
  There are [many better ways](http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/)
111
118
  to decompose a huge Ruby class.
112
119
 
120
+ ## Development
113
121
 
114
- Installation
115
- ------------
122
+ * Install Bundler 2 `gem install bundler:2.2.22` and run `bundle install` to have a working development setup.
123
+ * Running tests for the current Ruby version: `bundle exec rake`
124
+ * Running tests for all supported Ruby version: Push the changes to Github in a feature branch, open a merge request and have a look at the test matrix in Github actions
116
125
 
117
- Add the following to your `Gemfile`:
118
-
119
- gem 'modularity', '>=2'
120
-
121
- Now run `bundle install`.
122
-
123
-
124
- Migrating from Modularity 1
125
- ---------------------------
126
-
127
- If you have been using Modularity 1 with the `does` syntax, we provide a script to migrate your Ruby project
128
- automatically.
129
-
130
- 1. Make sure your project has tests and you have a backup of your files (or pushed your commits to Git)
131
-
132
- 2. From your project directory, do this:
133
-
134
- find . -name "*.rb" | migrate-modularity1-to-modularity2
135
-
136
- 3. The script will rename your files and change your code. It will also syntax-check your files after conversion
137
- (since the script is not perfect).
138
-
139
- 4. Check the diff to see what the script has done.
140
-
141
- 5. Run tests to see if everything still works.
142
-
143
-
144
-
145
-
146
- Credits
147
- -------
126
+ ## Credits
148
127
 
149
128
  Henning Koch from [makandra.com](http://makandra.com/)
150
-
data/Rakefile CHANGED
@@ -1,12 +1,5 @@
1
- require 'rake'
2
- require 'spec/rake/spectask'
3
1
  require 'bundler/gem_tasks'
2
+ require 'bundler/setup'
3
+ require 'gemika/tasks'
4
4
 
5
- desc 'Default: Run all specs.'
6
- task :default => :spec
7
-
8
- desc "Run all specs"
9
- Spec::Rake::SpecTask.new() do |t|
10
- t.spec_opts = ['--options', "\"spec/spec.opts\""]
11
- t.spec_files = FileList['spec/**/*_spec.rb']
12
- end
5
+ task default: 'matrix:spec'
data/bin/console ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'modularity'
5
+ require 'pry'
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+ Pry.start
@@ -1,3 +1,3 @@
1
1
  module Modularity
2
- VERSION = '2.0.1'
2
+ VERSION = '3.0.0'
3
3
  end
data/modularity.gemspec CHANGED
@@ -1,23 +1,27 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
1
+ lib = File.expand_path('lib', __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
3
  require 'modularity/version'
4
4
 
5
- Gem::Specification.new do |s|
6
- s.name = %q{modularity}
7
- s.version = Modularity::VERSION
8
- s.authors = ["Henning Koch"]
9
- s.email = %q{github@makandra.de}
10
- s.homepage = %q{http://github.com/makandra/modularity}
11
- s.summary = %q{Traits and partial classes for Ruby}
12
- s.description = %q{Traits and partial classes for Ruby}
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'modularity'
7
+ spec.version = Modularity::VERSION
8
+ spec.required_ruby_version = '>= 2.5.0'
9
+ spec.authors = ['Henning Koch']
10
+ spec.email = ['henning.koch@makandra.de']
13
11
 
14
- s.files = `git ls-files`.split("\n")
15
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
- s.require_paths = ["lib"]
12
+ spec.summary = 'Traits and partial classes for Ruby'
13
+ spec.description = 'Traits and partial classes for Ruby'
14
+ spec.homepage = 'https://github.com/makandra/modularity'
15
+ spec.license = 'MIT'
18
16
 
19
- s.add_development_dependency('rake')
20
- s.add_development_dependency('rspec', '<2')
21
- s.add_development_dependency('rspec_candy')
17
+ # Specify which files should be added to the gem when it is released.
18
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
19
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
20
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
21
+ end
22
+ spec.bindir = 'exe'
23
+ spec.executables = spec.files.grep(%r(^exe/)) { |f| File.basename(f) }
24
+ spec.require_paths = ['lib']
22
25
 
26
+ # Development dependencies are defined in the Gemfile (therefore no `spec.add_development_dependency` directives)
23
27
  end
metadata CHANGED
@@ -1,82 +1,40 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: modularity
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henning Koch
8
8
  autorequire:
9
- bindir: bin
9
+ bindir: exe
10
10
  cert_chain: []
11
- date: 2014-02-04 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: rake
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - '>='
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - '>='
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: rspec
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - <
32
- - !ruby/object:Gem::Version
33
- version: '2'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - <
39
- - !ruby/object:Gem::Version
40
- version: '2'
41
- - !ruby/object:Gem::Dependency
42
- name: rspec_candy
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'
11
+ date: 2021-08-24 00:00:00.000000000 Z
12
+ dependencies: []
55
13
  description: Traits and partial classes for Ruby
56
- email: github@makandra.de
57
- executables:
58
- - migrate-modularity1-to-modularity2
14
+ email:
15
+ - henning.koch@makandra.de
16
+ executables: []
59
17
  extensions: []
60
18
  extra_rdoc_files: []
61
19
  files:
62
- - .gitignore
20
+ - ".github/workflows/test.yml"
21
+ - ".gitignore"
22
+ - ".rspec"
23
+ - ".ruby-version"
24
+ - CHANGELOG.md
63
25
  - Gemfile
64
- - MIT-LICENSE
26
+ - Gemfile.lock
27
+ - LICENSE.txt
65
28
  - README.md
66
29
  - Rakefile
67
- - bin/migrate-modularity1-to-modularity2
30
+ - bin/console
68
31
  - lib/modularity.rb
69
32
  - lib/modularity/as_trait.rb
70
- - lib/modularity/migrator.rb
71
33
  - lib/modularity/version.rb
72
34
  - modularity.gemspec
73
- - spec/modularity/as_trait_spec.rb
74
- - spec/modularity/migrator_spec.rb
75
- - spec/rcov.opts
76
- - spec/spec.opts
77
- - spec/spec_helper.rb
78
- homepage: http://github.com/makandra/modularity
79
- licenses: []
35
+ homepage: https://github.com/makandra/modularity
36
+ licenses:
37
+ - MIT
80
38
  metadata: {}
81
39
  post_install_message:
82
40
  rdoc_options: []
@@ -84,17 +42,16 @@ require_paths:
84
42
  - lib
85
43
  required_ruby_version: !ruby/object:Gem::Requirement
86
44
  requirements:
87
- - - '>='
45
+ - - ">="
88
46
  - !ruby/object:Gem::Version
89
- version: '0'
47
+ version: 2.5.0
90
48
  required_rubygems_version: !ruby/object:Gem::Requirement
91
49
  requirements:
92
- - - '>='
50
+ - - ">="
93
51
  - !ruby/object:Gem::Version
94
52
  version: '0'
95
53
  requirements: []
96
- rubyforge_project:
97
- rubygems_version: 2.2.1
54
+ rubygems_version: 3.2.26
98
55
  signing_key:
99
56
  specification_version: 4
100
57
  summary: Traits and partial classes for Ruby
data/MIT-LICENSE DELETED
@@ -1,20 +0,0 @@
1
- Copyright (c) 2009 Henning Koch
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.
@@ -1,7 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require File.expand_path(File.dirname(__FILE__)) + '/../lib/modularity/migrator'
4
-
5
- ARGF.each do |path|
6
- Modularity::Migrator.migrate(path.strip)
7
- end
@@ -1,53 +0,0 @@
1
- gem 'activesupport'
2
- require 'active_support/all'
3
- require 'fileutils'
4
-
5
- module Modularity
6
- class Migrator
7
- class << self
8
-
9
- def migrate(old_path)
10
- old_path = File.expand_path(old_path)
11
- new_path = fix_filename(old_path)
12
- rename(old_path, new_path) unless old_path == new_path
13
- old_code = File.read(new_path)
14
- new_code = fix_code(old_code)
15
- rewrite_file(new_path, new_code) unless old_code == new_code
16
- puts "Migrated #{old_path}"
17
- `ruby -c #{new_path}`
18
- new_code
19
- end
20
-
21
- private
22
-
23
- def fix_filename(path)
24
- path = File.expand_path(path)
25
- new_path = path.sub(/\/([^\/]+)_trait\.rb$/, '/does_\\1.rb')
26
- new_path
27
- end
28
-
29
- def fix_code(code)
30
- code = code.gsub(/module (.*?)([A-Za-z0-9_]+)Trait\b/, 'module \\1Does\\2')
31
- code = code.gsub(/does ['":]([A-Za-z0-9\_\/]+)(?:'|"|$)(?:,\s*(.*)$)?/) do
32
- trait_path = $1
33
- parameters = $2
34
- trait_path = trait_path.sub(/([A-Za-z0-9\_]+)$/, 'does_\\1')
35
- trait_class = trait_path.camelize # don't use classify, it removes plurals!
36
- substituted = "include #{trait_class}"
37
- substituted << "[#{parameters}]" if parameters
38
- substituted
39
- end
40
- code
41
- end
42
-
43
- def rename(old, new)
44
- FileUtils.mv(old, new)
45
- end
46
-
47
- def rewrite_file(path, content)
48
- File.open(path, "w") { |file| file.write(content) }
49
- end
50
-
51
- end
52
- end
53
- end
@@ -1,210 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Modularity::AsTrait do
4
-
5
- describe '.included' do
6
-
7
- before :each do
8
- @doing_class = Class.new
9
- end
10
-
11
- describe 'without parameters' do
12
-
13
- it "applies the trait macro of the given module" do
14
-
15
- module DoesSome
16
- as_trait do
17
- some_trait_included
18
- end
19
- end
20
-
21
- @doing_class.should_receive(:some_trait_included)
22
-
23
- @doing_class.class_eval do
24
- include DoesSome
25
- end
26
-
27
- end
28
-
29
- it "applies the trait macro of the given namespaced module" do
30
-
31
- module Some
32
- module DoesChild
33
- as_trait do
34
- some_child_trait_included
35
- end
36
- end
37
- end
38
-
39
- @doing_class.should_receive(:some_child_trait_included)
40
-
41
- @doing_class.class_eval do
42
- include Some::DoesChild
43
- end
44
-
45
- end
46
-
47
- it "lets a trait define methods with different visibility" do
48
-
49
- module DoesVisibility
50
- as_trait do
51
- def public_method_from_trait
52
- end
53
- protected
54
- def protected_method_from_trait
55
- end
56
- private
57
- def private_method_from_trait
58
- end
59
- end
60
- end
61
-
62
- @doing_class.class_eval do
63
- include DoesVisibility
64
- end
65
-
66
- instance = @doing_class.new
67
-
68
- instance.public_methods.collect(&:to_s).should include("public_method_from_trait")
69
- instance.protected_methods.collect(&:to_s).should include("protected_method_from_trait")
70
- instance.private_methods.collect(&:to_s).should include("private_method_from_trait")
71
-
72
- end
73
-
74
- it 'appends methods outside the trait macro' do
75
-
76
- module HybridModule
77
-
78
- as_trait do
79
- define_method :trait_method do
80
- end
81
- end
82
-
83
- def vanilla_method
84
- end
85
-
86
- end
87
-
88
- @doing_class.class_eval do
89
- include HybridModule
90
- end
91
-
92
- instance = @doing_class.new
93
-
94
- instance.should respond_to(:trait_method)
95
- instance.should respond_to(:vanilla_method)
96
-
97
- end
98
-
99
- it 'applies multiple trait macros' do
100
-
101
- module FirstTrait
102
- as_trait do
103
- define_method :first do
104
- end
105
- end
106
- end
107
-
108
- module SecondTrait
109
- as_trait do
110
- define_method :second do
111
- end
112
- end
113
- end
114
-
115
- @doing_class.class_eval do
116
- include FirstTrait
117
- include SecondTrait
118
- end
119
-
120
- instance = @doing_class.new
121
-
122
- instance.should respond_to(:first)
123
- instance.should respond_to(:second)
124
-
125
- end
126
-
127
- end
128
-
129
- describe "with parameters" do
130
-
131
- it "it applies a trait macro with parameters" do
132
-
133
- module DoesCallMethod
134
- as_trait do |field|
135
- send(field)
136
- end
137
- end
138
-
139
- @doing_class.should_receive(:foo)
140
- @doing_class.class_eval do
141
- include DoesCallMethod[:foo]
142
- end
143
-
144
- end
145
-
146
- it "facilitates metaprogramming acrobatics" do
147
-
148
- module DoesDefineConstantMethod
149
- as_trait do |name, return_value|
150
- define_method name do
151
- return_value
152
- end
153
- end
154
- end
155
-
156
- @doing_class.class_eval do
157
- include DoesDefineConstantMethod["some_method", "some_return_value"]
158
- end
159
-
160
- instance = @doing_class.new
161
- instance.should respond_to(:some_method)
162
- instance.some_method.should == "some_return_value"
163
- end
164
-
165
- it "allies to call an unparametrized trait macro with an empty parameter list" do
166
-
167
- module DoesSome
168
- as_trait do
169
- some_trait_included
170
- end
171
- end
172
-
173
- @doing_class.should_receive(:some_trait_included)
174
-
175
- @doing_class.class_eval do
176
- include DoesSome[]
177
- end
178
-
179
- end
180
-
181
- it 'appends methods outside the trait macro' do
182
-
183
- module HybridModuleWithParameters
184
-
185
- as_trait do |name|
186
- define_method name do
187
- end
188
- end
189
-
190
- def vanilla_method
191
- end
192
-
193
- end
194
-
195
- @doing_class.class_eval do
196
- include HybridModuleWithParameters[:trait_method]
197
- end
198
-
199
- instance = @doing_class.new
200
-
201
- instance.should respond_to(:trait_method)
202
- instance.should respond_to(:vanilla_method)
203
-
204
- end
205
-
206
- end
207
-
208
- end
209
-
210
- end
@@ -1,109 +0,0 @@
1
- require 'spec_helper'
2
-
3
- require 'modularity/migrator' # this is an optional file and thus not loaded automatically
4
-
5
- describe Modularity::Migrator do
6
-
7
- subject do
8
- Modularity::Migrator
9
- end
10
-
11
- describe '.fix_filename' do
12
-
13
- it 'should replace the suffix _trait with a prefix does' do
14
- subject.send(:fix_filename, '/path/to/search_trait.rb').should == '/path/to/does_search.rb'
15
- end
16
-
17
- it "should not rename files that don't end in _trait.rb" do
18
- subject.send(:fix_filename, '/path/to/search.rb').should == '/path/to/search.rb'
19
- end
20
-
21
- end
22
-
23
- describe '.fix_code' do
24
-
25
- it 'renames a module FooBarTrait to DoesFooBar' do
26
-
27
- old_code = <<-RUBY
28
- module Namespace::FooBarTrait
29
- as_trait do
30
- define_method :foo do
31
- end
32
- define_method :bar do
33
- end
34
- end
35
- end
36
- RUBY
37
-
38
- new_code = <<-RUBY
39
- module Namespace::DoesFooBar
40
- as_trait do
41
- define_method :foo do
42
- end
43
- define_method :bar do
44
- end
45
- end
46
- end
47
- RUBY
48
-
49
- subject.send(:fix_code, old_code).should == new_code
50
- end
51
-
52
- it "does not rename modules that aren't traits" do
53
-
54
- old_code = <<-RUBY
55
- module Namespace::FooBar
56
- def foo
57
- end
58
- def bar
59
- end
60
- end
61
- RUBY
62
-
63
- subject.send(:fix_code, old_code).should == old_code
64
- end
65
-
66
- it 'replaces does calls with include' do
67
-
68
- old_code = <<-RUBY
69
- class User < ActiveRecord::Base
70
- does 'user/search'
71
- does 'user/account_settings'
72
- does 'trashable'
73
- end
74
- RUBY
75
-
76
- new_code = <<-RUBY
77
- class User < ActiveRecord::Base
78
- include User::DoesSearch
79
- include User::DoesAccountSettings
80
- include DoesTrashable
81
- end
82
- RUBY
83
-
84
- subject.send(:fix_code, old_code).should == new_code
85
- end
86
-
87
- it 'puts does parameters into square brackets' do
88
-
89
- old_code = <<-RUBY
90
- class User < ActiveRecord::Base
91
- does 'flag', :active, :default => true
92
- does 'record/search', :field => :email
93
- end
94
- RUBY
95
-
96
- new_code = <<-RUBY
97
- class User < ActiveRecord::Base
98
- include DoesFlag[:active, :default => true]
99
- include Record::DoesSearch[:field => :email]
100
- end
101
- RUBY
102
-
103
- subject.send(:fix_code, old_code).should == new_code
104
-
105
- end
106
-
107
- end
108
-
109
- end
data/spec/rcov.opts DELETED
@@ -1,2 +0,0 @@
1
- --exclude "spec/*,gems/*"
2
- --rails
data/spec/spec.opts DELETED
@@ -1,4 +0,0 @@
1
- --colour
2
- --format progress
3
- --loadby mtime
4
- --reverse
data/spec/spec_helper.rb DELETED
@@ -1,4 +0,0 @@
1
- $: << File.join(File.dirname(__FILE__), "/../lib" )
2
-
3
- require "#{File.dirname(__FILE__)}/../lib/modularity"
4
- require 'rspec_candy/all'