suture 1.1.1 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -0
  3. data/.standard.yml +7 -0
  4. data/.travis.yml +6 -4
  5. data/CHANGELOG.md +11 -0
  6. data/Gemfile +1 -1
  7. data/README.md +36 -23
  8. data/Rakefile +10 -11
  9. data/lib/suture.rb +0 -1
  10. data/lib/suture/adapter/dictaphone.rb +1 -2
  11. data/lib/suture/comparator.rb +5 -5
  12. data/lib/suture/config.rb +1 -1
  13. data/lib/suture/create/builds_plan.rb +1 -1
  14. data/lib/suture/create/chooses_surgeon.rb +1 -1
  15. data/lib/suture/create/validates_plan.rb +15 -15
  16. data/lib/suture/error/invalid_plan.rb +5 -5
  17. data/lib/suture/error/observation_conflict.rb +1 -1
  18. data/lib/suture/error/result_mismatch.rb +1 -1
  19. data/lib/suture/error/verification_failed.rb +14 -16
  20. data/lib/suture/reset.rb +0 -1
  21. data/lib/suture/surgeon/auditor.rb +5 -7
  22. data/lib/suture/surgeon/no_op.rb +1 -1
  23. data/lib/suture/surgeon/observer.rb +2 -3
  24. data/lib/suture/surgeon/remediator.rb +6 -8
  25. data/lib/suture/util/compares_results.rb +1 -1
  26. data/lib/suture/util/env.rb +4 -4
  27. data/lib/suture/util/scalpel.rb +5 -6
  28. data/lib/suture/util/shuffle.rb +1 -1
  29. data/lib/suture/value/observation.rb +1 -1
  30. data/lib/suture/value/plan.rb +4 -4
  31. data/lib/suture/value/result.rb +2 -2
  32. data/lib/suture/value/test_plan.rb +12 -12
  33. data/lib/suture/value/test_results.rb +0 -1
  34. data/lib/suture/verify.rb +0 -1
  35. data/lib/suture/verify/administers_test.rb +4 -4
  36. data/lib/suture/verify/interprets_results.rb +0 -2
  37. data/lib/suture/verify/prescribes_test_plan.rb +1 -1
  38. data/lib/suture/verify/tests_patient.rb +4 -5
  39. data/lib/suture/version.rb +1 -1
  40. data/lib/suture/wrap/logger.rb +35 -15
  41. data/lib/suture/wrap/sqlite.rb +1 -1
  42. data/suture.gemspec +10 -5
  43. metadata +18 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: f33e4939ed0c1027f6785cc54be152ea672ebdb4
4
- data.tar.gz: bec9bab57ef345f7095cabf4ece4c84e242b79e1
2
+ SHA256:
3
+ metadata.gz: 163a4b24e5b0e5a27e41455d0fab014c19e96d9e7abe9b5ebf35d984094fdb95
4
+ data.tar.gz: 6f5f28071fd9f3cb298fd16f7fe5ddf7b66e57941792b6e0142daeffb2965677
5
5
  SHA512:
6
- metadata.gz: 6ddae427868b0b514a8d4b6c3b413f0185c15321e5cfd0acea5ed044a60d78c5232dba4b4cbb3219b33abca7bfad9350a85aff05849f97dc8f1215d341b650f1
7
- data.tar.gz: 15ef4a1b3af52821d69f1c3aa6997b123bcbcdc0570ce6296cf420caf7437f64083a4442bc278427ccb302fb806705faba8acf2ca0c531cac20450fbaf3c2fb7
6
+ metadata.gz: e8d2bef6ec660786f4b3da2722c0e95b722e7f456ce4347da9e6e36627eff99446c5280d708a2c2b639d1543dfd1ddaa0ebb7c4a0cf7a101e9295eaef49063c7
7
+ data.tar.gz: dd00faab3aca2bff8fe346170d0a31d2e80ecaf0a08ee7b2794900f25ef7a48b4db542b8a0c38e4fda21ad3c052d5638d555560a971d8a48149617a38349b172
data/.gitignore CHANGED
@@ -1,5 +1,6 @@
1
1
  /.bundle/
2
2
  /.yardoc
3
+ /Dockerfile
3
4
  /Gemfile.lock
4
5
  /_yardoc/
5
6
  /coverage/
@@ -0,0 +1,7 @@
1
+ ruby_version: 1.8.7
2
+
3
+ ignore:
4
+ - "{safe,test}/**/*":
5
+ - Style/Semicolon
6
+ - "safe/fixtures/gilded_rose.rb"
7
+ - "example/rails_app/app/**/*"
@@ -1,15 +1,17 @@
1
1
  language: ruby
2
2
  sudo: false
3
- before_install:
4
- - gem install bundler
5
- - cd example/rails_app && ./script/setup.sh && cd ../..
6
3
  rvm:
7
4
  - 1.8.7
8
5
  - 1.9
9
6
  - 2.0
10
7
  - 2.1
11
8
  - 2.2
12
- - 2.3.1
9
+ - 2.3.3
10
+ before_install:
11
+ - gem install bundler
12
+ - cd example/rails_app && ./script/setup.sh && cd ../..
13
+ after_success:
14
+ - bundle exec codeclimate-test-reporter
13
15
  addons:
14
16
  code_climate:
15
17
  repo_token: 05e3e31164d59aa626b730b92eb9b7418326dbf23420a4b87eab2555840b39ef
@@ -1,5 +1,16 @@
1
1
  # Change Log
2
2
 
