synecdoche 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ Copyright (c) 2012 Dan Swain
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+
data/README.md ADDED
@@ -0,0 +1,109 @@
1
+ # Synecdoche
2
+
3
+ Synecdoche:
4
+ >_a figure of speech by which a part is put for the
5
+ >whole (as fifty sail for fifty ships), the whole for a part (as
6
+ >society for high society), the species for the genus (as cutthroat for
7
+ >assassin), the genus for the species (as a creature for a man), or the
8
+ >name of the material for the thing made (as boards for stage)_
9
+ >[m-w.com](http://www.merriam-webster.com/dictionary/synecdoche)
10
+
11
+ Synecdoche is a Ruby gem that enables you to include parts of a file,
12
+ class, or module. It is useful for testing specific methods that can
13
+ stand alone but are part of a larger module that has potentially
14
+ complex dependencies.
15
+
16
+ In some sense, Synecdoche solves a problem that shouldn't exist. Your
17
+ code _should_ be written so that each logical piece of code is
18
+ testable on its own. However, in the real world, you sometimes have
19
+ to work with code involving large modules with complex dependencies.
20
+
21
+ Synecdoche is a tool that you can use to refactor complex code. It
22
+ allows you to test the parts of the code that you want to refactor
23
+ while they are still embedded in larger modules. Then, once you have
24
+ tests, you can refactor with confidence, and eventually you won't
25
+ need Synecdoche anymore.
26
+
27
+ ## License
28
+
29
+ Synecdoche is released under the
30
+ [MIT license](http://en.wikipedia.org/wiki/MIT_License).
31
+ See the LICENSE file.
32
+
33
+ ## Requirements
34
+
35
+ Synecdoche should work on any Ruby. It's only been tested on Ruby
36
+ 1.9.3 so far, though.
37
+
38
+ ## Installation
39
+
40
+ _Note: The gem hasn't been published yet and I haven't added the
41
+ Rakefile yet. These tasks will be done soon._
42
+
43
+ If your system is set up to allow it, you can just do
44
+
45
+ gem install synecdoche
46
+
47
+ Or, if you prefer a more hands-on approach or want to hack at the source:
48
+
49
+ git clone git://github.com/simplifi/synecdoche.git
50
+ cd synecdoche
51
+ rake install
52
+
53
+ If you are working on a system where you need to `sudo gem install`
54
+ you can do
55
+
56
+ rake gem
57
+ sudo gem install synecdoche
58
+
59
+ As always, you can `rake -T` to find out what other rake tasks we have
60
+ provided.
61
+
62
+ ## Basic Usage
63
+
64
+ Suppose we have a class `SomeClass` defined in `some_class.rb`:
65
+
66
+ # some_class.rb
67
+
68
+ # potentially lots of dependencies here
69
+
70
+ class SomeClass
71
+ # other methods, etc...
72
+
73
+ # a method we'd like to refactor
74
+ def double x
75
+ 2*x
76
+ end
77
+
78
+ end
79
+
80
+ Using Synecdoche, we could extract `SomeClass#double` into a smaller
81
+ class without needing to import all of `some_class.rb`:
82
+
83
+ # spec/test_double_method.rb
84
+
85
+ require 'synecdoche'
86
+
87
+ class PartialSomeClass < Synecdoche::PartialClass
88
+ include_method :double
89
+ end
90
+
91
+ If the directories are set up right, Synecdoche will guess the file
92
+ name (using Rails' camel casing guidelines) of the source file.
93
+ Otherwise we could do `include_method :double, :file_name =>
94
+ "path/to/some_class.rb"`.
95
+
96
+ More docs coming soon.
97
+
98
+ ## Contributing
99
+
100
+ The usual github process applies here:
101
+
102
+ 1. Fork it
103
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
104
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
105
+ 4. Push to the branch (`git push origin my-new-feature`)
106
+ 5. Create new Pull Request
107
+
108
+ You can also contribute to the author's ego by letting him know that
109
+ you find String Eater useful ;)
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ require 'rake/clean'
2
+
3
+ project_name = "synecdoche"
4
+
5
+ desc "Run rspec spec/ (compile if needed)"
6
+ task :test do
7
+ sh "rspec spec/"
8
+ end
9
+
10
+ desc "Create gem"
11
+ task :gem => "#{project_name}.gemspec" do
12
+ sh "gem build #{project_name}.gemspec"
13
+ end
14
+
15
+ desc "Install using 'gem install'"
16
+ task :install => :gem do
17
+ sh "gem install #{project_name}"
18
+ end
@@ -0,0 +1,11 @@
1
+ $LOAD_PATH.unshift(File.expand_path("../lib", File.dirname(__FILE__)))
2
+
3
+ require 'synecdoche'
4
+
5
+ class PartialSomeClass < Synecdoche::PartialClass
6
+ include_method :double
7
+ end
8
+
9
+ c = PartialSomeClass.new
10
+
11
+ puts c.double(2)
@@ -0,0 +1,5 @@
1
+ class SomeClass
2
+ def double x
3
+ 2*x
4
+ end
5
+ end
@@ -0,0 +1,33 @@
1
+ module Synecdoche
2
+ class PartialClass
3
+ def self.parser
4
+ @parser ||= Synecdoche::SourceParser.new
5
+ end
6
+
7
+ def self.from_file file_name
8
+ @file_name = file_name
9
+ end
10
+
11
+ def self.part_of class_name
12
+ @class_name = class_name
13
+ end
14
+
15
+ def self.class_name
16
+ @class_name ||= name.gsub(/\APartial/, '')
17
+ end
18
+
19
+ def self.file_name
20
+ @file_name ||= (Synecdoche::SourceParser::underscore(class_name) + ".rb")
21
+ end
22
+
23
+ def self.include_method name, opts={}
24
+ from_file(opts[:file_name]) if opts[:file_name]
25
+ part_of(opts[:class_name]) if opts[:class_name]
26
+
27
+ parser.ensure_parsed(file_name)
28
+ source = parser.method_source_in_class(name, class_name)
29
+
30
+ class_eval(source)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,38 @@
1
+ require 'rdoc'
2
+ require 'rdoc/rdoc'
3
+
4
+ module Synecdoche
5
+ class SourceParser
6
+ def self.underscore string
7
+ string.gsub(/::/, '/').
8
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
9
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
10
+ tr("-", "_").
11
+ downcase
12
+ end
13
+
14
+ def initialize
15
+ @rdoc = RDoc::RDoc.new
16
+ @rdoc.options = RDoc::Options.new
17
+ end
18
+
19
+ def parse_file file_name
20
+ @file_name = file_name
21
+ @file = @rdoc.parse_files([file_name]).first
22
+ end
23
+
24
+ def ensure_parsed file_name
25
+ unless @file && (@file_name == file_name)
26
+ parse_file(file_name)
27
+ end
28
+ end
29
+
30
+ def method_source_in_class method_name, class_name
31
+ raise "No file parsed" unless @file
32
+ klass = @file.classes.find{|c| c.name == class_name.to_s}
33
+ klass.method_list.find do |m|
34
+ m.name == method_name.to_s
35
+ end.tokens_to_s
36
+ end
37
+ end
38
+ end
data/lib/synecdoche.rb ADDED
@@ -0,0 +1,5 @@
1
+ module Synecdoche
2
+ autoload :SourceParser, 'source_parser/source_parser'
3
+ autoload :PartialClass, 'partial_class/partial_class'
4
+ autoload :VERSION, 'version/version'
5
+ end
@@ -0,0 +1,9 @@
1
+ module Synecdoche
2
+ module VERSION
3
+ MAJOR = 0
4
+ MINOR = 1
5
+ PATCH = 0
6
+ PRE = nil
7
+ STRING = [MAJOR, MINOR, PATCH, PRE].compact.join('.')
8
+ end
9
+ end
metadata ADDED
@@ -0,0 +1,55 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: synecdoche
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Dan Swain
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-24 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Include parts of a class in another class.
15
+ email:
16
+ - dan@simpli.fi
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - lib/synecdoche.rb
22
+ - lib/partial_class/partial_class.rb
23
+ - lib/source_parser/source_parser.rb
24
+ - lib/version/version.rb
25
+ - examples/partial_class.rb
26
+ - examples/some_class.rb
27
+ - LICENSE
28
+ - Rakefile
29
+ - README.md
30
+ homepage: http://github.com/simplifi/synecdoche
31
+ licenses: []
32
+ post_install_message:
33
+ rdoc_options: []
34
+ require_paths:
35
+ - lib
36
+ required_ruby_version: !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ! '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ required_rubygems_version: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ requirements: []
49
+ rubyforge_project:
50
+ rubygems_version: 1.8.24
51
+ signing_key:
52
+ specification_version: 3
53
+ summary: Include parts of a class in another class. Useful for refactoring large
54
+ modules with complex dependencies.
55
+ test_files: []