metamorpher 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +6 -3
  3. data/.ruby-version +1 -0
  4. data/.travis.yml +4 -1
  5. data/Gemfile +0 -1
  6. data/README.md +75 -2
  7. data/Rakefile +1 -1
  8. data/examples/refactorings/rails/where_first/app.rb +1 -1
  9. data/examples/refactorings/rails/where_first/refactorers/refactor_where_first_mocks.rb +6 -6
  10. data/examples/refactorings/rails/where_first/refactorers/refactor_where_first_strict_mocks.rb +2 -2
  11. data/lib/metamorpher/builders/ast/builder.rb +1 -0
  12. data/lib/metamorpher/builders/ast/greedy_variable_builder.rb +1 -1
  13. data/lib/metamorpher/builders/ast/literal_builder.rb +2 -2
  14. data/lib/metamorpher/builders/ast/variable_builder.rb +1 -1
  15. data/lib/metamorpher/matcher/matching.rb +1 -1
  16. data/lib/metamorpher/refactorer.rb +1 -2
  17. data/lib/metamorpher/rewriter/rule.rb +1 -1
  18. data/lib/metamorpher/terms/derived.rb +1 -1
  19. data/lib/metamorpher/terms/literal.rb +1 -1
  20. data/lib/metamorpher/terms/variable.rb +2 -2
  21. data/lib/metamorpher/version.rb +1 -1
  22. data/metamorpher.gemspec +7 -7
  23. data/spec/integration/ruby/builder_spec.rb +12 -12
  24. data/spec/integration/ruby/refactorer_spec.rb +7 -6
  25. data/spec/spec_helper.rb +2 -10
  26. data/spec/support/matchers/have_matched_matcher.rb +2 -2
  27. data/spec/support/matchers/have_substitution_matcher.rb +2 -2
  28. data/spec/support/shared_examples/shared_examples_for_greedy_variable_builders.rb +4 -4
  29. data/spec/support/shared_examples/shared_examples_for_variable_builders.rb +4 -4
  30. data/spec/unit/drivers/ruby_spec.rb +4 -4
  31. data/spec/unit/rewriter/traverser_spec.rb +1 -1
  32. data/spec/unit/visitable/visitor_spec.rb +3 -7
  33. metadata +19 -18
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ba3cbe5b4caa4cc89ef42987cbc19f1c8f93fa11
4
- data.tar.gz: 439e71e7d526596c23842f9affad63995455bac7
3
+ metadata.gz: 4d16003d62069703538fe00d09537221c30a8b50
4
+ data.tar.gz: 2be984b2778ce18e4085795895d23df4d5407f9d
5
5
  SHA512:
6
- metadata.gz: b10b8f2f4344c760f772f4fe11af3de5a7a1d4c8fcac847be6210eb44c42ab9dc1360c6111326cb8f40a127bda8d3c0a783f5f8683f97e223b5fedc4c461e6b7
7
- data.tar.gz: 6efc0d4e4dd097c5df447c723e855dcba610f9283d3766193799d205963f9843dc686a578b4c382124e12c68ea91f47ff56ca0d4cd0c97822ed3dca7a69521c9
6
+ metadata.gz: 2a9745cbf4788895da970497de3b8f15e28c9866b74c899e468a36a13f86bf804400be34db79e20f0ae35437fcd0487e0f4ffd032c2744bb3193050897595e32
7
+ data.tar.gz: bf3e827ea391a666826a816d4338b8bd4afbebd426f53e7977ded9bf3238f5371c41dac6e950440d066269244c5677e54fb98ae14fe664d14b82728ebbbc7753
data/.rubocop.yml CHANGED
@@ -1,16 +1,19 @@
1
1
  AllCops:
2
- Includes:
2
+ Include:
3
3
  - Gemfile
4
4
  - Rakefile