3
+ ## [v1.1.1](https://github.com/testdouble/suture/tree/v1.1.1) (2016-09-19)
4
+ [Full Changelog](https://github.com/testdouble/suture/compare/v1.1.0...v1.1.1)
5
+
6
+ **Closed issues:**
7
+
8
+ - call\_both: if raise\_on\_result\_mismatch is false and return\_old\_on\_result\_mismatch is true, rescue errors from :new path [\#64](https://github.com/testdouble/suture/issues/64)
9
+
10
+ **Merged pull requests:**
11
+
12
+ - Allow graceful fallback by call\_both when new code path raises [\#65](https://github.com/testdouble/suture/pull/65) ([searls](https://github.com/searls))
13
+
3
14
  ## [v1.1.0](https://github.com/testdouble/suture/tree/v1.1.0) (2016-09-18)
4
15
  [Full Changelog](https://github.com/testdouble/suture/compare/v1.0.0...v1.1.0)
5
16
 
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in suture.gemspec
4
4
  gemspec
data/README.md CHANGED
@@ -9,11 +9,21 @@ Suture hopes to make it safer to completely reimplement a code path.
9
9
  Suture provides help to the entire lifecycle of refactoring poorly-understood
10
10
  code, from local development, to a staging environment, and even in production.
11
11
 
12
+ # Video
13
+
14
+ Suture was unveiled at Ruby Kaigi 2016 as a one approach that we can make
15
+ refactors less scary and more predictable. You can watch the 45 minute screencast
16
+ here:
17
+
18
+ [<img width="803" alt="screen shot 2016-09-20 at 9 44 43 am" src="https://cloud.githubusercontent.com/assets/79303/18653743/e669d304-7f16-11e6-84e7-c86b8f88132c.png" alt="A presentation on Suture">](http://blog.testdouble.com/posts/2016-09-16-surgical-refactors-with-suture.html)
19
+
20
+ # Walk-through guide
21
+
12
22
  Refactoring or reimplementing important code is an involved process! Instead of
13
23
  listing out Suture's API without sufficient exposition, here is an example that
14
24
  we'll take you through each stage of the lifecycle.
15
25
 
16
- ## development
26
+ ## Development
17
27
 
18
28
  Suppose you have a really nasty worker method:
19
29
 
@@ -58,9 +68,12 @@ class LegacyWorker
58
68
  end
59
69
  ```
60
70
 
61
- As you can see, the call to `MyMailer.send` is left at the original call site,
62
- since its effectively a void method being invoked for its side effect, and its
63
- much easier to verify return values.
71
+ As you can see, the call to `MyMailer.send` is left at the original call site.
72
+ `MyMailer.send` is effectively a void method being invoked for its side effect,
73
+ which would make it difficult to test. By creating `LegacyWorker#call`, we can
74
+ now express the work more clearly in terms of repeatable inputs (`id`) and
75
+ outputs (`thing.result`), which will help us verify that our refactor is working
76
+ later.
64
77
 
65
78
  Since any changes to the code while it's untested are very dangerous, it's
66
79
  important to minimize changes made for the sake of creating a clear seam.
@@ -89,10 +102,10 @@ LegacyWorker without taking any other meaningful action.
89
102
 
90
103
  ### 3. Record the current behavior
91
104
 
92
- Next, we want to start observing how the legacy worker is actually called: what
93
- arguments are sent to it and what values does it return? By recording the calls
94
- as we use our app locally, we can later test that the old and new
95
- implementations behave the same way.
105
+ Next, we want to start observing how the legacy worker is actually called. What
106
+ arguments are being sent to it and what value does it returns (or, what error
107
+ does it raise)? By recording the calls as we use our app locally, we can later
108
+ test that the old and new implementations behave the same way.
96
109
 
97
110
  First, we tell Suture to start recording calls by setting the environment
98
111
  variable `SUTURE_RECORD_CALLS` to something truthy (e.g.
@@ -101,8 +114,8 @@ any calls to our seam will record the arguments passed to the legacy code path
101
114
  and the return value.
102
115
 
103
116
  As you use the application (whether it's a queue system, a web app, or a CLI),
104
- the calls will be saved to a sqlite database. If the legacy code path relies on
105
- external data sources or services, keep in mind that your recorded inputs and
117
+ the calls will be saved to a sqlite database. Keep in mind that if the legacy code
118
+ path relies on external data sources or services, your recorded inputs and
106
119
  outputs will rely on them as well. You may want to narrow the scope of your
107
120
  seam accordingly (e.g. to receive an object as an argument instead of a database
108
121
  id).
@@ -146,7 +159,7 @@ expected value. It's a good idea to run this against the legacy code first,
146
159
  for two reasons:
147
160
 
148
161
  * running the characterization tests against the legacy code path will ensure
149
- the test environment has the data needed to behave the same way as when it was
162
+ that the test environment has the data needed to behave the same way as when it was
150
163
  recorded (it may be appropriate to take a snapshot of the database before you
151
164
  start recording and load it before you run your tests)
152
165
 
@@ -158,13 +171,13 @@ start recording and load it before you run your tests)
158
171
  subordinate to it) to make sure our characterization test sufficiently
159
172
  exercises it
160
173
  * identify incidental coverage of code paths that are outside the scope of
161
- what we hope to refactor, and in turn analyzing whether `LegacyWorker` has
174
+ what we hope to refactor. This will help to see if `LegacyWorker` has
162
175
  side effects we didn't anticipate and should additionally write tests for
163
176
 
164
177
  ### 5. Specify and test a path for new code
165
178
 
166
- Once our automated characterization test of our recordings is passing, then we
167
- can start work on a `NewWorker`. To get started, we can update our Suture
179
+ Once the automated characterization test of our recordings is passing, then we
180
+ can start work on a `NewWorker`. To get started, we update our Suture
168
181
  configuration:
169
182
 
170
183
  ``` ruby
@@ -214,7 +227,7 @@ end
214
227
  ```
215
228
 
216
229
  Obviously, this should fail until `NewWorker`'s implementation covers all the
217
- cases we recorded from `LegacyWorker`.
230
+ cases that we recorded from `LegacyWorker`.
218
231
 
219
232
  Remember, characterization tests aren't designed to be kept around forever. Once
220
233
  you're confident that the new implementation is sufficient, it's typically better
@@ -225,21 +238,21 @@ implementation and its component parts.
225
238
 
226
239
  This step is the hardest part and there's not much Suture can do to make it
227
240
  any easier. How you go about implementing your improvements depends on whether
228
- you intend to rewrite the legacy code path or refactor it. Some comment on each
229
- approach follows:
241
+ you intend to rewrite the legacy code path or refactor it. Some comments on each
242
+ approach follow:
230
243
 
231
244
  #### Reimplementing
232
245
 
233
246
  The best time to rewrite a piece of software is when you have a better
234
- understanding of the real-world process it models than the original authors did
247
+ understanding of the real-world process that it models than the original authors did
235
248
  when they first wrote it. If that's the case, it's likely you'll think of more
236
249
  reliable names and abstractions than they did.
237
250
 
238
251
  As for workflow, consider writing the new implementation like you would any other
239
- new part of the system, with the added benefit of being able to run the
252
+ new part of the system. The added benefit is being able to run the
240
253
  characterization tests as a progress indicator and a backstop for any missed edge
241
254
  cases. The ultimate goal of this workflow should be to incrementally arrive at a
242
- clean design that completely passes the characterization test run by
255
+ clean design that completely passes the characterization test run by running
243
256
  `Suture.verify`.
244
257
 
245
258
  #### Refactoring
@@ -323,7 +336,7 @@ Suture.config({
323
336
  ```
324
337
 
325
338
  When your new code path raises an error with the above settings, it will
326
- propogate and log the error to the specified file.
339
+ propagate and log the error to the specified file.
327
340
 
328
341
  ### Custom error handlers
329
342
 
@@ -478,7 +491,7 @@ certain cases, setting `:expected_error_types => [WidgetError]` will result in:
478
491
  `kind_of?` any recorded error type (regardless of whether `Suture.verify` is
479
492
  passed a redundant list of `expected_error_types`)
480
493
  * `Suture.create`, when `fallback_on_error` is enabled, will allow expected
481
- errors raised by the `new` path to propogate, as opposed to logging &
494
+ errors raised by the `new` path to propagate, as opposed to logging &
482
495
  rescuing them before calling the `old` path as a fallback
483
496
 
484
497
  * _disable_ - (Default: `false`) - when enabled, Suture will attempt to revert to
@@ -641,7 +654,7 @@ detects two ActiveRecord model instances being compared, it will behave
641
654
  differently, by this logic:
642
655
 
643
656
  1. Instead of comparing the objects with `==` (which returns true so long as the
644
- `id` attribute matdhes), Suture will compare the objects' `attributes` hashes
657
+ `id` attribute matches), Suture will compare the objects' `attributes` hashes
645
658
  instead
646
659
  2. The built-in `updated_at` and `created_at` will typically differ when code
647
660
  is executed at different times and are usually not meaningful to application
data/Rakefile CHANGED
@@ -4,13 +4,13 @@ require "rake/testtask"
4
4
  Rake::TestTask.new(:unit) do |t|
5
5
  t.libs << "test"
6
6
  t.libs << "lib"
7
- t.test_files = FileList['test/helper.rb', 'test/**/*_test.rb']
7
+ t.test_files = FileList["test/helper.rb", "test/**/*_test.rb"]
8
8
  end
9
9
 
10
10
  Rake::TestTask.new(:safe) do |t|
11
11
  t.libs << "safe"
12
12
  t.libs << "lib"
13
- t.test_files = FileList['safe/helper.rb', 'safe/**/*_test.rb']
13
+ t.test_files = FileList["safe/helper.rb", "safe/**/*_test.rb"]
14
14
  end
15
15
 
16
16
  Rake::TestTask.new(:test) do |t|
@@ -18,11 +18,11 @@ Rake::TestTask.new(:test) do |t|
18
18
  t.libs << "safe"
19
19
  t.libs << "lib"
20
20
  t.test_files = FileList[
21
- 'safe/support/code_climate',
22
- 'test/helper.rb',
23
- 'test/**/*_test.rb',
24
- 'safe/helper.rb',
25
- 'safe/**/*_test.rb'
21
+ "safe/support/code_climate",
22
+ "test/helper.rb",
23
+ "test/**/*_test.rb",
24
+ "safe/helper.rb",
25
+ "safe/**/*_test.rb"
26
26
  ]
27
27
  end
28
28
 
@@ -32,14 +32,14 @@ task :example do
32
32
  BUNDLE_GEMFILE="$PWD/Gemfile" bundle install --quiet
33
33
  BUNDLE_GEMFILE="$PWD/Gemfile" bundle exec rake suture
34
34
  SH
35
- if !passed
36
- raise StandardError.new("Rails example failed!")
35
+ unless passed
36
+ raise StandardError, "Rails example failed!"
37
37
  end
38
38
  end
39
39
  end
40
40
 
41
41
  if Gem.ruby_version >= Gem::Version.new("2.2.2")
42
- require 'github_changelog_generator/task'
42
+ require "github_changelog_generator/task"
43
43
  GitHubChangelogGenerator::RakeTask.new :changelog
44
44
  task :changelog_commit do
45
45
  require "suture"
@@ -50,5 +50,4 @@ if Gem.ruby_version >= Gem::Version.new("2.2.2")
50
50
  Rake::Task["release:rubygem_push"].enhance([:changelog, :changelog_commit])
51
51
  end
52
52
 
53
-
54
53
  task :default => [:test, :example]
@@ -5,4 +5,3 @@ require "suture/verify"
5
5
  require "suture/delete"
6
6
  require "suture/config"
7
7
  require "suture/reset"
8
-
@@ -19,7 +19,6 @@ module Suture::Adapter
19
19
  end
20
20
  end
21
21
 
22
-
23
22
  def record(returned_value)
24
23
  record_result(Suture::Value::Result.returned(returned_value))
25
24
  end
@@ -48,7 +47,7 @@ module Suture::Adapter
48
47
  Suture::Wrap::Sqlite.delete(@db, :observations, "where name = ?", [name.to_s])
49
48
  end
50
49
 
51
- private
50
+ private
52
51
 
53
52
  def record_result(result)
54
53
  Suture::Wrap::Sqlite.insert(
@@ -7,7 +7,7 @@ module Suture
7
7
  :active_record_excluded_attributes => (
8
8
  options[:active_record_excluded_attributes] ||
9
9
  DEFAULT_ACTIVE_RECORD_EXCLUDED_ATTRIBUTES
10
- ).map(&:to_s)
10
+ ).map(&:to_s),
11
11
  }
12
12
  end
13
13
 
@@ -23,7 +23,7 @@ module Suture
23
23
  protected
24
24
 
25
25
  def compare_active_record(recorded, actual)
26
- actual.kind_of?(recorded.class) &&
26
+ actual.is_a?(recorded.class) &&
27
27
  without_excluded_attrs(recorded.attributes) ==
28
28
  without_excluded_attrs(actual.attributes)
29
29
  end
@@ -31,7 +31,7 @@ module Suture
31
31
  private
32
32
 
33
33
  def without_excluded_attrs(hash)
34
- hash.reject do |k, v|
34
+ hash.reject do |k, _v|
35
35
  @options[:active_record_excluded_attributes].include?(k.to_s)
36
36
  end
37
37
  end
@@ -46,8 +46,8 @@ module Suture
46
46
 
47
47
  def is_active_record?(recorded, actual)
48
48
  defined?(ActiveRecord::Base) &&
49
- recorded.kind_of?(ActiveRecord::Base) &&
50
- actual.kind_of?(ActiveRecord::Base)
49
+ recorded.is_a?(ActiveRecord::Base) &&
50
+ actual.is_a?(ActiveRecord::Base)
51
51
  end
52
52
  end
53
53
  end
@@ -8,7 +8,7 @@ module Suture
8
8
  :log_stdout => true,
9
9
  :log_io => nil,
10
10
  :log_file => nil,
11
- :raise_on_result_mismatch => true
11
+ :raise_on_result_mismatch => true,
12
12
  }
13
13
 
14
14
  def self.config(config = {})
@@ -5,7 +5,7 @@ module Suture
5
5
  class BuildsPlan
6
6
  UN_ENV_IABLE_OPTIONS = [:name, :old, :new, :args, :comparator, :after_new,
7
7
  :after_old, :on_new_error, :on_old_error,
8
- :expected_error_types]
8
+ :expected_error_types,]
9
9
 
10
10
  def build(name, options = {})
11
11
  Value::Plan.new(
@@ -12,7 +12,7 @@ module Suture
12
12
  return Surgeon::NoOp.new if plan.disable
13
13
  if plan.record_calls
14
14
  if plan.new
15
- log_warn <<-MSG.gsub(/^ {12}/,'')
15
+ log_warn <<-MSG.gsub(/^ {12}/, "")
16
16
  Seam #{plan.name.inspect} has a :new code path defined, but because
17
17
  it is set to :record_calls, we will invoke the :old code path
18
18
  instead. If this is not what you intend, set :record_calls to false.
@@ -5,28 +5,28 @@ module Suture
5
5
  REQUIREMENTS = {
6
6
  :name => "in order to identify recorded calls",
7
7
  :old => "in order to call the legacy code path (must respond to `:call`)",
8
- :args => "in order to differentiate recorded calls (if the code you're changing doesn't take arguments, you can set :args to `[]` but should probably consider creating a seam inside of it which can--consult the README for more advice)"
8
+ :args => "in order to differentiate recorded calls (if the code you're changing doesn't take arguments, you can set :args to `[]` but should probably consider creating a seam inside of it which can--consult the README for more advice)",
9
9
  }
10
10
 
11
11
  VALIDATIONS = {
12
12
  :name => {
13
13
  :test => lambda { |name| name.to_s.size < 256 },
14
- :message => "must be less than 256 characters"
14
+ :message => "must be less than 256 characters",
15
15
  },
16
- :old => CALLABLE_VALIDATION = ({
16
+ :old => CALLABLE_VALIDATION = {
17
17
  :test => lambda { |old| old.respond_to?(:call) },
18
- :message => "must respond to `call` (e.g. `dog.method(:bark)` or `->(*args){ dog.bark(*args) }`)"
19
- }),
18
+ :message => "must respond to `call` (e.g. `dog.method(:bark)` or `->(*args){ dog.bark(*args) }`)",
19
+ },
20
20
  :new => CALLABLE_VALIDATION,
21
21
  :comparator => CALLABLE_VALIDATION.merge(
22
22
  :message => "must respond to `call` (e.g. `MyComparator.new` or `->(recorded, actual) { recorded == actual }`)"
23
- )
23
+ ),
24
24
  }
25
25
 
26
26
  CONFLICTS = [
27
27
  lambda { |plan|
28
28
  if plan.record_calls && !plan.database_path
29
- <<-MSG.gsub(/^ {12}/,'')
29
+ <<-MSG.gsub(/^ {12}/, "")
30
30
  :record_calls is enabled, but :database_path is nil, so Suture
31
31
  doesn't know where to record calls to the seam.
32
32
  MSG
@@ -34,7 +34,7 @@ module Suture
34
34
  },
35
35
  lambda { |plan|
36
36
  if plan.record_calls && plan.call_both
37
- <<-MSG.gsub(/^ {12}/,'')
37
+ <<-MSG.gsub(/^ {12}/, "")
38
38
  :record_calls & :call_both are both enabled and conflict with one
39
39
  another. :record_calls will only invoke the old code path (intended
40
40
  for characterization of the old code path and initial development
@@ -51,7 +51,7 @@ module Suture
51
51
  },
52
52
  lambda { |plan|
53
53
  if plan.record_calls && plan.fallback_on_error
54
- <<-MSG.gsub(/^ {12}/,'')
54
+ <<-MSG.gsub(/^ {12}/, "")
55
55
  :record_calls & :fallback_on_error are both enabled and conflict with
56
56
  one another. :record_calls will only invoke the old code path
57
57
  (intended for characterization of the old code path and initial
@@ -63,7 +63,7 @@ module Suture
63
63
  },
64
64
  lambda { |plan|
65
65
  if plan.call_both && plan.fallback_on_error
66
- <<-MSG.gsub(/^ {12}/,'')
66
+ <<-MSG.gsub(/^ {12}/, "")
67
67
  :call_both & :fallback_on_error are both enabled and conflict with
68
68
  one another. :call_both is designed for pre-production environments
69
69
  and will call both the old and new code paths to compare their
@@ -75,7 +75,7 @@ module Suture
75
75
  },
76
76
  lambda { |plan|
77
77
  if plan.call_both && !plan.new.respond_to?(:call)
78
- <<-MSG.gsub(/^ {12}/,'')
78
+ <<-MSG.gsub(/^ {12}/, "")
79
79
  :call_both is set but :new is either not set or is not callable. In
80
80
  order to call both code paths, both :old and :new must be set and
81
81
  callable
@@ -84,7 +84,7 @@ module Suture
84
84
  },
85
85
  lambda { |plan|
86
86
  if plan.fallback_on_error && !plan.new.respond_to?(:call)
87
- <<-MSG.gsub(/^ {12}/,'')
87
+ <<-MSG.gsub(/^ {12}/, "")
88
88
  :fallback_on_error is set but :new is either not set or is not
89
89
  callable. This mode is designed for after the :new code path has
90
90
  been developed and run in production-like environments, where :old
@@ -96,13 +96,13 @@ module Suture
96
96
  },
97
97
  lambda { |plan|
98
98
  if !plan.raise_on_result_mismatch && !plan.call_both
99
- <<-MSG.gsub(/^ {12}/,'')
99
+ <<-MSG.gsub(/^ {12}/, "")
100
100
  :raise_on_result_mismatch was disabled but :call_both is not enabled.
101
101
  This option only applies to the :call_both mode, and will have no
102
102
  impact when set for other modes
103
103
  MSG
104
104
  end
105
- }
105
+ },
106
106
  ]
107
107
 
108
108
  def validate(plan)
@@ -125,7 +125,7 @@ module Suture
125
125
 
126
126
  def invalid_attrs(plan)
127
127
  VALIDATIONS.select { |name, rule|
128
- next unless attr = plan.send(name)
128
+ next unless (attr = plan.send(name))
129
129
  !rule[:test].call(attr)
130
130
  }
131
131
  end
@@ -3,31 +3,31 @@ module Suture::Error
3
3
  HEADER = "Suture was unable to create your seam, because options passed to `Suture.create` were invalid."
4
4
 
5
5
  def self.missing_requirements(requirements)
6
- new <<-MSG.gsub(/^ {8}/,'')
6
+ new <<-MSG.gsub(/^ {8}/, "")
7
7
  #{HEADER}
8
8
 
9
9
  The following options are required:
10
10
 
11
- #{requirements.map {|(name,explanation)|
11
+ #{requirements.map {|(name, explanation)|
12
12
  "* #{name.inspect} - #{explanation}"
13
13
  }.join("\n ")}
14
14
  MSG
15
15
  end
16
16
 
17
17
  def self.invalid_options(invalids)
18
- new <<-MSG.gsub(/^ {8}/,'')
18
+ new <<-MSG.gsub(/^ {8}/, "")
19
19
  #{HEADER}
20
20
 
21
21
  The following options were invalid:
22
22
 
23
- #{invalids.map {|(name,rule)|
23
+ #{invalids.map {|(name, rule)|
24
24
  "* #{name.inspect} - #{rule[:message]}"
25
25
  }.join("\n ")}
26
26
  MSG
27
27
  end
28
28
 
29
29
  def self.conflicting_options(conflicts)
30
- new <<-MSG.gsub(/^ {8}/,'')
30
+ new <<-MSG.gsub(/^ {8}/, "")
31
31
  #{HEADER}
32
32
 
33
33
  Suture isn't sure how to best handle the combination of options passed:
@@ -9,7 +9,7 @@ module Suture::Error
9
9
  end
10
10
 
11
11
  def message
12
- <<-MSG.gsub(/^ {8}/,'')
12
+ <<-MSG.gsub(/^ {8}/, "")
13
13
  At seam #{@name.inspect}, we just recorded a duplicate call, but the same arguments
14
14
  resulted in a different output. Read on for details:
15
15
 
@@ -7,7 +7,7 @@ module Suture::Error
7
7
  end
8
8
 
9
9
  def message
10
- <<-MSG.gsub(/^ {8}/,'')
10
+ <<-MSG.gsub(/^ {8}/, "")
11
11
  The results from the old & new code paths did not match for the seam
12
12
  #{@plan.name.inspect} and Suture is raising this error because the `:call_both`
13
13
  option is enabled, because both code paths are expected to return the
@@ -14,7 +14,7 @@ module Suture::Error
14
14
  describe_failures(@results.failed, @plan),
15
15
  configuration(@plan),
16
16
  summarize(@results),
17
- progress(@plan, @results)
17
+ progress(@plan, @results),
18
18
  ].compact.join("\n").tap do
19
19
  end
20
20
  end
@@ -22,7 +22,7 @@ module Suture::Error
22
22
  private
23
23
 
24
24
  def intro
25
- <<-MSG.gsub(/^ {8}/,'')
25
+ <<-MSG.gsub(/^ {8}/, "")
26
26
 
27
27
  # Verification of your seam failed!
28
28
 
@@ -31,7 +31,7 @@ module Suture::Error
31
31
  end
32
32
 
33
33
  def summarize(results)
34
- <<-MSG.gsub(/^ {8}/,'')
34
+ <<-MSG.gsub(/^ {8}/, "")
35
35
  # Result Summary
36
36
 
37
37
  - Passed........#{results.passed_count}
@@ -49,7 +49,7 @@ module Suture::Error
49
49
  results.all.size
50
50
  )
51
51
  percent = Suture::Util::Numbers.percent(results.passed.size, results.all.size)
52
- <<-MSG.gsub(/^ {8}/,'')
52
+ <<-MSG.gsub(/^ {8}/, "")
53
53
  ## Progress
54
54
 
55
55
  Here's what your progress to initial completion looks like so far:
@@ -61,7 +61,7 @@ module Suture::Error
61
61
  end
62
62
 
63
63
  def configuration(plan)
64
- <<-MSG.gsub(/^ {8}/,'')
64
+ <<-MSG.gsub(/^ {8}/, "")
65
65
  # Configuration
66
66
 
67
67
  This is the configuration used by this test run:
@@ -81,7 +81,7 @@ module Suture::Error
81
81
  end
82
82
 
83
83
  def describe_comparator(comparator)
84
- if comparator.kind_of?(Proc)
84
+ if comparator.is_a?(Proc)
85
85
  "Proc # (in: `#{describe_source_location(*comparator.source_location)}`)"
86
86
  elsif comparator.respond_to?(:method) && comparator.method(:call)
87
87
  "#{comparator.inspect}.new, # (in: `#{describe_source_location(*comparator.method(:call).source_location)}`)"
@@ -90,7 +90,7 @@ module Suture::Error
90
90
 
91
91
  def describe_source_location(file, line)
92
92
  root = File.join(Dir.getwd, "/")
93
- path = file.start_with?(root) ? file.gsub(root, '') : file
93
+ path = file.start_with?(root) ? file.gsub(root, "") : file
94
94
  "#{path}:#{line}"
95
95
  end
96
96
 
@@ -102,13 +102,13 @@ module Suture::Error
102
102
  describe_failure(failure, index) if plan.error_message_limit.nil? || index < plan.error_message_limit
103
103
  },
104
104
  describe_squelched_failure_messages(failures.size, plan.error_message_limit),
105
- describe_general_failure_advice(plan)
105
+ describe_general_failure_advice(plan),
106
106
  ].flatten.compact.join("\n")
107
107
  end
108
108
 
109
109
  def describe_failure(failure, index)
110
110
  expected = failure[:observation]
111
- return <<-MSG.gsub(/^ {8}/,'')
111
+ <<-MSG.gsub(/^ {8}/, "")
112
112
  #{index + 1}.) Recorded call for seam #{expected.name.inspect} (ID: #{expected.id}) ran and #{failure[:error] ? "raised an error" : "failed comparison"}.
113
113
 
114
114
  Arguments: ```
@@ -117,13 +117,12 @@ module Suture::Error
117
117
  Expected #{expected.result.errored? ? "error raised" : "returned value"}: ```
118
118
  #{expected.result.value.inspect}
119
119
  ```
120
- Actual #{(failure[:error] || failure[:new_result].errored?) ? "error raised" : "returned value"}: ```
120
+ Actual #{failure[:error] || failure[:new_result].errored? ? "error raised" : "returned value"}: ```
121
121
  #{if failure[:error]
122
122
  stringify_error(failure[:error])
123
123
  else
124
124
  failure[:new_result].value.inspect
125
- end
126
- }
125
+ end}
127
126
  ```
128
127
 
129
128
  Ideas to fix this:
@@ -138,7 +137,7 @@ module Suture::Error
138
137
  end
139
138
 
140
139
  def describe_general_failure_advice(plan)
141
- <<-MSG.gsub(/^ {8}/,'')
140
+ <<-MSG.gsub(/^ {8}/, "")
142
141
  ### Fixing these failures
143
142
 
144
143
  #### Custom comparator
@@ -156,7 +155,7 @@ module Suture::Error
156
155
  behavior somewhere in your subject's code.
157
156
 
158
157
  #{if !plan.random_seed.nil?
159
- <<-MOAR.gsub(/^ {14}/,'')
158
+ <<-MOAR.gsub(/^ {14}/, "")
160
159
  To re-run the tests with the same random seed as was used in this run,
161
160
  set the env var `SUTURE_RANDOM_SEED=#{plan.random_seed}` or the config entry
162
161
  `:random_seed => #{plan.random_seed}`.
@@ -167,7 +166,7 @@ module Suture::Error
167
166
  `:random_seed => nil`.
168
167
  MOAR
169
168
  else
170
- <<-MOAR.gsub(/^ {14}/,'')
169
+ <<-MOAR.gsub(/^ {14}/, "")
171
170
  This test was run in insertion order (by the primary key of the table
172
171
  that stores calls, ascending). This is sometimes necessary when the
173
172
  code has an order-dependent side effect, but shouldn't be set unless it's
@@ -180,7 +179,6 @@ module Suture::Error
180
179
  MSG
181
180
  end
182
181
 
183
-
184
182
  def stringify_error(error)
185
183
  s = error.inspect
186
184
  s += "\n" + error.backtrace.join("\n") if error.backtrace
@@ -6,4 +6,3 @@ module Suture
6
6
  Adapter::Log.reset!
7
7
  end
8
8
  end
9
-
@@ -24,11 +24,9 @@ module Suture::Surgeon
24
24
  private
25
25
 
26
26
  def result_for(plan, path)
27
- begin
28
- Suture::Value::Result.returned(@scalpel.cut(plan, path))
29
- rescue StandardError => error
30
- Suture::Value::Result.errored(error)
31
- end
27
+ Suture::Value::Result.returned(@scalpel.cut(plan, path))
28
+ rescue => error
29
+ Suture::Value::Result.errored(error)
32
30
  end
33
31
 
34
32
  def comparable?(plan, old_result, new_result)
@@ -53,12 +51,12 @@ module Suture::Surgeon
53
51
  if result.errored?
54
52
  raise result.value
55
53
  else
56
- return result.value
54
+ result.value
57
55
  end
58
56
  end
59
57
 
60
58
  def log_warning(plan, old_result, new_result)
61
- log_warn <<-MSG.gsub(/^ {8}/,'')
59
+ log_warn <<-MSG.gsub(/^ {8}/, "")
62
60
  Seam #{plan.name.inspect} is set to :call_both the :new and :old code
63
61
  paths, but they did not match.
64
62
 
@@ -3,7 +3,7 @@ require "suture/util/scalpel"
3
3
  module Suture::Surgeon
4
4
  class NoOp
5
5
  def operate(plan)
6
- if code_path = code_path_for(plan)
6
+ if (code_path = code_path_for(plan))
7
7
  Suture::Util::Scalpel.new.cut(plan, code_path)
8
8
  end
9
9
  end
@@ -9,8 +9,8 @@ module Suture::Surgeon
9
9
  Suture::Util::Scalpel.new.cut(plan, :old).tap do |result|
10
10
  dictaphone.record(result)
11
11
  end
12
- rescue StandardError => error
13
- if plan.expected_error_types.any? {|e| error.kind_of?(e) }
12
+ rescue => error
13
+ if plan.expected_error_types.any? {|e| error.is_a?(e) }
14
14
  dictaphone.record_error(error)
15
15
  end
16
16
  raise error
@@ -18,4 +18,3 @@ module Suture::Surgeon
18
18
  end
19
19
  end
20
20
  end
21
-
@@ -7,14 +7,12 @@ module Suture::Surgeon
7
7
  end
8
8
 
9
9
  def operate(plan)
10
- begin
11
- @scalpel.cut(plan ,:new)
12
- rescue StandardError => actual_error
13
- if plan.expected_error_types.any? { |e| actual_error.is_a?(e) }
14
- raise actual_error
15
- else
16
- @scalpel.cut(plan, :old)
17
- end
10
+ @scalpel.cut(plan, :new)
11
+ rescue => actual_error
12
+ if plan.expected_error_types.any? { |e| actual_error.is_a?(e) }
13
+ raise actual_error
14
+ else
15
+ @scalpel.cut(plan, :old)
18
16
  end
19
17
  end
20
18
  end
@@ -8,7 +8,7 @@ module Suture::Util
8
8
  if expected.errored? != actual.errored?
9
9
  false
10
10
  elsif expected.errored?
11
- actual.value.kind_of?(expected.value.class) &&
11
+ actual.value.is_a?(expected.value.class) &&
12
12
  expected.value.message == actual.value.message
13
13
  else
14
14
  @comparator.call(expected.value, actual.value)
@@ -3,15 +3,15 @@ module Suture::Util
3
3
  def self.to_map(excludes = {})
4
4
  Hash[
5
5
  ENV.keys.
6
- select { |k| k.start_with?("SUTURE_") }.
7
- map { |k| [to_sym(k), sanitize_value(ENV[k])] }
8
- ].reject { |(k,_)| excludes.include?(k) }
6
+ select { |k| k.start_with?("SUTURE_") }.
7
+ map { |k| [to_sym(k), sanitize_value(ENV[k])] }
8
+ ].reject { |(k, _)| excludes.include?(k) }
9
9
  end
10
10
 
11
11
  # private
12
12
 
13
13
  def self.to_sym(name)
14
- name.gsub(/^SUTURE\_/,'').downcase.to_sym
14
+ name.gsub(/^SUTURE\_/, "").downcase.to_sym
15
15
  end
16
16
 
17
17
  def self.sanitize_value(value)
@@ -10,7 +10,7 @@ module Suture::Util
10
10
  plan.send(location).call(*args).tap do |result|
11
11
  call_after_hook(plan, location, args, result)
12
12
  end
13
- rescue StandardError => error
13
+ rescue => error
14
14
  log_error_details(plan, location, args, error)
15
15
  call_error_hook(plan, location, args, error)
16
16
  raise error
@@ -20,13 +20,13 @@ module Suture::Util
20
20
  private
21
21
 
22
22
  def call_after_hook(plan, location, args, result)
23
- return unless after_hook = try(plan, "after_#{location}")
23
+ return unless (after_hook = try(plan, "after_#{location}"))
24
24
  after_hook.call(args, result)
25
25
  end
26
26
 
27
27
  def log_error_details(plan, location, args, error)
28
28
  return if expected_error?(plan, error)
29
- log_error <<-MSG.gsub(/^ {8}/,'')
29
+ log_error <<-MSG.gsub(/^ {8}/, "")
30
30
  Suture invoked the #{plan.name.inspect} seam's #{location.inspect} code path with args: ```
31
31
  #{args.inspect}
32
32
  ```
@@ -38,12 +38,12 @@ module Suture::Util
38
38
 
39
39
  def call_error_hook(plan, location, args, error)
40
40
  return if expected_error?(plan, error)
41
- return unless error_hook = try(plan, "on_#{location}_error")
41
+ return unless (error_hook = try(plan, "on_#{location}_error"))
42
42
  error_hook.call(plan.name, args, error)
43
43
  end
44
44
 
45
45
  def expected_error?(plan, error)
46
- plan.expected_error_types.any? {|e| error.kind_of?(e) }
46
+ plan.expected_error_types.any? {|e| error.is_a?(e) }
47
47
  end
48
48
 
49
49
  def args_for(plan, args_override)
@@ -62,6 +62,5 @@ module Suture::Util
62
62
  return unless plan.respond_to?(method)
63
63
  plan.send(method)
64
64
  end
65
-
66
65
  end
67
66
  end
@@ -7,7 +7,7 @@ module Suture::Util
7
7
  index = random.rand(old_array.size)
8
8
  new_array << old_array.delete_at(index)
9
9
  end
10
- return new_array
10
+ new_array
11
11
  end
12
12
  end
13
13
  end
@@ -13,7 +13,7 @@ module Suture::Value
13
13
  end
14
14
 
15
15
  def result
16
- @expectation ||= @error ? Result.errored(@error) : Result.returned(@return_value)
16
+ @result ||= @error ? Result.errored(@error) : Result.returned(@return_value)
17
17
  end
18
18
  end
19
19
  end
@@ -1,10 +1,10 @@
1
1
  module Suture::Value
2
2
  class Plan
3
3
  attr_reader :name, :old, :new, :args, :after_new, :after_old, :on_new_error,
4
- :on_old_error, :database_path, :record_calls, :comparator,
5
- :call_both, :raise_on_result_mismatch,
6
- :return_old_on_result_mismatch, :fallback_on_error,
7
- :expected_error_types, :disable, :dup_args
4
+ :on_old_error, :database_path, :record_calls, :comparator,
5
+ :call_both, :raise_on_result_mismatch,
6
+ :return_old_on_result_mismatch, :fallback_on_error,
7
+ :expected_error_types, :disable, :dup_args
8
8
 
9
9
  def initialize(attrs = {})
10
10
  @name = attrs[:name]
@@ -19,10 +19,10 @@ module Suture::Value
19
19
  end
20
20
 
21
21
  def ==(other)
22
- other.kind_of?(self.class) && other.state == state
22
+ other.is_a?(self.class) && other.state == state
23
23
  end
24
24
 
25
- alias_method :eql?, :==
25
+ alias eql? ==
26
26
 
27
27
  def hash
28
28
  state.hash
@@ -1,17 +1,17 @@
1
1
  module Suture::Value
2
2
  class TestPlan
3
3
  attr_accessor :name, :subject,
4
- :verify_only, :fail_fast, :call_limit, :time_limit,
5
- :error_message_limit, :random_seed, :comparator,
6
- :database_path, :after_subject, :on_subject_error,
7
- :expected_error_types
4
+ :verify_only, :fail_fast, :call_limit, :time_limit,
5
+ :error_message_limit, :random_seed, :comparator,
6
+ :database_path, :after_subject, :on_subject_error,
7
+ :expected_error_types
8
8
 
9
9
  def initialize(attrs = {})
10
10
  assign_simple_ivars!(attrs, :name, :subject, :comparator,
11
- :database_path, :after_subject,
12
- :on_subject_error)
11
+ :database_path, :after_subject,
12
+ :on_subject_error)
13
13
  assign_integral_ivars!(attrs, :verify_only, :call_limit, :time_limit,
14
- :error_message_limit)
14
+ :error_message_limit)
15
15
  @fail_fast = !!attrs[:fail_fast]
16
16
  @expected_error_types = attrs[:expected_error_types] || []
17
17
  @random_seed = determine_random_seed(attrs)
@@ -26,18 +26,18 @@ module Suture::Value
26
26
  end
27
27
 
28
28
  def assign_integral_ivars!(attrs, *names)
29
- assign_simple_ivars!(massage_values(attrs, names) {|v| v.to_i }, *names)
29
+ assign_simple_ivars!(massage_values(attrs, names, &:to_i), *names)
30
30
  end
31
31
 
32
- def massage_values(attrs, names, &blk)
32
+ def massage_values(attrs, names)
33
33
  Hash[
34
- attrs.select {|(k,_)| names.include?(k) }.
35
- map { |(k,v)| [k, v.nil? ? nil : blk.call(v) ]}
34
+ attrs.select {|(k, _)| names.include?(k) }.
35
+ map { |(k, v)| [k, v.nil? ? nil : yield(v)]}
36
36
  ]
37
37
  end
38
38
 
39
39
  def determine_random_seed(attrs)
40
- if attrs.has_key?(:random_seed)
40
+ if attrs.key?(:random_seed)
41
41
  if attrs[:random_seed].nil? || attrs[:random_seed] == "nil"
42
42
  nil
43
43
  else
@@ -45,4 +45,3 @@ module Suture::Value
45
45
  end
46
46
  end
47
47
  end
48
-
@@ -11,4 +11,3 @@ module Suture
11
11
  end
12
12
  end
13
13
  end
14
-
@@ -14,17 +14,17 @@ module Suture
14
14
  result = Value::Result.returned(@scalpel.cut(test_plan, :subject, observation.args))
15
15
  {
16
16
  :new_result => result,
17
- :passed => compares_results.compare(observation.result, result)
17
+ :passed => compares_results.compare(observation.result, result),
18
18
  }
19
- rescue StandardError => error
19
+ rescue => error
20
20
  if observation.result.errored?
21
21
  result = Value::Result.errored(error)
22
22
  {
23
23
  :new_result => result,
24
- :passed => compares_results.compare(observation.result, result)
24
+ :passed => compares_results.compare(observation.result, result),
25
25
  }
26
26
  else
27
- { :error => error, :passed => false }
27
+ {:error => error, :passed => false}
28
28
  end
29
29
  end
30
30
  end
@@ -8,5 +8,3 @@ module Suture
8
8
  end
9
9
  end
10
10
  end
11
-
12
-
@@ -4,7 +4,7 @@ require "suture/util/env"
4
4
  module Suture
5
5
  class PrescribesTestPlan
6
6
  UN_ENV_IABLE_OPTIONS = [:name, :subject, :comparator, :after_subject,
7
- :on_subject_error, :expected_error_types]
7
+ :on_subject_error, :expected_error_types,]
8
8
 
9
9
  def prescribe(name, options = {})
10
10
  Value::TestPlan.new(Suture.config.
@@ -24,12 +24,12 @@ module Suture
24
24
  if should_skip?(test_plan, experienced_failure_in_life, i, timer)
25
25
  {
26
26
  :observation => observation,
27
- :ran => false
27
+ :ran => false,
28
28
  }
29
29
  else
30
30
  @administers_test.administer(test_plan, observation).merge({
31
31
  :observation => observation,
32
- :ran => true
32
+ :ran => true,
33
33
  }).tap { |r| experienced_failure_in_life = true unless r[:passed] }
34
34
  end
35
35
  })
@@ -39,7 +39,7 @@ module Suture
39
39
 
40
40
  def validate_test_plan!(test_plan)
41
41
  if !test_plan.subject || !test_plan.subject.respond_to?(:call)
42
- raise Suture::Error::InvalidTestPlan.new
42
+ raise Suture::Error::InvalidTestPlan
43
43
  end
44
44
  end
45
45
 
@@ -56,7 +56,7 @@ module Suture
56
56
  test_plan.random_seed
57
57
  ).tap do |test_cases|
58
58
  next if test_cases.size > 0
59
- log_warn <<-MSG.gsub(/^ {10}/,'')
59
+ log_warn <<-MSG.gsub(/^ {10}/, "")
60
60
  Suture.verify found no recorded calls for seam #{test_plan.name.inspect}.
61
61
  As a result, verify will have no effect and cannot provide any assurance
62
62
  that the subject is working as expected.
@@ -70,4 +70,3 @@ module Suture
70
70
  end
71
71
  end
72
72
  end
73
-
@@ -1,3 +1,3 @@
1
1
  module Suture
2
- VERSION = "1.1.1"
2
+ VERSION = "1.1.2"
3
3
  end
@@ -12,12 +12,12 @@ module Suture::Wrap
12
12
  end
13
13
 
14
14
  @logger.level = if options[:log_level]
15
- ::Logger.const_get(options[:log_level])
16
- else
17
- ::Logger::INFO
18
- end
15
+ ::Logger.const_get(options[:log_level])
16
+ else
17
+ ::Logger::INFO
18
+ end
19
19
 
20
- @logger.formatter = proc { |_, time , _, msg|
20
+ @logger.formatter = proc { |_, time, _, msg|
21
21
  formatted_time = time.strftime("%Y-%m-%dT%H:%M:%S.%6N")
22
22
  "[#{formatted_time}] Suture: #{msg}\n".tap { |out|
23
23
  puts out if options[:log_stdout]
@@ -25,19 +25,39 @@ module Suture::Wrap
25
25
  }
26
26
  }
27
27
 
28
- return @logger
28
+ @logger
29
29
  end
30
30
 
31
31
  class NullIO
32
- def gets; end
33
- def each; end
34
- def read(count=nil,buffer=nil); (count && count > 0) ? nil : ""; end
35
- def rewind; 0; end
36
- def close; end
37
- def size; 0; end
38
- def sync=(*args); end
39
- def puts(*args); end
40
- def write(*args); end
32
+ def gets
33
+ end
34
+
35
+ def each
36
+ end
37
+
38
+ def read(count = nil, _buffer = nil)
39
+ count && count > 0 ? nil : ""
40
+ end
41
+
42
+ def rewind
43
+ 0
44
+ end
45
+
46
+ def close
47
+ end
48
+
49
+ def size
50
+ 0
51
+ end
52
+
53
+ def sync=(*args)
54
+ end
55
+
56
+ def puts(*args)
57
+ end
58
+
59
+ def write(*args)
60
+ end
41
61
  end
42
62
  end
43
63
  end
@@ -4,7 +4,7 @@ require "suture/error/schema_version"
4
4
 
5
5
  module Suture::Wrap
6
6
  module Sqlite
7
- SCHEMA_VERSION=2
7
+ SCHEMA_VERSION = 2
8
8
  def self.init(location)
9
9
  full_path = File.join(Dir.getwd, location)
10
10
  FileUtils.mkdir_p(File.dirname(full_path))
@@ -1,7 +1,8 @@
1
1
  # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
2
+
3
+ lib = File.expand_path("../lib", __FILE__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'suture/version'
5
+ require "suture/version"
5
6
 
6
7
  Gem::Specification.new do |spec|
7
8
  spec.name = "suture"
@@ -9,8 +10,8 @@ Gem::Specification.new do |spec|
9
10
  spec.authors = ["Justin Searls"]
10
11
  spec.email = ["searls@gmail.com"]
11
12
 
12
- spec.summary = %q{A gem that helps people refactor or reimplement legacy code}
13
- spec.description = %q{Provides tools to record calls to legacy code and verify new implementations still work}
13
+ spec.summary = "A gem that helps people refactor or reimplement legacy code"
14
+ spec.description = "Provides tools to record calls to legacy code and verify new implementations still work"
14
15
  spec.homepage = "https://github.com/testdouble/suture"
15
16
 
16
17
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(example|test|db|log|safe|spec|features)/}) }
@@ -30,7 +31,11 @@ Gem::Specification.new do |spec|
30
31
 
31
32
  if Gem.ruby_version >= Gem::Version.new("1.9.3")
32
33
  spec.add_development_dependency "codeclimate-test-reporter"
33
- spec.add_development_dependency "simplecov", "~> 0.11.2" #<--only here to lock
34
+ spec.add_development_dependency "simplecov", "~> 0.11.2" # <--only here to lock
35
+ end
36
+
37
+ if Gem.ruby_version >= Gem::Version.new("2.2.0")
38
+ spec.add_development_dependency "standard"
34
39
  end
35
40
 
36
41
  if Gem.ruby_version >= Gem::Version.new("2.2.2")
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: suture
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Searls
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-09-19 00:00:00.000000000 Z
11
+ date: 2018-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sqlite3
@@ -150,6 +150,20 @@ dependencies:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
152
  version: 0.11.2
153
+ - !ruby/object:Gem::Dependency
154
+ name: standard
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
153
167
  - !ruby/object:Gem::Dependency
154
168
  name: github_changelog_generator
155
169
  requirement: !ruby/object:Gem::Requirement
@@ -176,6 +190,7 @@ files:
176
190
  - ".gitignore"
177
191
  - ".projections.json"
178
192
  - ".rubocop.yml"
193
+ - ".standard.yml"
179
194
  - ".travis.yml"
180
195
  - CHANGELOG.md
181
196
  - Gemfile
@@ -246,7 +261,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
246
261
  version: '0'
247
262
  requirements: []
248
263
  rubyforge_project:
249
- rubygems_version: 2.5.1
264
+ rubygems_version: 2.7.6
250
265
  signing_key:
251
266
  specification_version: 4
252
267
  summary: A gem that helps people refactor or reimplement legacy code