metamorpher 0.1.0 → 0.1.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +6 -3
- data/.ruby-version +1 -0
- data/.travis.yml +4 -1
- data/Gemfile +0 -1
- data/README.md +75 -2
- data/Rakefile +1 -1
- data/examples/refactorings/rails/where_first/app.rb +1 -1
- data/examples/refactorings/rails/where_first/refactorers/refactor_where_first_mocks.rb +6 -6
- data/examples/refactorings/rails/where_first/refactorers/refactor_where_first_strict_mocks.rb +2 -2
- data/lib/metamorpher/builders/ast/builder.rb +1 -0
- data/lib/metamorpher/builders/ast/greedy_variable_builder.rb +1 -1
- data/lib/metamorpher/builders/ast/literal_builder.rb +2 -2
- data/lib/metamorpher/builders/ast/variable_builder.rb +1 -1
- data/lib/metamorpher/matcher/matching.rb +1 -1
- data/lib/metamorpher/refactorer.rb +1 -2
- data/lib/metamorpher/rewriter/rule.rb +1 -1
- data/lib/metamorpher/terms/derived.rb +1 -1
- data/lib/metamorpher/terms/literal.rb +1 -1
- data/lib/metamorpher/terms/variable.rb +2 -2
- data/lib/metamorpher/version.rb +1 -1
- data/metamorpher.gemspec +7 -7
- data/spec/integration/ruby/builder_spec.rb +12 -12
- data/spec/integration/ruby/refactorer_spec.rb +7 -6
- data/spec/spec_helper.rb +2 -10
- data/spec/support/matchers/have_matched_matcher.rb +2 -2
- data/spec/support/matchers/have_substitution_matcher.rb +2 -2
- data/spec/support/shared_examples/shared_examples_for_greedy_variable_builders.rb +4 -4
- data/spec/support/shared_examples/shared_examples_for_variable_builders.rb +4 -4
- data/spec/unit/drivers/ruby_spec.rb +4 -4
- data/spec/unit/rewriter/traverser_spec.rb +1 -1
- data/spec/unit/visitable/visitor_spec.rb +3 -7
- metadata +19 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4d16003d62069703538fe00d09537221c30a8b50
|
4
|
+
data.tar.gz: 2be984b2778ce18e4085795895d23df4d5407f9d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2a9745cbf4788895da970497de3b8f15e28c9866b74c899e468a36a13f86bf804400be34db79e20f0ae35437fcd0487e0f4ffd032c2744bb3193050897595e32
|
7
|
+
data.tar.gz: bf3e827ea391a666826a816d4338b8bd4afbebd426f53e7977ded9bf3238f5371c41dac6e950440d066269244c5677e54fb98ae14fe664d14b82728ebbbc7753
|
data/.rubocop.yml
CHANGED
@@ -1,16 +1,19 @@
|
|
1
1
|
AllCops:
|
2
|
-
|
2
|
+
Include:
|
3
3
|
- Gemfile
|
4
4
|
- Rakefile
|
5
|
-
|
5
|
+
Exclude:
|
6
6
|
- vendor/*
|
7
7
|
- examples/refactorings/rails/where_first/sample_controller.rb
|
8
8
|
|
9
9
|
StringLiterals:
|
10
|
-
|
10
|
+
Enabled: false
|
11
11
|
|
12
12
|
LineLength:
|
13
13
|
Max: 99
|
14
14
|
|
15
15
|
Documentation:
|
16
16
|
Enabled: false
|
17
|
+
|
18
|
+
Metrics/AbcSize:
|
19
|
+
Max: 16
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.2.2
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Metamorpher [](https://travis-ci.org/mutiny/metamorpher) [](https://codeclimate.com/github/mutiny/metamorpher) [](https://gemnasium.com/mutiny/metamorpher) [](https://codeclimate.com/github/mutiny/metamorpher)
|
2
2
|
|
3
3
|
A term rewriting library for transforming (Ruby) programs.
|
4
4
|
|
@@ -506,10 +506,83 @@ end
|
|
506
506
|
|
507
507
|
#### Examples
|
508
508
|
|
509
|
+
Below are a few examples of using metamorpher to perform refactorings on Ruby code.
|
510
|
+
|
509
511
|
##### Refactor Rails where(...).first
|
510
512
|
|
513
|
+
The following refactoring can be used to slightly tidy up code that uses ActiveRecord. Specifically, it refactors expressions of the form `User.where(...).first` to expressions of the form `User.find_by(...)`.
|
514
|
+
|
515
|
+
```ruby
|
516
|
+
require "metamorpher"
|
517
|
+
|
518
|
+
class RefactorWhereFirstToFindBy
|
519
|
+
include Metamorpher::Refactorer
|
520
|
+
include Metamorpher::Builders::Ruby
|
521
|
+
|
522
|
+
def pattern
|
523
|
+
builder.build("TYPE.where(PARAMS_).first")
|
524
|
+
end
|
525
|
+
|
526
|
+
def replacement
|
527
|
+
builder.build("TYPE.find_by(PARAMS_)")
|
528
|
+
end
|
529
|
+
end
|
530
|
+
```
|
531
|
+
|
532
|
+
This example was put together following a suggestion from [Sam Saffron](https://github.com/SamSaffron) and was applied to the discourse project. Complete code for the example (which includes refactorers for the impacted RSpec tests) is [here](https://github.com/mutiny/metamorpher/tree/master/examples/refactorings/rails/where_first).
|
533
|
+
|
534
|
+
|
511
535
|
##### Refactor Rails dynamic find_by
|
512
536
|
|
537
|
+
The following refactoring can be used to switch from ActiveRecord's dynamic `find_by` method to a version that uses a hash.
|
538
|
+
|
539
|
+
```ruby
|
540
|
+
require "metamorpher"
|
541
|
+
|
542
|
+
class RefactorWhereFirstToFindBy
|
543
|
+
include Metamorpher::Refactorer
|
544
|
+
include Metamorpher::Builders::Ruby
|
545
|
+
|
546
|
+
def pattern
|
547
|
+
builder
|
548
|
+
.build("TYPE.METHOD(PARAMS_)")
|
549
|
+
.ensuring("METHOD") { |f| f.name[/^find_by_/] }
|
550
|
+
end
|
551
|
+
|
552
|
+
def replacement
|
553
|
+
builder
|
554
|
+
.build("TYPE.find_by(HASH)")
|
555
|
+
.deriving("HASH", "METHOD", "PARAMS") do |method, params|
|
556
|
+
keys = attributes_from_dynamic_finder(method.name.to_s)
|
557
|
+
values = params.map { |p| driver.unparse(p) }
|
558
|
+
builder.build(create_hash_string(keys, values))
|
559
|
+
end
|
560
|
+
end
|
561
|
+
|
562
|
+
private
|
563
|
+
|
564
|
+
# Extracts an array of attributes from the name of a dynamic
|
565
|
+
# finder, such as find_by_asset_id_and_object_path.
|
566
|
+
def attributes_from_dynamic_finder(dynamic_finder)
|
567
|
+
dynamic_finder["find_by_".length..-1].split("_and_")
|
568
|
+
end
|
569
|
+
|
570
|
+
# Builds a string representation of a hash from a set of keys
|
571
|
+
# and a corresponding set of values
|
572
|
+
def create_hash_string(keys, values)
|
573
|
+
"{" + create_pairs_string(keys, values) + "}"
|
574
|
+
end
|
575
|
+
|
576
|
+
def create_pairs_string(keys, values)
|
577
|
+
keys
|
578
|
+
.zip(values)
|
579
|
+
.map { |k, v| ":#{k} => #{v}" }
|
580
|
+
.join(",")
|
581
|
+
end
|
582
|
+
end
|
583
|
+
```
|
584
|
+
|
585
|
+
This example was put together following a suggestion from [Brian Morearty](https://github.com/bmorearty).
|
513
586
|
|
514
587
|
## Installation
|
515
588
|
|
@@ -538,4 +611,4 @@ Or install it yourself as:
|
|
538
611
|
Thank-you to the authors of other projects and resources that have inspired metamorpher, including:
|
539
612
|
|
540
613
|
* Paul Klint's [tutorial on term rewriting](http://www.meta-environment.org/doc/books/extraction-transformation/term-rewriting/term-rewriting.html), which metamorpher is heavily based on.
|
541
|
-
* Jim Weirich's [Builder](https://github.com/jimweirich/builder) gem, which heavily influenced the design of `Metamorpher::Builders::AST::Builder`.
|
614
|
+
* Jim Weirich's [Builder](https://github.com/jimweirich/builder) gem, which heavily influenced the design of `Metamorpher::Builders::AST::Builder`.
|
data/Rakefile
CHANGED
@@ -8,7 +8,7 @@ options = { overwrite: true }
|
|
8
8
|
OptionParser.new do |opts|
|
9
9
|
opts.banner = "Usage: refactorer.rb [options]"
|
10
10
|
|
11
|
-
opts.on("-d", "--dry-run", "Write changes to console, rather than to source files.") do |
|
11
|
+
opts.on("-d", "--dry-run", "Write changes to console, rather than to source files.") do |_v|
|
12
12
|
options[:overwrite] = false
|
13
13
|
end
|
14
14
|
end.parse!
|
@@ -6,16 +6,16 @@ class RefactorWhereFirstMocks
|
|
6
6
|
|
7
7
|
def pattern
|
8
8
|
builder
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
.build("TYPE.DOUBLE_METHOD(:where).returns(ARRAY_VALUE)")
|
10
|
+
.ensuring("DOUBLE_METHOD") { |m| m.name == :expects || m.name == :stubs }
|
11
|
+
.ensuring("ARRAY_VALUE") { |v| v.name == :array }
|
12
|
+
# Doesn't match non-array return types, such as Topic.stubs(:where).returns(Topic)
|
13
13
|
end
|
14
14
|
|
15
15
|
def replacement
|
16
16
|
builder
|
17
|
-
|
18
|
-
|
17
|
+
.build("TYPE.DOUBLE_METHOD(:find_by).returns(SINGLE_VALUE)")
|
18
|
+
.deriving("SINGLE_VALUE", "ARRAY_VALUE") { |array_value| take_first(array_value) }
|
19
19
|
end
|
20
20
|
|
21
21
|
private
|
data/examples/refactorings/rails/where_first/refactorers/refactor_where_first_strict_mocks.rb
CHANGED
@@ -10,8 +10,8 @@ class RefactorWhereFirstStrictMocks
|
|
10
10
|
|
11
11
|
def replacement
|
12
12
|
builder
|
13
|
-
|
14
|
-
|
13
|
+
.build("TYPE.expects(:find_by).with(PARAMS_).returns(SINGLE_VALUE)")
|
14
|
+
.deriving("SINGLE_VALUE", "ARRAY_VALUE") { |array_value| take_first(array_value) }
|
15
15
|
end
|
16
16
|
|
17
17
|
private
|
@@ -2,6 +2,7 @@ require "metamorpher/builders/ast/literal_builder"
|
|
2
2
|
require "metamorpher/builders/ast/variable_builder"
|
3
3
|
require "metamorpher/builders/ast/greedy_variable_builder"
|
4
4
|
require "metamorpher/builders/ast/derivation_builder"
|
5
|
+
require "forwardable"
|
5
6
|
|
6
7
|
module Metamorpher
|
7
8
|
module Builders
|
@@ -8,7 +8,7 @@ module Metamorpher
|
|
8
8
|
Terms::Literal.new(name: name, children: children.map { |c| termify(c) })
|
9
9
|
end
|
10
10
|
|
11
|
-
def shorthand?(method, *
|
11
|
+
def shorthand?(method, *_arguments, &_block)
|
12
12
|
!method[/\p{Upper}/]
|
13
13
|
end
|
14
14
|
|
@@ -23,7 +23,7 @@ module Metamorpher
|
|
23
23
|
private
|
24
24
|
|
25
25
|
def termify(item)
|
26
|
-
item.
|
26
|
+
item.is_a?(Terms::Term) ? item : literal!(item)
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
@@ -16,11 +16,10 @@ module Metamorpher
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def refactor_files(paths, &block)
|
19
|
-
paths.
|
19
|
+
paths.each_with_object({}) do |path, result|
|
20
20
|
changes = []
|
21
21
|
result[path] = refactor_file(path) { |change| changes << change }
|
22
22
|
block.call(path, result[path], changes) if block
|
23
|
-
result
|
24
23
|
end
|
25
24
|
end
|
26
25
|
|
data/lib/metamorpher/version.rb
CHANGED
data/metamorpher.gemspec
CHANGED
@@ -19,12 +19,12 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
21
|
spec.add_runtime_dependency "attributable", "~> 0.1.0"
|
22
|
-
spec.add_runtime_dependency "parser", "~> 2.
|
23
|
-
spec.add_runtime_dependency "unparser", "~> 0.
|
22
|
+
spec.add_runtime_dependency "parser", "~> 2.2.2"
|
23
|
+
spec.add_runtime_dependency "unparser", "~> 0.2.3"
|
24
24
|
|
25
|
-
spec.add_development_dependency "bundler", "~> 1.
|
26
|
-
spec.add_development_dependency "rake", "~> 10.
|
27
|
-
spec.add_development_dependency "rspec", "~> 2.
|
28
|
-
spec.add_development_dependency "
|
29
|
-
spec.add_development_dependency "rubocop", "~> 0.
|
25
|
+
spec.add_development_dependency "bundler", "~> 1.9.4"
|
26
|
+
spec.add_development_dependency "rake", "~> 10.4.2"
|
27
|
+
spec.add_development_dependency "rspec", "~> 3.2.0"
|
28
|
+
spec.add_development_dependency "codeclimate-test-reporter", "~> 0.4.6"
|
29
|
+
spec.add_development_dependency "rubocop", "~> 0.30.1"
|
30
30
|
end
|
@@ -72,25 +72,25 @@ describe Metamorpher.builder do
|
|
72
72
|
built = subject.build("A").ensuring("A") { |n| n > 0 }
|
73
73
|
|
74
74
|
expect(built.name).to eq(:a)
|
75
|
-
expect(built.condition.call(1)).to
|
76
|
-
expect(built.condition.call(-1)).to
|
75
|
+
expect(built.condition.call(1)).to be_truthy
|
76
|
+
expect(built.condition.call(-1)).to be_falsey
|
77
77
|
end
|
78
78
|
|
79
79
|
it "should create several conditional variables from several calls to ensuring" do
|
80
80
|
built = subject
|
81
|
-
|
82
|
-
|
83
|
-
|
81
|
+
.build("A + B")
|
82
|
+
.ensuring("A") { |n| n > 0 }
|
83
|
+
.ensuring("B") { |n| n < 0 }
|
84
84
|
|
85
85
|
first_variable, _operator, last_variable = built.children
|
86
86
|
|
87
87
|
expect(first_variable.name).to eq(:a)
|
88
|
-
expect(first_variable.condition.call(1)).to
|
89
|
-
expect(first_variable.condition.call(-1)).to
|
88
|
+
expect(first_variable.condition.call(1)).to be_truthy
|
89
|
+
expect(first_variable.condition.call(-1)).to be_falsey
|
90
90
|
|
91
91
|
expect(last_variable.name).to eq(:b)
|
92
|
-
expect(last_variable.condition.call(-1)).to
|
93
|
-
expect(last_variable.condition.call(1)).to
|
92
|
+
expect(last_variable.condition.call(-1)).to be_truthy
|
93
|
+
expect(last_variable.condition.call(1)).to be_falsey
|
94
94
|
end
|
95
95
|
end
|
96
96
|
|
@@ -112,9 +112,9 @@ describe Metamorpher.builder do
|
|
112
112
|
|
113
113
|
it "should create several derivations from several calls to deriving" do
|
114
114
|
built = subject
|
115
|
-
|
116
|
-
|
117
|
-
|
115
|
+
.build("NEW_FIRST; NEW_LAST")
|
116
|
+
.deriving("NEW_FIRST", "FIRST") {}
|
117
|
+
.deriving("NEW_LAST", "LAST") {}
|
118
118
|
|
119
119
|
first_derived, last_derived = built.children
|
120
120
|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require "metamorpher"
|
2
|
+
require "tempfile"
|
2
3
|
|
3
4
|
describe "Refactorer" do
|
4
5
|
describe "for Ruby" do
|
@@ -19,8 +20,8 @@ describe "Refactorer" do
|
|
19
20
|
|
20
21
|
let(:refactorable) do
|
21
22
|
"def run\n" \
|
22
|
-
" a = #{refactorable_code_for(
|
23
|
-
" b = #{refactorable_code_for(
|
23
|
+
" a = #{refactorable_code_for('some_predicate')}\n" \
|
24
|
+
" b = #{refactorable_code_for('some_other_predicate')}\n" \
|
24
25
|
"end"
|
25
26
|
end
|
26
27
|
|
@@ -42,7 +43,7 @@ describe "Refactorer" do
|
|
42
43
|
it "should yield for each refactoring site" do
|
43
44
|
expect { |b| subject.refactor(refactorable, &b) }.to yield_successive_args(
|
44
45
|
site_for(14..55, "some_predicate"),
|
45
|
-
site_for(63..
|
46
|
+
site_for(63..110, "some_other_predicate")
|
46
47
|
)
|
47
48
|
end
|
48
49
|
end
|
@@ -69,7 +70,7 @@ describe "Refactorer" do
|
|
69
70
|
it "should yield for each refactoring site" do
|
70
71
|
expect { |b| subject.refactor_file(refactorable_file, &b) }.to yield_successive_args(
|
71
72
|
site_for(14..55, "some_predicate"),
|
72
|
-
site_for(63..
|
73
|
+
site_for(63..110, "some_other_predicate")
|
73
74
|
)
|
74
75
|
end
|
75
76
|
end
|
@@ -133,7 +134,7 @@ describe "Refactorer" do
|
|
133
134
|
refactored,
|
134
135
|
[
|
135
136
|
site_for(14..55, "some_predicate"),
|
136
|
-
site_for(63..
|
137
|
+
site_for(63..110, "some_other_predicate")
|
137
138
|
]
|
138
139
|
]
|
139
140
|
|
@@ -142,7 +143,7 @@ describe "Refactorer" do
|
|
142
143
|
refactored,
|
143
144
|
[
|
144
145
|
site_for(14..55, "some_predicate"),
|
145
|
-
site_for(63..
|
146
|
+
site_for(63..110, "some_other_predicate")
|
146
147
|
]
|
147
148
|
]
|
148
149
|
|
data/spec/spec_helper.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require "
|
2
|
-
|
1
|
+
require "codeclimate-test-reporter"
|
2
|
+
CodeClimate::TestReporter.start
|
3
3
|
|
4
4
|
Dir["./spec/support/**/*.rb"].each { |f| require f }
|
5
5
|
|
@@ -10,7 +10,6 @@ Dir["./spec/support/**/*.rb"].each { |f| require f }
|
|
10
10
|
#
|
11
11
|
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
12
12
|
RSpec.configure do |config|
|
13
|
-
config.treat_symbols_as_metadata_keys_with_true_values = true
|
14
13
|
config.run_all_when_everything_filtered = true
|
15
14
|
config.filter_run :focus
|
16
15
|
|
@@ -19,11 +18,4 @@ RSpec.configure do |config|
|
|
19
18
|
# the seed, which is printed after each run.
|
20
19
|
# --seed 1234
|
21
20
|
config.order = "random"
|
22
|
-
|
23
|
-
config.expect_with :rspec do |c|
|
24
|
-
# Disable old "should" syntax for expressions
|
25
|
-
c.syntax = :expect
|
26
|
-
end
|
27
|
-
|
28
|
-
config.treat_symbols_as_metadata_keys_with_true_values = true # Prepare for RSpec 3
|
29
21
|
end
|
@@ -5,7 +5,7 @@ RSpec::Matchers.define :have_matched do |expected_root|
|
|
5
5
|
actual.matches? && (expected_root.nil? || actual.root == expected_root)
|
6
6
|
end
|
7
7
|
|
8
|
-
|
8
|
+
failure_message do |actual|
|
9
9
|
if actual.matches?
|
10
10
|
"expected a match against '#{expected_root.inspect}', " \
|
11
11
|
"but got a match against '#{actual.root.inspect}'"
|
@@ -14,7 +14,7 @@ RSpec::Matchers.define :have_matched do |expected_root|
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
|
17
|
+
failure_message_when_negated do |actual|
|
18
18
|
if actual.matches?
|
19
19
|
"expected no match, but got a match against #{actual.root.inspect}"
|
20
20
|
end
|
@@ -5,11 +5,11 @@ RSpec::Matchers.define :have_substitution do |expected|
|
|
5
5
|
actual.substitution == expected
|
6
6
|
end
|
7
7
|
|
8
|
-
|
8
|
+
failure_message do |actual|
|
9
9
|
"expected the substitution #{actual.substitution}, but got #{expected}"
|
10
10
|
end
|
11
11
|
|
12
|
-
|
12
|
+
failure_message_when_negated do |actual|
|
13
13
|
"expected to not receive the substitution #{actual.substitution}"
|
14
14
|
end
|
15
15
|
end
|
@@ -15,8 +15,8 @@ module Metamorpher
|
|
15
15
|
built = subject.greedy_variable!(:a) { |term| term > 0 }
|
16
16
|
|
17
17
|
expect(built.name).to eq(:a)
|
18
|
-
expect(built.condition.call(1)).to
|
19
|
-
expect(built.condition.call(-1)).to
|
18
|
+
expect(built.condition.call(1)).to be_truthy
|
19
|
+
expect(built.condition.call(-1)).to be_falsey
|
20
20
|
end
|
21
21
|
|
22
22
|
it "should not allow children" do
|
@@ -36,8 +36,8 @@ module Metamorpher
|
|
36
36
|
built = subject.A_ { |term| term > 0 }
|
37
37
|
|
38
38
|
expect(built.name).to eq(:a)
|
39
|
-
expect(built.condition.call(1)).to
|
40
|
-
expect(built.condition.call(-1)).to
|
39
|
+
expect(built.condition.call(1)).to be_truthy
|
40
|
+
expect(built.condition.call(-1)).to be_falsey
|
41
41
|
end
|
42
42
|
|
43
43
|
it "should not allow children" do
|
@@ -15,8 +15,8 @@ module Metamorpher
|
|
15
15
|
built = subject.variable!(:a) { |term| term > 0 }
|
16
16
|
|
17
17
|
expect(built.name).to eq(:a)
|
18
|
-
expect(built.condition.call(1)).to
|
19
|
-
expect(built.condition.call(-1)).to
|
18
|
+
expect(built.condition.call(1)).to be_truthy
|
19
|
+
expect(built.condition.call(-1)).to be_falsey
|
20
20
|
end
|
21
21
|
|
22
22
|
it "should not allow children" do
|
@@ -36,8 +36,8 @@ module Metamorpher
|
|
36
36
|
built = subject.A { |term| term > 0 }
|
37
37
|
|
38
38
|
expect(built.name).to eq(:a)
|
39
|
-
expect(built.condition.call(1)).to
|
40
|
-
expect(built.condition.call(-1)).to
|
39
|
+
expect(built.condition.call(1)).to be_truthy
|
40
|
+
expect(built.condition.call(-1)).to be_falsey
|
41
41
|
end
|
42
42
|
|
43
43
|
it "should not allow children" do
|
@@ -43,10 +43,10 @@ module Metamorpher
|
|
43
43
|
let(:source) { "LEFT + RIGHT" }
|
44
44
|
let(:literal) do
|
45
45
|
builder.literal!(
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
46
|
+
:send,
|
47
|
+
builder.const(nil, :LEFT),
|
48
|
+
:+,
|
49
|
+
builder.const(nil, :RIGHT)
|
50
50
|
)
|
51
51
|
end
|
52
52
|
|
@@ -4,28 +4,24 @@ module Metamorpher
|
|
4
4
|
module Visitable
|
5
5
|
describe Visitor do
|
6
6
|
it "should call visitor based on the type of the visitee" do
|
7
|
-
subject
|
8
|
-
subject.stub(visit_string: true)
|
7
|
+
allow(subject).to receive(:visit_string)
|
9
8
|
subject.visit("foo")
|
10
9
|
expect(subject).to have_received(:visit_string)
|
11
10
|
end
|
12
11
|
|
13
12
|
it "should call visitor on ancestor of visitee if necessary" do
|
14
|
-
subject
|
15
|
-
subject.stub(visit_numeric: true)
|
13
|
+
allow(subject).to receive(:visit_numeric)
|
16
14
|
subject.visit(3) # Fixnum < Integer < Numeric
|
17
15
|
expect(subject).to have_received(:visit_numeric)
|
18
16
|
end
|
19
17
|
|
20
18
|
it "should call visitor based on unqualified type of the visitee" do
|
21
|
-
subject
|
22
|
-
subject.stub(visit_dummy: true)
|
19
|
+
allow(subject).to receive(:visit_dummy)
|
23
20
|
subject.visit(Dummy.new)
|
24
21
|
expect(subject).to have_received(:visit_dummy)
|
25
22
|
end
|
26
23
|
|
27
24
|
it "should raise if no appropriate visit method is defined" do
|
28
|
-
subject = Visitor.new
|
29
25
|
expect { subject.visit("foo") }.to raise_error(ArgumentError)
|
30
26
|
end
|
31
27
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: metamorpher
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Louis Rose
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-05-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: attributable
|
@@ -30,98 +30,98 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 2.
|
33
|
+
version: 2.2.2
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 2.
|
40
|
+
version: 2.2.2
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: unparser
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 0.
|
47
|
+
version: 0.2.3
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0.
|
54
|
+
version: 0.2.3
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: bundler
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 1.9.4
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: 1.9.4
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rake
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 10.
|
75
|
+
version: 10.4.2
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 10.
|
82
|
+
version: 10.4.2
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: rspec
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 2.
|
89
|
+
version: 3.2.0
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 2.
|
96
|
+
version: 3.2.0
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
98
|
+
name: codeclimate-test-reporter
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: 0.
|
103
|
+
version: 0.4.6
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: 0.
|
110
|
+
version: 0.4.6
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: rubocop
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
115
|
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: 0.
|
117
|
+
version: 0.30.1
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version: 0.
|
124
|
+
version: 0.30.1
|
125
125
|
description: Provides structures that support program transformations, such as refactoring
|
126
126
|
or program mutation.
|
127
127
|
email:
|
@@ -133,6 +133,7 @@ files:
|
|
133
133
|
- ".gitignore"
|
134
134
|
- ".rspec"
|
135
135
|
- ".rubocop.yml"
|
136
|
+
- ".ruby-version"
|
136
137
|
- ".travis.yml"
|
137
138
|
- Gemfile
|
138
139
|
- LICENSE.txt
|
@@ -232,7 +233,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
232
233
|
version: '0'
|
233
234
|
requirements: []
|
234
235
|
rubyforge_project:
|
235
|
-
rubygems_version: 2.
|
236
|
+
rubygems_version: 2.4.5
|
236
237
|
signing_key:
|
237
238
|
specification_version: 4
|
238
239
|
summary: A term rewriting library for transforming (Ruby) programs
|