brutal 1.6.0.beta3 → 2.0.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/LICENSE.md +1 -1
- data/README.md +155 -77
- data/bin/brutal +7 -12
- data/lib/brutal/cli.rb +134 -0
- data/lib/brutal/literal.rb +62 -0
- data/lib/brutal/manifest.rb +120 -79
- data/lib/brutal/output.rb +94 -0
- data/lib/brutal/program.rb +182 -0
- data/lib/brutal/runner.rb +186 -0
- data/lib/brutal.rb +81 -25
- metadata +29 -122
- data/lib/brutal/command_line_arguments_parser.rb +0 -115
- data/lib/brutal/format/ruby/filename.rb +0 -15
- data/lib/brutal/format/ruby.rb +0 -163
- data/lib/brutal/format.rb +0 -11
- data/lib/brutal/manifest/file/name.rb +0 -18
- data/lib/brutal/manifest/file.rb +0 -26
data/lib/brutal/format/ruby.rb
DELETED
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative File.join("ruby", "filename")
|
|
4
|
-
|
|
5
|
-
class Brutal
|
|
6
|
-
module Format
|
|
7
|
-
# Ruby format class
|
|
8
|
-
class Ruby
|
|
9
|
-
# Whitespace character.
|
|
10
|
-
SPACE = " "
|
|
11
|
-
|
|
12
|
-
# Hyphen-minus character.
|
|
13
|
-
HYPHEN_MINUS = "-"
|
|
14
|
-
|
|
15
|
-
# Two spaces per indentation level.
|
|
16
|
-
INDENTATION = SPACE * 2
|
|
17
|
-
|
|
18
|
-
# Specifies templates to challenge evaluated subjects & get results.
|
|
19
|
-
attr_reader :actuals
|
|
20
|
-
|
|
21
|
-
# Specifies a list of variables to populate the subject's template.
|
|
22
|
-
attr_reader :contexts
|
|
23
|
-
|
|
24
|
-
# Specifies a block of lines to be executed once before all examples.
|
|
25
|
-
attr_reader :header
|
|
26
|
-
|
|
27
|
-
# Specifies a block of lines to be executed before each example.
|
|
28
|
-
attr_reader :before
|
|
29
|
-
|
|
30
|
-
# Specifies the template of the code to be declined across contexts.
|
|
31
|
-
attr_reader :subject
|
|
32
|
-
|
|
33
|
-
# Specifies a block of lines to be executed after each example.
|
|
34
|
-
attr_reader :after
|
|
35
|
-
|
|
36
|
-
# Specifies a block of lines to be executed once after all examples.
|
|
37
|
-
attr_reader :footer
|
|
38
|
-
|
|
39
|
-
# Initialize a new scaffold generator.
|
|
40
|
-
def initialize(header, before, subject, after, footer, *actuals, **contexts)
|
|
41
|
-
header = "# Brutal test suite" if header.empty?
|
|
42
|
-
before = "# Starting an example" if before.empty?
|
|
43
|
-
after = "# Finishing an example" if after.empty?
|
|
44
|
-
footer = "# End of the brutal test" if footer.empty?
|
|
45
|
-
|
|
46
|
-
warn("Empty subject!") if subject.empty?
|
|
47
|
-
warn("Empty actual values!") if actuals.empty?
|
|
48
|
-
warn("Empty contexts!") if contexts.empty?
|
|
49
|
-
|
|
50
|
-
@header = header
|
|
51
|
-
@before = before
|
|
52
|
-
@subject = subject
|
|
53
|
-
@actuals = actuals
|
|
54
|
-
@contexts = contexts
|
|
55
|
-
@after = after
|
|
56
|
-
@footer = footer
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
# Return a Ruby string that can be evaluated.
|
|
60
|
-
def inspect(object)
|
|
61
|
-
return object.to_s unless object.is_a?(::String)
|
|
62
|
-
|
|
63
|
-
object.strip
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
# Return a string representation.
|
|
67
|
-
#
|
|
68
|
-
# @return [String]
|
|
69
|
-
def to_s
|
|
70
|
-
eval(header) # rubocop:disable Security/Eval
|
|
71
|
-
|
|
72
|
-
ruby_lines.compact.join(separator_code)
|
|
73
|
-
ensure
|
|
74
|
-
eval(footer) # rubocop:disable Security/Eval
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def attributes(*values)
|
|
78
|
-
context_names.each_with_index.inject({}) do |h, (name, i)|
|
|
79
|
-
h.merge(name.to_sym => inspect(values.fetch(i)))
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def context_names
|
|
84
|
-
contexts.keys.sort
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def contexts_values
|
|
88
|
-
context_names.map { |context_name| contexts.fetch(context_name) }
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
def combinations_values
|
|
92
|
-
Array(contexts_values[0]).product(*Array(contexts_values[1..]))
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
def ruby_lines
|
|
96
|
-
[header_code] + actual_codes + [footer_code]
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
def actual_codes
|
|
100
|
-
combinations_values.map do |values|
|
|
101
|
-
actual_str = format(inspect(subject), **attributes(*values))
|
|
102
|
-
string = actual_code(actual_str)
|
|
103
|
-
actual = eval(actual_str) # rubocop:disable Security/Eval, Lint/UselessAssignment
|
|
104
|
-
|
|
105
|
-
actuals.each do |actual_value|
|
|
106
|
-
result_str = format(actual_value, subject: "actual")
|
|
107
|
-
string += "raise if #{result_str} != #{eval(result_str).inspect}\n" # rubocop:disable Security/Eval
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
string
|
|
111
|
-
end
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
def actual_code(actual_str)
|
|
115
|
-
<<~CODE
|
|
116
|
-
#{before_code}
|
|
117
|
-
actual = begin
|
|
118
|
-
#{actual_str.gsub(/^/, INDENTATION)}
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
#{after_code}
|
|
122
|
-
CODE
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
def header_code
|
|
126
|
-
<<~CODE
|
|
127
|
-
#{header.chomp}
|
|
128
|
-
CODE
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
def before_code
|
|
132
|
-
<<~CODE
|
|
133
|
-
#{before.chomp}
|
|
134
|
-
CODE
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
def after_code
|
|
138
|
-
<<~CODE
|
|
139
|
-
#{after.chomp}
|
|
140
|
-
CODE
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
def footer_code
|
|
144
|
-
<<~CODE
|
|
145
|
-
#{footer.chomp}
|
|
146
|
-
CODE
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
def separator_code
|
|
150
|
-
<<~CODE
|
|
151
|
-
|
|
152
|
-
#{thematic_break_code}
|
|
153
|
-
CODE
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
def thematic_break_code
|
|
157
|
-
<<~CODE
|
|
158
|
-
# #{HYPHEN_MINUS * 78}
|
|
159
|
-
CODE
|
|
160
|
-
end
|
|
161
|
-
end
|
|
162
|
-
end
|
|
163
|
-
end
|
data/lib/brutal/format.rb
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class Brutal
|
|
4
|
-
class Manifest
|
|
5
|
-
class File
|
|
6
|
-
module Name
|
|
7
|
-
# Suffix for configuration file names.
|
|
8
|
-
SUFFIX = "_brutal.yaml"
|
|
9
|
-
|
|
10
|
-
# Suffix pattern for configuration file names.
|
|
11
|
-
SUFFIX_PATTERN = "*#{SUFFIX}"
|
|
12
|
-
|
|
13
|
-
# Suffix regex for configuration file names.
|
|
14
|
-
SUFFIX_REGEX = /#{SUFFIX}\z/.freeze
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
data/lib/brutal/manifest/file.rb
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative File.join("file", "name")
|
|
4
|
-
|
|
5
|
-
require "yaml"
|
|
6
|
-
|
|
7
|
-
class Brutal
|
|
8
|
-
class Manifest
|
|
9
|
-
# YAML manifest file parser.
|
|
10
|
-
class File
|
|
11
|
-
attr_reader :yaml
|
|
12
|
-
|
|
13
|
-
def initialize(pathname)
|
|
14
|
-
unless pathname.fnmatch?(Name::SUFFIX_PATTERN, ::File::FNM_PATHNAME | ::File::FNM_DOTMATCH)
|
|
15
|
-
raise ::ArgumentError
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
@yaml = pathname.read
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def parse
|
|
22
|
-
::YAML.safe_load(yaml, symbolize_names: false)
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|