pact 1.3.3 → 1.4.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +16 -1
- data/Gemfile +5 -0
- data/Gemfile.lock +34 -13
- data/README.md +3 -2
- data/example/animal-service/lib/animal_service/api.rb +1 -0
- data/example/zoo-app/lib/zoo_app/animal_service_client.rb +0 -9
- data/example/zoo-app/lib/zoo_app/models/alligator.rb +2 -0
- data/lib/pact.rb +6 -5
- data/lib/pact/cli.rb +0 -26
- data/lib/pact/consumer/configuration.rb +0 -1
- data/lib/pact/consumer/configuration/configuration_extensions.rb +51 -0
- data/lib/pact/consumer/consumer_contract_builder.rb +1 -2
- data/lib/pact/consumer/interaction_builder.rb +2 -4
- data/lib/pact/doc/interaction_view_model.rb +9 -6
- data/lib/pact/doc/sort_interactions.rb +1 -1
- data/lib/pact/provider/rspec.rb +11 -9
- data/lib/pact/version.rb +1 -1
- data/pact.gemspec +5 -0
- data/spec/lib/pact/consumer/interaction_builder_spec.rb +4 -8
- data/spec/support/case-insensitive-response-header-matching.json +21 -0
- data/spec/support/case-insensitive-response-header-matching.rb +15 -0
- data/tasks/pact-test.rake +5 -0
- metadata +42 -122
- data/lib/pact/configuration.rb +0 -195
- data/lib/pact/consumer/app_manager.rb +0 -158
- data/lib/pact/consumer/interactions_filter.rb +0 -48
- data/lib/pact/consumer/mock_service.rb +0 -2
- data/lib/pact/consumer/mock_service/app.rb +0 -82
- data/lib/pact/consumer/mock_service/interaction_delete.rb +0 -33
- data/lib/pact/consumer/mock_service/interaction_list.rb +0 -76
- data/lib/pact/consumer/mock_service/interaction_mismatch.rb +0 -73
- data/lib/pact/consumer/mock_service/interaction_post.rb +0 -31
- data/lib/pact/consumer/mock_service/interaction_replay.rb +0 -139
- data/lib/pact/consumer/mock_service/log_get.rb +0 -28
- data/lib/pact/consumer/mock_service/missing_interactions_get.rb +0 -30
- data/lib/pact/consumer/mock_service/mock_service_administration_endpoint.rb +0 -31
- data/lib/pact/consumer/mock_service/pact_post.rb +0 -33
- data/lib/pact/consumer/mock_service/rack_request_helper.rb +0 -51
- data/lib/pact/consumer/mock_service/verification_get.rb +0 -68
- data/lib/pact/consumer/mock_service_client.rb +0 -65
- data/lib/pact/consumer/mock_service_interaction_expectation.rb +0 -37
- data/lib/pact/consumer/request.rb +0 -27
- data/lib/pact/consumer/server.rb +0 -90
- data/lib/pact/consumer_contract.rb +0 -1
- data/lib/pact/consumer_contract/consumer_contract.rb +0 -115
- data/lib/pact/consumer_contract/consumer_contract_writer.rb +0 -84
- data/lib/pact/consumer_contract/file_name.rb +0 -19
- data/lib/pact/consumer_contract/headers.rb +0 -51
- data/lib/pact/consumer_contract/interaction.rb +0 -67
- data/lib/pact/consumer_contract/pact_file.rb +0 -24
- data/lib/pact/consumer_contract/request.rb +0 -73
- data/lib/pact/consumer_contract/service_consumer.rb +0 -28
- data/lib/pact/consumer_contract/service_provider.rb +0 -28
- data/lib/pact/logging.rb +0 -14
- data/lib/pact/matchers.rb +0 -1
- data/lib/pact/matchers/actual_type.rb +0 -16
- data/lib/pact/matchers/base_difference.rb +0 -37
- data/lib/pact/matchers/differ.rb +0 -153
- data/lib/pact/matchers/difference.rb +0 -13
- data/lib/pact/matchers/difference_indicator.rb +0 -26
- data/lib/pact/matchers/embedded_diff_formatter.rb +0 -62
- data/lib/pact/matchers/expected_type.rb +0 -35
- data/lib/pact/matchers/index_not_found.rb +0 -15
- data/lib/pact/matchers/list_diff_formatter.rb +0 -101
- data/lib/pact/matchers/matchers.rb +0 -139
- data/lib/pact/matchers/no_diff_indicator.rb +0 -18
- data/lib/pact/matchers/regexp_difference.rb +0 -13
- data/lib/pact/matchers/type_difference.rb +0 -16
- data/lib/pact/matchers/unexpected_index.rb +0 -11
- data/lib/pact/matchers/unexpected_key.rb +0 -11
- data/lib/pact/matchers/unix_diff_formatter.rb +0 -114
- data/lib/pact/reification.rb +0 -28
- data/lib/pact/rspec.rb +0 -53
- data/lib/pact/shared/active_support_support.rb +0 -51
- data/lib/pact/shared/dsl.rb +0 -76
- data/lib/pact/shared/jruby_support.rb +0 -18
- data/lib/pact/shared/json_differ.rb +0 -15
- data/lib/pact/shared/key_not_found.rb +0 -15
- data/lib/pact/shared/null_expectation.rb +0 -31
- data/lib/pact/shared/request.rb +0 -80
- data/lib/pact/shared/text_differ.rb +0 -14
- data/lib/pact/something_like.rb +0 -49
- data/lib/pact/symbolize_keys.rb +0 -12
- data/lib/pact/term.rb +0 -85
- data/spec/lib/pact/consumer/request_spec.rb +0 -24
- data/spec/lib/pact/consumer_contract/active_support_support_spec.rb +0 -58
- data/spec/lib/pact/consumer_contract/consumer_contract_spec.rb +0 -180
- data/spec/lib/pact/consumer_contract/headers_spec.rb +0 -107
- data/spec/lib/pact/consumer_contract/interaction_spec.rb +0 -107
- data/spec/lib/pact/consumer_contract/request_spec.rb +0 -329
- data/spec/lib/pact/matchers/differ_spec.rb +0 -214
- data/spec/lib/pact/matchers/difference_spec.rb +0 -22
- data/spec/lib/pact/matchers/embedded_diff_formatter_spec.rb +0 -90
- data/spec/lib/pact/matchers/index_not_found_spec.rb +0 -21
- data/spec/lib/pact/matchers/list_diff_formatter_spec.rb +0 -114
- data/spec/lib/pact/matchers/matchers_spec.rb +0 -500
- data/spec/lib/pact/matchers/regexp_difference_spec.rb +0 -20
- data/spec/lib/pact/matchers/type_difference_spec.rb +0 -34
- data/spec/lib/pact/matchers/unexpected_index_spec.rb +0 -20
- data/spec/lib/pact/matchers/unexpected_key_spec.rb +0 -20
- data/spec/lib/pact/matchers/unix_diff_formatter_spec.rb +0 -216
- data/spec/lib/pact/reification_spec.rb +0 -67
- data/spec/lib/pact/shared/dsl_spec.rb +0 -86
- data/spec/lib/pact/shared/json_differ_spec.rb +0 -36
- data/spec/lib/pact/shared/key_not_found_spec.rb +0 -20
- data/spec/lib/pact/shared/request_spec.rb +0 -111
- data/spec/lib/pact/shared/text_differ_spec.rb +0 -54
- data/spec/lib/pact/something_like_spec.rb +0 -21
- data/spec/lib/pact/term_spec.rb +0 -89
- data/spec/support/dsl_spec_support.rb +0 -7
@@ -1,24 +0,0 @@
|
|
1
|
-
module Pact
|
2
|
-
|
3
|
-
module PactFile
|
4
|
-
|
5
|
-
extend self
|
6
|
-
|
7
|
-
def read uri, options = {}
|
8
|
-
pact = open(uri.to_s) { | file | file.read }
|
9
|
-
if options[:save_pactfile_to_tmp]
|
10
|
-
save_pactfile_to_tmp pact, ::File.basename(uri.to_s)
|
11
|
-
end
|
12
|
-
pact
|
13
|
-
rescue StandardError => e
|
14
|
-
$stderr.puts "Error reading file from #{uri}"
|
15
|
-
$stderr.puts "#{e.to_s} #{e.backtrace.join("\n")}"
|
16
|
-
raise e
|
17
|
-
end
|
18
|
-
|
19
|
-
def save_pactfile_to_tmp pact, name
|
20
|
-
::FileUtils.mkdir_p Pact.configuration.tmp_dir
|
21
|
-
::File.open(Pact.configuration.tmp_dir + "/#{name}", "w") { |file| file << pact}
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
@@ -1,73 +0,0 @@
|
|
1
|
-
require 'pact/shared/request'
|
2
|
-
require 'pact/shared/null_expectation'
|
3
|
-
|
4
|
-
module Pact
|
5
|
-
|
6
|
-
module Request
|
7
|
-
|
8
|
-
class Expected < Pact::Request::Base
|
9
|
-
|
10
|
-
DEFAULT_OPTIONS = {:allow_unexpected_keys => false}.freeze
|
11
|
-
attr_accessor :options #Temporary hack
|
12
|
-
|
13
|
-
def self.from_hash(hash)
|
14
|
-
sym_hash = symbolize_keys hash
|
15
|
-
method = sym_hash.fetch(:method)
|
16
|
-
path = sym_hash.fetch(:path)
|
17
|
-
query = sym_hash.fetch(:query, key_not_found)
|
18
|
-
headers = sym_hash.fetch(:headers, key_not_found)
|
19
|
-
body = sym_hash.fetch(:body, key_not_found)
|
20
|
-
options = sym_hash.fetch(:options, {})
|
21
|
-
new(method, path, headers, body, query, options)
|
22
|
-
end
|
23
|
-
|
24
|
-
def initialize(method, path, headers, body, query, options = {})
|
25
|
-
super(method, path, headers, body, query)
|
26
|
-
@options = options
|
27
|
-
end
|
28
|
-
|
29
|
-
def matches?(actual_request)
|
30
|
-
difference(actual_request).empty?
|
31
|
-
end
|
32
|
-
|
33
|
-
def matches_route? actual_request
|
34
|
-
diff({:method => method, :path => path}, {:method => actual_request.method, :path => actual_request.path}).empty?
|
35
|
-
end
|
36
|
-
|
37
|
-
def difference(actual_request)
|
38
|
-
request_diff = diff(to_hash_without_body, actual_request.to_hash_without_body)
|
39
|
-
unless body.is_a? NullExpectation
|
40
|
-
request_diff.merge(body_difference(actual_request.body))
|
41
|
-
else
|
42
|
-
request_diff
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
protected
|
47
|
-
|
48
|
-
def self.key_not_found
|
49
|
-
Pact::NullExpectation.new
|
50
|
-
end
|
51
|
-
|
52
|
-
private
|
53
|
-
|
54
|
-
# Options is a dirty hack to allow Condor to send extra keys in the request,
|
55
|
-
# as it's too much work to set up an exactly matching expectation.
|
56
|
-
# Need to implement a proper matching strategy and remove this.
|
57
|
-
# Do not rely on it!
|
58
|
-
def runtime_options
|
59
|
-
DEFAULT_OPTIONS.merge(symbolize_keys(options))
|
60
|
-
end
|
61
|
-
|
62
|
-
def body_difference(actual_body)
|
63
|
-
body_differ.call({:body => body}, {body: actual_body}, allow_unexpected_keys: runtime_options[:allow_unexpected_keys_in_body])
|
64
|
-
end
|
65
|
-
|
66
|
-
def body_differ
|
67
|
-
Pact.configuration.body_differ_for_content_type content_type
|
68
|
-
end
|
69
|
-
|
70
|
-
end
|
71
|
-
|
72
|
-
end
|
73
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
require 'pact/symbolize_keys'
|
2
|
-
|
3
|
-
module Pact
|
4
|
-
class ServiceConsumer
|
5
|
-
include SymbolizeKeys
|
6
|
-
|
7
|
-
attr_accessor :name
|
8
|
-
def initialize options
|
9
|
-
@name = options[:name]
|
10
|
-
end
|
11
|
-
|
12
|
-
def to_s
|
13
|
-
name
|
14
|
-
end
|
15
|
-
|
16
|
-
def to_hash
|
17
|
-
{name: name}
|
18
|
-
end
|
19
|
-
|
20
|
-
def as_json options = {}
|
21
|
-
to_hash
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.from_hash hash
|
25
|
-
new(symbolize_keys(hash))
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
require 'pact/symbolize_keys'
|
2
|
-
|
3
|
-
module Pact
|
4
|
-
class ServiceProvider
|
5
|
-
include SymbolizeKeys
|
6
|
-
|
7
|
-
attr_accessor :name
|
8
|
-
def initialize options
|
9
|
-
@name = options[:name] || '[provider name unknown - please update the pact gem in the consumer project to the latest version and regenerate the pacts]'
|
10
|
-
end
|
11
|
-
|
12
|
-
def to_s
|
13
|
-
name
|
14
|
-
end
|
15
|
-
|
16
|
-
def to_hash
|
17
|
-
{name: name}
|
18
|
-
end
|
19
|
-
|
20
|
-
def as_json options = {}
|
21
|
-
to_hash
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.from_hash hash
|
25
|
-
new(symbolize_keys(hash))
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
data/lib/pact/logging.rb
DELETED
data/lib/pact/matchers.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require_relative 'matchers/matchers'
|
@@ -1,37 +0,0 @@
|
|
1
|
-
require 'pact/matchers/expected_type'
|
2
|
-
require 'pact/matchers/actual_type'
|
3
|
-
|
4
|
-
module Pact
|
5
|
-
module Matchers
|
6
|
-
class BaseDifference
|
7
|
-
|
8
|
-
attr_reader :expected, :actual
|
9
|
-
|
10
|
-
def initialize expected, actual
|
11
|
-
@expected = expected
|
12
|
-
@actual = actual
|
13
|
-
end
|
14
|
-
|
15
|
-
def any?
|
16
|
-
true
|
17
|
-
end
|
18
|
-
|
19
|
-
def empty?
|
20
|
-
false
|
21
|
-
end
|
22
|
-
|
23
|
-
def to_json options = {}
|
24
|
-
as_json.to_json(options)
|
25
|
-
end
|
26
|
-
|
27
|
-
def to_s
|
28
|
-
as_json.to_s
|
29
|
-
end
|
30
|
-
|
31
|
-
def == other
|
32
|
-
other.class == self.class && other.expected == expected && other.actual == actual
|
33
|
-
end
|
34
|
-
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
data/lib/pact/matchers/differ.rb
DELETED
@@ -1,153 +0,0 @@
|
|
1
|
-
# Ripped from RSpec::Expectations::Differ in rspec/expectations/differ.rb in rspec-expectations 2.14.3
|
2
|
-
# Thank you kindly to the original author.
|
3
|
-
# Needed to be able to turn the colour off, but can't set RSpec.configuration.color to false
|
4
|
-
# once it has been set to true due to a "if bool" at the start of the color= method
|
5
|
-
|
6
|
-
require 'diff/lcs'
|
7
|
-
require 'diff/lcs/hunk'
|
8
|
-
require 'pp'
|
9
|
-
|
10
|
-
module Pact
|
11
|
-
module Matchers
|
12
|
-
class Differ
|
13
|
-
|
14
|
-
def initialize(color = false)
|
15
|
-
@color = color
|
16
|
-
end
|
17
|
-
|
18
|
-
# This is snagged from diff/lcs/ldiff.rb (which is a commandline tool)
|
19
|
-
def diff_as_string(input_data_new, input_data_old)
|
20
|
-
output = matching_encoding("", input_data_old)
|
21
|
-
data_old = input_data_old.split(matching_encoding("\n", input_data_old)).map! { |e| e.chomp }
|
22
|
-
data_new = input_data_new.split(matching_encoding("\n", input_data_new)).map! { |e| e.chomp }
|
23
|
-
diffs = Diff::LCS.diff(data_old, data_new)
|
24
|
-
return output if diffs.empty?
|
25
|
-
oldhunk = hunk = nil
|
26
|
-
file_length_difference = 0
|
27
|
-
diffs.each do |piece|
|
28
|
-
begin
|
29
|
-
hunk = Diff::LCS::Hunk.new(
|
30
|
-
data_old, data_new, piece, context_lines, file_length_difference
|
31
|
-
)
|
32
|
-
file_length_difference = hunk.file_length_difference
|
33
|
-
next unless oldhunk
|
34
|
-
# Hunks may overlap, which is why we need to be careful when our
|
35
|
-
# diff includes lines of context. Otherwise, we might print
|
36
|
-
# redundant lines.
|
37
|
-
if (context_lines > 0) and hunk.overlaps?(oldhunk)
|
38
|
-
if hunk.respond_to?(:merge)
|
39
|
-
# diff-lcs 1.2.x
|
40
|
-
hunk.merge(oldhunk)
|
41
|
-
else
|
42
|
-
# diff-lcs 1.1.3
|
43
|
-
hunk.unshift(oldhunk)
|
44
|
-
end
|
45
|
-
else
|
46
|
-
output << matching_encoding(oldhunk.diff(format).to_s, output)
|
47
|
-
end
|
48
|
-
ensure
|
49
|
-
oldhunk = hunk
|
50
|
-
output << matching_encoding("\n", output)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
#Handle the last remaining hunk
|
54
|
-
output << matching_encoding(oldhunk.diff(format).to_s,output)
|
55
|
-
output << matching_encoding("\n",output)
|
56
|
-
color_diff output
|
57
|
-
rescue Encoding::CompatibilityError
|
58
|
-
if input_data_new.encoding != input_data_old.encoding
|
59
|
-
"Could not produce a diff because the encoding of the actual string (#{input_data_old.encoding}) "+
|
60
|
-
"differs from the encoding of the expected string (#{input_data_new.encoding})"
|
61
|
-
else
|
62
|
-
"Could not produce a diff because of the encoding of the string (#{input_data_old.encoding})"
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def diff_as_object(actual, expected)
|
67
|
-
actual_as_string = object_to_string(actual)
|
68
|
-
expected_as_string = object_to_string(expected)
|
69
|
-
if diff = diff_as_string(actual_as_string, expected_as_string)
|
70
|
-
color_diff diff
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
def red(text)
|
75
|
-
return text unless @color
|
76
|
-
color(text, 31)
|
77
|
-
end
|
78
|
-
|
79
|
-
def green(text)
|
80
|
-
return text unless @color
|
81
|
-
color(text, 32)
|
82
|
-
end
|
83
|
-
|
84
|
-
protected
|
85
|
-
|
86
|
-
def format
|
87
|
-
:unified
|
88
|
-
end
|
89
|
-
|
90
|
-
def context_lines
|
91
|
-
3
|
92
|
-
end
|
93
|
-
|
94
|
-
def color(text, color_code)
|
95
|
-
"\e[#{color_code}m#{text}\e[0m"
|
96
|
-
end
|
97
|
-
|
98
|
-
|
99
|
-
def blue(text)
|
100
|
-
color(text, 34)
|
101
|
-
end
|
102
|
-
|
103
|
-
def color_diff(diff)
|
104
|
-
return diff unless @color
|
105
|
-
|
106
|
-
diff.lines.map { |line|
|
107
|
-
case line[0].chr
|
108
|
-
when "+"
|
109
|
-
green line
|
110
|
-
when "-"
|
111
|
-
red line
|
112
|
-
when "@"
|
113
|
-
line[1].chr == "@" ? blue(line) : line
|
114
|
-
else
|
115
|
-
line
|
116
|
-
end
|
117
|
-
}.join
|
118
|
-
end
|
119
|
-
|
120
|
-
def object_to_string(object)
|
121
|
-
case object
|
122
|
-
when Hash
|
123
|
-
object.keys.sort_by { |k| k.to_s }.map do |key|
|
124
|
-
pp_key = PP.singleline_pp(key, "")
|
125
|
-
pp_value = PP.singleline_pp(object[key], "")
|
126
|
-
|
127
|
-
# on 1.9.3 PP seems to minimise to US-ASCII, ensure we're matching source encoding
|
128
|
-
#
|
129
|
-
# note, PP is used to ensure the ordering of the internal values of key/value e.g.
|
130
|
-
# <# a: b: c:> not <# c: a: b:>
|
131
|
-
matching_encoding("#{pp_key} => #{pp_value}", key.to_s)
|
132
|
-
end.join(",\n")
|
133
|
-
when String
|
134
|
-
object =~ /\n/ ? object : object.inspect
|
135
|
-
else
|
136
|
-
PP.pp(object,"")
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
if String.method_defined?(:encoding)
|
141
|
-
def matching_encoding(string, source)
|
142
|
-
string.encode(source.encoding)
|
143
|
-
end
|
144
|
-
else
|
145
|
-
def matching_encoding(string, source)
|
146
|
-
string
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
@@ -1,26 +0,0 @@
|
|
1
|
-
require 'pact/shared/active_support_support'
|
2
|
-
|
3
|
-
module Pact
|
4
|
-
class DifferenceIndicator
|
5
|
-
|
6
|
-
include ActiveSupportSupport
|
7
|
-
|
8
|
-
def == other
|
9
|
-
other.class == self.class
|
10
|
-
end
|
11
|
-
|
12
|
-
def eql? other
|
13
|
-
self == other
|
14
|
-
end
|
15
|
-
|
16
|
-
def to_json options = {}
|
17
|
-
remove_unicode as_json.to_json(options)
|
18
|
-
end
|
19
|
-
|
20
|
-
def as_json options = {}
|
21
|
-
to_s
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
end
|
@@ -1,62 +0,0 @@
|
|
1
|
-
require 'pact/shared/active_support_support'
|
2
|
-
require 'term/ansicolor'
|
3
|
-
|
4
|
-
module Pact
|
5
|
-
module Matchers
|
6
|
-
class EmbeddedDiffFormatter
|
7
|
-
|
8
|
-
include Pact::ActiveSupportSupport
|
9
|
-
C = ::Term::ANSIColor
|
10
|
-
|
11
|
-
|
12
|
-
EXPECTED = /"EXPECTED([A-Z_]*)":/
|
13
|
-
|
14
|
-
ACTUAL = /"ACTUAL([A-Z_]*)":/
|
15
|
-
|
16
|
-
attr_reader :diff, :colour
|
17
|
-
|
18
|
-
def initialize diff, options = {}
|
19
|
-
@diff = diff
|
20
|
-
@colour = options.fetch(:colour, false)
|
21
|
-
end
|
22
|
-
|
23
|
-
def self.call diff, options = {colour: Pact.configuration.color_enabled}
|
24
|
-
new(diff, options).call
|
25
|
-
end
|
26
|
-
|
27
|
-
def call
|
28
|
-
to_s
|
29
|
-
end
|
30
|
-
|
31
|
-
def to_hash
|
32
|
-
diff
|
33
|
-
end
|
34
|
-
|
35
|
-
def to_s
|
36
|
-
colourise_message_if_configured fix_json_formatting(diff.to_json)
|
37
|
-
end
|
38
|
-
|
39
|
-
def colourise_message_if_configured message
|
40
|
-
if colour
|
41
|
-
colourise_message message
|
42
|
-
else
|
43
|
-
message
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def colourise_message message
|
48
|
-
message.split("\n").collect{| line | colourise(line) }.join("\n")
|
49
|
-
end
|
50
|
-
|
51
|
-
def colourise line
|
52
|
-
line.gsub(EXPECTED){|match| coloured_key match, :red }.gsub(ACTUAL){ | match | coloured_key match, :green }
|
53
|
-
end
|
54
|
-
|
55
|
-
def coloured_key match, colour
|
56
|
-
'"' + C.color(colour, match.downcase.gsub(/^"|":$/,'')) + '":'
|
57
|
-
end
|
58
|
-
|
59
|
-
end
|
60
|
-
|
61
|
-
end
|
62
|
-
end
|