5
- Excludes:
5
+ Exclude:
6
6
  - vendor/*
7
7
  - examples/refactorings/rails/where_first/sample_controller.rb
8
8
 
9
9
  StringLiterals:
10
- EnforcedStyle: double_quotes
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
@@ -1,3 +1,6 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.1.1
3
+ - 2.2.2
4
+ addons:
5
+ code_climate:
6
+ repo_token: ccac936a51a09e2bd82f13edee996fc2376304e119df9cbb288a6a7ead7f82ce
data/Gemfile CHANGED
@@ -1,4 +1,3 @@
1
- ruby "2.1.1"
2
1
  source "https://rubygems.org"
3
2
 
4
3
  # Specify your gem's dependencies in metamorpher.gemspec
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Metamorpher [![Build Status](https://travis-ci.org/mutiny/metamorpher.png)](https://travis-ci.org/mutiny/metamorpher) [![Code Climate](https://codeclimate.com/github/mutiny/metamorpher.png)](https://codeclimate.com/github/mutiny/metamorpher) [![Dependency Status](https://gemnasium.com/mutiny/metamorpher.png)](https://gemnasium.com/mutiny/metamorpher) [![Coverage Status](https://coveralls.io/repos/mutiny/metamorpher/badge.png?branch=master)](https://coveralls.io/r/mutiny/metamorpher?branch=master)
1
+ # Metamorpher [![Build Status](https://travis-ci.org/mutiny/metamorpher.svg?branch=master)](https://travis-ci.org/mutiny/metamorpher) [![Code Climate](https://codeclimate.com/github/mutiny/metamorpher/badges/gpa.svg)](https://codeclimate.com/github/mutiny/metamorpher) [![Dependency Status](https://gemnasium.com/mutiny/metamorpher.svg)](https://gemnasium.com/mutiny/metamorpher) [![Test Coverage](https://codeclimate.com/github/mutiny/metamorpher/badges/coverage.svg)](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
@@ -17,7 +17,7 @@ namespace :style do
17
17
  require "rubocop/rake_task"
18
18
 
19
19
  desc "Run RuboCop on the lib directory"
20
- Rubocop::RakeTask.new(:check) do |task|
20
+ RuboCop::RakeTask.new(:check) do |task|
21
21
  task.options = ["--auto-correct"]
22
22
  end
23
23
  end
@@ -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 |v|
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
- .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)
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
- .build("TYPE.DOUBLE_METHOD(:find_by).returns(SINGLE_VALUE)")
18
- .deriving("SINGLE_VALUE", "ARRAY_VALUE") { |array_value| take_first(array_value) }
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
@@ -10,8 +10,8 @@ class RefactorWhereFirstStrictMocks
10
10
 
11
11
  def replacement
12
12
  builder
13
- .build("TYPE.expects(:find_by).with(PARAMS_).returns(SINGLE_VALUE)")
14
- .deriving("SINGLE_VALUE", "ARRAY_VALUE") { |array_value| take_first(array_value) }
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
@@ -12,7 +12,7 @@ module Metamorpher
12
12
  end
13
13
  end
14
14
 
15
- def shorthand?(method, *arguments, &block)
15
+ def shorthand?(method, *_arguments, &_block)
16
16
  !method[/\p{Lower}/] && method.to_s.end_with?("_")
17
17
  end
18
18
 
@@ -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, *arguments, &block)
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.kind_of?(Terms::Term) ? item : literal!(item)
26
+ item.is_a?(Terms::Term) ? item : literal!(item)
27
27
  end
28
28
  end
29
29
  end
@@ -12,7 +12,7 @@ module Metamorpher
12
12
  end
13
13
  end
14
14
 
15
- def shorthand?(method, *arguments, &block)
15
+ def shorthand?(method, *_arguments, &_block)
16
16
  !method[/\p{Lower}/] && !method.to_s.end_with?("_")
17
17
  end
18
18
 
@@ -41,7 +41,7 @@ module Metamorpher
41
41
  end
42
42
  end
43
43
 
44
- def visit_derived(derived)
44
+ def visit_derived(_derived)
45
45
  fail MatchingError, "Cannot match against a derived variable."
46
46
  end
47
47
 
@@ -16,11 +16,10 @@ module Metamorpher
16
16
  end
17
17
 
18
18
  def refactor_files(paths, &block)
19
- paths.reduce({}) do |result, path|
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
 
@@ -31,7 +31,7 @@ module Metamorpher
31
31
  traverser.traverse(ast)
32
32
  .lazy # only compute the next match when needed
33
33
  .map { |current| pattern.match(current) }
34
- .select { |result| result.matches? }
34
+ .select(&:matches?)
35
35
  end
36
36
  end
37
37
  end
@@ -6,7 +6,7 @@ module Metamorpher
6
6
  attributes :base, :derivation
7
7
 
8
8
  def inspect
9
- "[#{base.map(&:upcase).join(", ")}] -> ..."
9
+ "[#{base.map(&:upcase).join(', ')}] -> ..."
10
10
  end
11
11
  end
12
12
  end
@@ -40,7 +40,7 @@ module Metamorpher
40
40
 
41
41
  def index(child)
42
42
  children.index(child) ||
43
- fail(ArgumentError, "#{child.inspect} is not a child of #{inspect}")
43
+ fail(ArgumentError, "#{child.inspect} is not a child of #{inspect}")
44
44
  end
45
45
  end
46
46
  end
@@ -9,8 +9,8 @@ module Metamorpher
9
9
 
10
10
  def inspect
11
11
  name.to_s.upcase +
12
- (greedy? ? "+" : "") +
13
- (condition != DEFAULT_CONDITION ? "?" : "")
12
+ (greedy? ? "+" : "") +
13
+ (condition != DEFAULT_CONDITION ? "?" : "")
14
14
  end
15
15
  end
16
16
  end
@@ -1,3 +1,3 @@
1
1
  module Metamorpher
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
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.1.4"
23
- spec.add_runtime_dependency "unparser", "~> 0.1.9"
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.3"
26
- spec.add_development_dependency "rake", "~> 10.1.1"
27
- spec.add_development_dependency "rspec", "~> 2.14.1"
28
- spec.add_development_dependency "coveralls", "~> 0.7.0"
29
- spec.add_development_dependency "rubocop", "~> 0.19.1"
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 be_true
76
- expect(built.condition.call(-1)).to be_false
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
- .build("A + B")
82
- .ensuring("A") { |n| n > 0 }
83
- .ensuring("B") { |n| n < 0 }
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 be_true
89
- expect(first_variable.condition.call(-1)).to be_false
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 be_true
93
- expect(last_variable.condition.call(1)).to be_false
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
- .build("NEW_FIRST; NEW_LAST")
116
- .deriving("NEW_FIRST", "FIRST") {}
117
- .deriving("NEW_LAST", "LAST") {}
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("some_predicate")}\n" \
23
- " b = #{refactorable_code_for("some_other_predicate")}\n" \
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.. 110, "some_other_predicate")
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.. 110, "some_other_predicate")
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.. 110, "some_other_predicate")
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.. 110, "some_other_predicate")
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 "coveralls"
2
- Coveralls.wear!
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
- failure_message_for_should do |actual|
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
- failure_message_for_should_not do |actual|
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
- failure_message_for_should do |actual|
8
+ failure_message do |actual|
9
9
  "expected the substitution #{actual.substitution}, but got #{expected}"
10
10
  end
11
11
 
12
- failure_message_for_should_not do |actual|
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 be_true
19
- expect(built.condition.call(-1)).to be_false
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 be_true
40
- expect(built.condition.call(-1)).to be_false
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 be_true
19
- expect(built.condition.call(-1)).to be_false
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 be_true
40
- expect(built.condition.call(-1)).to be_false
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
- :send,
47
- builder.const(nil, :LEFT),
48
- :+,
49
- builder.const(nil, :RIGHT)
46
+ :send,
47
+ builder.const(nil, :LEFT),
48
+ :+,
49
+ builder.const(nil, :RIGHT)
50
50
  )
51
51
  end
52
52
 
@@ -45,7 +45,7 @@ module Metamorpher
45
45
  Tree.new(children)
46
46
  end
47
47
 
48
- class Tree < Struct.new(:children); end
48
+ Tree = Struct.new(:children)
49
49
  end
50
50
  end
51
51
  end
@@ -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 = Visitor.new
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 = Visitor.new
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 = Visitor.new
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.0
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: 2014-05-06 00:00:00.000000000 Z
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.1.4
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.1.4
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.1.9
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.1.9
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: '1.3'
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: '1.3'
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.1.1
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.1.1
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.14.1
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.14.1
96
+ version: 3.2.0
97
97
  - !ruby/object:Gem::Dependency
98
- name: coveralls
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.7.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.7.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.19.1
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.19.1
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.2.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