suture 0.1.0 → 0.2.0
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/.projections.json +5 -0
- data/.travis.yml +10 -0
- data/LICENSE.txt +20 -0
- data/README.md +2 -0
- data/lib/suture/adapter/dictaphone.rb +30 -6
- data/lib/suture/builds_plan.rb +9 -14
- data/lib/suture/chooses_surgeon.rb +3 -0
- data/lib/suture/error/observation_conflict.rb +43 -0
- data/lib/suture/error/schema_version.rb +12 -0
- data/lib/suture/error/verification_failed.rb +12 -0
- data/lib/suture/interprets_results.rb +12 -0
- data/lib/suture/prescribes_test_plan.rb +19 -0
- data/lib/suture/surgeon/observer.rb +2 -5
- data/lib/suture/tests_patient.rb +38 -0
- data/lib/suture/util/env.rb +22 -0
- data/lib/suture/value/plan.rb +2 -1
- data/lib/suture/value/test_plan.rb +12 -0
- data/lib/suture/value/test_results.rb +38 -0
- data/lib/suture/version.rb +1 -1
- data/lib/suture/wrap/sqlite.rb +27 -6
- data/lib/suture.rb +16 -3
- data/suture.gemspec +1 -1
- metadata +16 -6
- data/lib/suture/surgeon.rb +0 -2
- data/lib/suture/value.rb +0 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 00233003cd21f9ec984925ed6fbc2f5a03ce9671
|
4
|
+
data.tar.gz: 526640d66eed549a7e7943f3ef2c459b1bfcd315
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9b19ab9fd1965a1ac8b41522b4cbd9b5cad966616c4e3518bb41ad120375e324cf341d1bb5bd735b2cc341e28a8b00ffd108e1db7c25e3eb1d934016b52233c1
|
7
|
+
data.tar.gz: 53ceca44a97179bb4a256357d6ae3c587b9c67751c7aebc63fdf0c5637c9888f081e32d8b0f371f353b0a2c987b43d54fb295512c2830b0ea6e71c9062c2b40b
|
data/.projections.json
ADDED
data/.travis.yml
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2016 Test Double, LLC
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# Suture
|
2
2
|
|
3
|
+
[](https://travis-ci.org/testdouble/suture)
|
4
|
+
|
3
5
|
A refactoring tool for Ruby, designed to make it safe to change code you don't
|
4
6
|
confidently understand. In fact, changing untrustworthy code is so fraught,
|
5
7
|
Suture hopes to make it safer to completely reimplement a code path.
|
@@ -1,18 +1,30 @@
|
|
1
1
|
require "suture/wrap/sqlite"
|
2
|
+
require "suture/value/observation"
|
3
|
+
require "suture/error/observation_conflict"
|
2
4
|
|
3
5
|
module Suture::Adapter
|
4
6
|
class Dictaphone
|
5
|
-
def initialize
|
6
|
-
@db = Suture::Wrap::Sqlite.init
|
7
|
+
def initialize(plan)
|
8
|
+
@db = Suture::Wrap::Sqlite.init(plan.database_path)
|
9
|
+
@name = plan.name
|
10
|
+
@args = plan.args
|
7
11
|
end
|
8
12
|
|
9
|
-
def record(
|
13
|
+
def record(result)
|
10
14
|
Suture::Wrap::Sqlite.insert(@db, :observations, [:name, :args, :result],
|
11
|
-
[name.to_s, Marshal.dump(args), Marshal.dump(result)])
|
15
|
+
[@name.to_s, Marshal.dump(@args), Marshal.dump(result)])
|
16
|
+
|
17
|
+
rescue SQLite3::ConstraintException => e
|
18
|
+
old_result = result_for(@name, @args)
|
19
|
+
if old_result != result # TODO - use comparator
|
20
|
+
raise Suture::Error::ObservationConflict.new(@name, @args, result, old_result)
|
21
|
+
else
|
22
|
+
# We're all good here, it was just a duplicative observation. No harm.
|
23
|
+
end
|
12
24
|
end
|
13
25
|
|
14
|
-
def play
|
15
|
-
rows = Suture::Wrap::Sqlite.select(@db, :observations, "where name = ?", [name.to_s])
|
26
|
+
def play
|
27
|
+
rows = Suture::Wrap::Sqlite.select(@db, :observations, "where name = ?", [@name.to_s])
|
16
28
|
rows.map do |row|
|
17
29
|
Suture::Value::Observation.new(
|
18
30
|
row[0],
|
@@ -22,5 +34,17 @@ module Suture::Adapter
|
|
22
34
|
)
|
23
35
|
end
|
24
36
|
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def result_for(name, args)
|
41
|
+
rows = Suture::Wrap::Sqlite.select(
|
42
|
+
@db,
|
43
|
+
:observations,
|
44
|
+
"where name = ? and args = ?",
|
45
|
+
[name.to_s, Marshal.dump(args)]
|
46
|
+
)
|
47
|
+
Marshal.load(rows.first[3])
|
48
|
+
end
|
25
49
|
end
|
26
50
|
end
|
data/lib/suture/builds_plan.rb
CHANGED
@@ -1,22 +1,17 @@
|
|
1
|
+
require "suture/value/plan"
|
2
|
+
require "suture/util/env"
|
3
|
+
|
1
4
|
module Suture
|
2
5
|
class BuildsPlan
|
3
6
|
UN_ENV_IABLE_OPTIONS = [:name, :old, :new, :args]
|
4
7
|
|
5
8
|
def build(name, options = {})
|
6
|
-
Value::Plan.new(
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
Hash[ENV.keys.
|
13
|
-
select { |k| k.start_with?("SUTURE_") }.
|
14
|
-
map { |k| [env_var_name_to_option_name(k), ENV[k]] }].
|
15
|
-
reject { |(k,v)| UN_ENV_IABLE_OPTIONS.include?(k) }
|
16
|
-
end
|
17
|
-
|
18
|
-
def env_var_name_to_option_name(name)
|
19
|
-
name.gsub(/^SUTURE\_/,'').downcase.to_sym
|
9
|
+
Value::Plan.new(
|
10
|
+
DEFAULT_OPTIONS.
|
11
|
+
merge(options).
|
12
|
+
merge(:name => name).
|
13
|
+
merge(Suture::Util::Env.to_map(UN_ENV_IABLE_OPTIONS))
|
14
|
+
)
|
20
15
|
end
|
21
16
|
end
|
22
17
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Suture::Error
|
2
|
+
class ObservationConflict < StandardError
|
3
|
+
def initialize(name, args, new_result, old_result)
|
4
|
+
@name = name
|
5
|
+
@args = args
|
6
|
+
@new_result = new_result
|
7
|
+
@old_result = old_result
|
8
|
+
end
|
9
|
+
|
10
|
+
def message
|
11
|
+
<<-MSG.gsub(/^\s{8}/,'')
|
12
|
+
At suture #{@name.inspect} with inputs `#{@args.inspect}`, the newly-observed return value `#{@new_result.inspect}`
|
13
|
+
conflicts with previously recorded return value `#{@old_result.inspect}`.
|
14
|
+
|
15
|
+
That's not good! Here are a few ideas of what may have happened:
|
16
|
+
|
17
|
+
1. The old code path may have a side effect that results in different
|
18
|
+
return values. If it's possible, to create the suture at a point after
|
19
|
+
this side effect. Otherwise, read on.
|
20
|
+
|
21
|
+
2. Either environmental differents (e.g. system time resulting in a
|
22
|
+
different timestamp) or side effects (e.g. saving to a database
|
23
|
+
resulting in a different GUID value) mean that Suture is detecting two
|
24
|
+
different results for the same inputs. This can be worked around by
|
25
|
+
providing a custom comparator for the two values nearest common
|
26
|
+
ancestor type. Comparator support is tracked here:
|
27
|
+
https://github.com/testdouble/suture/issues/14
|
28
|
+
|
29
|
+
3. If neither of the above are true, it's possible that the old code path
|
30
|
+
was changed while still in the early stage of recording characterization
|
31
|
+
calls (presumably by mistake). If such a change may have occurred in
|
32
|
+
error, check your git history. Otherwise, perhaps you `record_calls` is
|
33
|
+
accidentally still enabled and should be turned off for this suture
|
34
|
+
(either with SUTURE_RECORD_CALLS=false or :record_calls => false).
|
35
|
+
|
36
|
+
4. If the old recording was made in error, then you may want to delete it
|
37
|
+
Deletion support via the Suture API is tracked here:
|
38
|
+
https://github.com/testdouble/suture/issues/10
|
39
|
+
|
40
|
+
MSG
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Suture::Error
|
2
|
+
class SchemaVersion < StandardError
|
3
|
+
def initialize(expected, actual)
|
4
|
+
@expected = expected
|
5
|
+
@actual = actual
|
6
|
+
end
|
7
|
+
|
8
|
+
def message
|
9
|
+
"Your suture gem is too #{@expected > @actual ? "new" : "old"} for this schema. Either delete your database or #{@expected > @actual ? "upgrade" : "downgrade"} the gem (expected schema version #{@expected}, was #{@actual})"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require "suture/value/test_plan"
|
2
|
+
require "suture/util/env"
|
3
|
+
|
4
|
+
module Suture
|
5
|
+
class PrescribesTestPlan
|
6
|
+
UN_ENV_IABLE_OPTIONS = [:name, :subject, :args]
|
7
|
+
DEFAULT_TEST_OPTIONS = {
|
8
|
+
:fail_fast => true
|
9
|
+
}
|
10
|
+
|
11
|
+
def prescribe(name, options = {})
|
12
|
+
Value::TestPlan.new(DEFAULT_OPTIONS.
|
13
|
+
merge(DEFAULT_TEST_OPTIONS).
|
14
|
+
merge(options).
|
15
|
+
merge(:name => name).
|
16
|
+
merge(Suture::Util::Env.to_map(UN_ENV_IABLE_OPTIONS)))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -2,13 +2,10 @@ require "suture/adapter/dictaphone"
|
|
2
2
|
|
3
3
|
module Suture::Surgeon
|
4
4
|
class Observer
|
5
|
-
def initialize
|
6
|
-
@dictaphone = Suture::Adapter::Dictaphone.new
|
7
|
-
end
|
8
|
-
|
9
5
|
def operate(plan)
|
6
|
+
dictaphone = Suture::Adapter::Dictaphone.new(plan)
|
10
7
|
plan.old.call(*plan.args).tap do |result|
|
11
|
-
|
8
|
+
dictaphone.record(result)
|
12
9
|
end
|
13
10
|
end
|
14
11
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "suture/adapter/dictaphone"
|
2
|
+
require "suture/value/test_results"
|
3
|
+
|
4
|
+
module Suture
|
5
|
+
class TestsPatient
|
6
|
+
def test(test_plan)
|
7
|
+
dictaphone = Suture::Adapter::Dictaphone.new(test_plan)
|
8
|
+
experienced_failure_in_life = false
|
9
|
+
Value::TestResults.new(dictaphone.play.map { |observation|
|
10
|
+
if test_plan.fail_fast && experienced_failure_in_life
|
11
|
+
{
|
12
|
+
:observation => observation,
|
13
|
+
:ran => false
|
14
|
+
}
|
15
|
+
else
|
16
|
+
invoke(test_plan, observation).merge({
|
17
|
+
:observation => observation,
|
18
|
+
:ran => true
|
19
|
+
}).tap { |r| experienced_failure_in_life = true unless r[:passed]}
|
20
|
+
end
|
21
|
+
})
|
22
|
+
end
|
23
|
+
|
24
|
+
def invoke(test_plan, observation)
|
25
|
+
{}.tap do |result|
|
26
|
+
begin
|
27
|
+
result[:new_result] = test_plan.subject.call(*observation.args)
|
28
|
+
# TODO: Comparators go here:
|
29
|
+
result[:passed] = result[:new_result] == observation.result
|
30
|
+
rescue StandardError => e
|
31
|
+
result[:passed] = false
|
32
|
+
result[:error] = e
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Suture::Util
|
2
|
+
module Env
|
3
|
+
def self.to_map(excludes)
|
4
|
+
Hash[
|
5
|
+
ENV.keys.
|
6
|
+
select { |k| k.start_with?("SUTURE_") }.
|
7
|
+
map { |k| [to_sym(k), sanitize_value(ENV[k])] }
|
8
|
+
].reject { |(k,v)| excludes.include?(k) }
|
9
|
+
end
|
10
|
+
|
11
|
+
# private
|
12
|
+
|
13
|
+
def self.to_sym(name)
|
14
|
+
name.gsub(/^SUTURE\_/,'').downcase.to_sym
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.sanitize_value(value)
|
18
|
+
return false if value == "false"
|
19
|
+
value
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/suture/value/plan.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
module Suture::Value
|
2
2
|
class Plan
|
3
|
-
attr_reader :name, :old, :new, :args, :record_calls
|
3
|
+
attr_reader :name, :old, :new, :args, :record_calls, :database_path
|
4
4
|
def initialize(attrs = {})
|
5
5
|
@name = attrs[:name]
|
6
6
|
@old = attrs[:old]
|
7
7
|
@new = attrs[:new]
|
8
8
|
@args = attrs[:args]
|
9
9
|
@record_calls = !!attrs[:record_calls]
|
10
|
+
@database_path = attrs[:database_path]
|
10
11
|
end
|
11
12
|
end
|
12
13
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Suture::Value
|
2
|
+
class TestPlan
|
3
|
+
attr_accessor :name, :subject, :args, :fail_fast, :database_path
|
4
|
+
def initialize(attrs = {})
|
5
|
+
@name = attrs[:name]
|
6
|
+
@subject = attrs[:subject]
|
7
|
+
@args = attrs[:args]
|
8
|
+
@fail_fast = attrs[:fail_fast]
|
9
|
+
@database_path = attrs[:database_path]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Suture::Value
|
2
|
+
class TestResults
|
3
|
+
attr_reader :results
|
4
|
+
|
5
|
+
def initialize(results)
|
6
|
+
@results = results
|
7
|
+
end
|
8
|
+
|
9
|
+
def failed?
|
10
|
+
@results.any? { |r| !r[:passed] }
|
11
|
+
end
|
12
|
+
|
13
|
+
def ran_all_tests?
|
14
|
+
@results.all? { |r| r[:ran] }
|
15
|
+
end
|
16
|
+
|
17
|
+
def total_count
|
18
|
+
@results.size
|
19
|
+
end
|
20
|
+
|
21
|
+
def passed_count
|
22
|
+
@results.count { |r| r[:passed] }
|
23
|
+
end
|
24
|
+
|
25
|
+
def failed_count
|
26
|
+
@results.count { |r| !r[:passed] && r[:ran] }
|
27
|
+
end
|
28
|
+
|
29
|
+
def errored_count
|
30
|
+
@results.count { |r| r[:error] }
|
31
|
+
end
|
32
|
+
|
33
|
+
def skipped_count
|
34
|
+
@results.count { |r| !r[:ran] }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
data/lib/suture/version.rb
CHANGED
data/lib/suture/wrap/sqlite.rb
CHANGED
@@ -1,24 +1,45 @@
|
|
1
1
|
require "fileutils"
|
2
|
-
require "
|
2
|
+
require "sqlite3"
|
3
|
+
require "suture/error/schema_version"
|
3
4
|
|
4
5
|
module Suture::Wrap
|
5
6
|
module Sqlite
|
6
|
-
|
7
|
-
|
8
|
-
|
7
|
+
SCHEMA_VERSION=1
|
8
|
+
def self.init(location)
|
9
|
+
full_path = File.join(Dir.getwd, location)
|
10
|
+
FileUtils.mkdir_p(File.dirname(full_path))
|
11
|
+
SQLite3::Database.new(full_path).tap do |db|
|
12
|
+
db.execute <<-SQL
|
13
|
+
create table if not exists schema_info (
|
14
|
+
version integer unique
|
15
|
+
);
|
16
|
+
SQL
|
17
|
+
db.execute("insert or ignore into schema_info values (?)", [SCHEMA_VERSION])
|
18
|
+
actual_schema_version = db.execute("select * from schema_info").first[0]
|
19
|
+
if SCHEMA_VERSION != actual_schema_version
|
20
|
+
raise Suture::Error::SchemaVersion.new(SCHEMA_VERSION, actual_schema_version)
|
21
|
+
end
|
22
|
+
|
9
23
|
db.execute <<-SQL
|
10
24
|
create table if not exists observations (
|
11
25
|
id integer primary key,
|
12
26
|
name varchar(255),
|
13
27
|
args clob,
|
14
|
-
result clob
|
28
|
+
result clob,
|
29
|
+
unique(name, args)
|
15
30
|
);
|
16
31
|
SQL
|
17
32
|
end
|
18
33
|
end
|
19
34
|
|
20
35
|
def self.insert(db, table, cols, vals)
|
21
|
-
|
36
|
+
sql = <<-SQL
|
37
|
+
insert into #{table}
|
38
|
+
(#{cols.join(", ")})
|
39
|
+
values
|
40
|
+
(#{vals.size.times.map { "?" }.join(", ")})
|
41
|
+
SQL
|
42
|
+
db.execute(sql, vals)
|
22
43
|
end
|
23
44
|
|
24
45
|
def self.select(db, table, where_clause, bind_params)
|
data/lib/suture.rb
CHANGED
@@ -1,16 +1,29 @@
|
|
1
1
|
require "suture/version"
|
2
2
|
|
3
|
-
require "suture/surgeon"
|
4
|
-
require "suture/value"
|
5
|
-
|
6
3
|
require "suture/builds_plan"
|
7
4
|
require "suture/chooses_surgeon"
|
8
5
|
require "suture/performs_surgery"
|
9
6
|
|
7
|
+
require "suture/prescribes_test_plan"
|
8
|
+
require "suture/tests_patient"
|
9
|
+
require "suture/interprets_results"
|
10
|
+
|
10
11
|
module Suture
|
12
|
+
DEFAULT_OPTIONS = {
|
13
|
+
:database_path => "db/suture.sqlite3"
|
14
|
+
}
|
15
|
+
|
11
16
|
def self.create(name, options)
|
12
17
|
plan = BuildsPlan.new.build(name, options)
|
13
18
|
surgeon = ChoosesSurgeon.new.choose(plan)
|
14
19
|
PerformsSurgery.new.perform(plan, surgeon)
|
15
20
|
end
|
21
|
+
|
22
|
+
def self.verify(name, options)
|
23
|
+
test_plan = Suture::PrescribesTestPlan.new.prescribe(name, options)
|
24
|
+
test_results = Suture::TestsPatient.new.test(test_plan)
|
25
|
+
if test_results.failed?
|
26
|
+
Suture::InterpretsResults.new.interpret(test_results)
|
27
|
+
end
|
28
|
+
end
|
16
29
|
end
|
data/suture.gemspec
CHANGED
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
|
|
22
22
|
|
23
23
|
spec.add_development_dependency "bundler", "~> 1.12"
|
24
24
|
spec.add_development_dependency "rake", "~> 10.0"
|
25
|
-
spec.add_development_dependency "pry", "~> 0.
|
25
|
+
spec.add_development_dependency "pry", "~> 0.9.12.6"
|
26
26
|
spec.add_development_dependency "minitest", "~> 5.9"
|
27
27
|
spec.add_development_dependency "gimme", "~> 0.5"
|
28
28
|
end
|
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: 0.
|
4
|
+
version: 0.2.0
|
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-08-
|
11
|
+
date: 2016-08-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sqlite3
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 0.9.12.6
|
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: 0.9.12.6
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: minitest
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -103,7 +103,10 @@ extensions: []
|
|
103
103
|
extra_rdoc_files: []
|
104
104
|
files:
|
105
105
|
- ".gitignore"
|
106
|
+
- ".projections.json"
|
107
|
+
- ".travis.yml"
|
106
108
|
- Gemfile
|
109
|
+
- LICENSE.txt
|
107
110
|
- README.md
|
108
111
|
- Rakefile
|
109
112
|
- bin/console
|
@@ -112,13 +115,20 @@ files:
|
|
112
115
|
- lib/suture/adapter/dictaphone.rb
|
113
116
|
- lib/suture/builds_plan.rb
|
114
117
|
- lib/suture/chooses_surgeon.rb
|
118
|
+
- lib/suture/error/observation_conflict.rb
|
119
|
+
- lib/suture/error/schema_version.rb
|
120
|
+
- lib/suture/error/verification_failed.rb
|
121
|
+
- lib/suture/interprets_results.rb
|
115
122
|
- lib/suture/performs_surgery.rb
|
116
|
-
- lib/suture/
|
123
|
+
- lib/suture/prescribes_test_plan.rb
|
117
124
|
- lib/suture/surgeon/no_op.rb
|
118
125
|
- lib/suture/surgeon/observer.rb
|
119
|
-
- lib/suture/
|
126
|
+
- lib/suture/tests_patient.rb
|
127
|
+
- lib/suture/util/env.rb
|
120
128
|
- lib/suture/value/observation.rb
|
121
129
|
- lib/suture/value/plan.rb
|
130
|
+
- lib/suture/value/test_plan.rb
|
131
|
+
- lib/suture/value/test_results.rb
|
122
132
|
- lib/suture/version.rb
|
123
133
|
- lib/suture/wrap/sqlite.rb
|
124
134
|
- suture.gemspec
|
data/lib/suture/surgeon.rb
DELETED
data/lib/suture/value.rb
DELETED