brutal 1.6.0.beta4 → 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.
@@ -1,170 +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 a test" if before.empty?
43
- after = "# Finishing a test" 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
- string = before_code
102
- eval(before_code) # rubocop:disable Security/Eval
103
-
104
- actual_str = format(inspect(subject), **attributes(*values))
105
- string += actual_code(actual_str)
106
- actual = eval(actual_str) # rubocop:disable Security/Eval, Lint/UselessAssignment
107
-
108
- actuals.each do |actual_value|
109
- result_str = format(actual_value, subject: "actual")
110
- result = eval(result_str) # rubocop:disable Security/Eval
111
- string += "raise if #{result_str} != #{result.inspect}\n"
112
- end
113
-
114
- string += after_code
115
- eval(after_code) # rubocop:disable Security/Eval
116
-
117
- string
118
- end
119
- end
120
-
121
- def actual_code(actual_str)
122
- <<~CODE
123
- actual = begin
124
- #{actual_str.gsub(/^/, INDENTATION)}
125
- end
126
-
127
- CODE
128
- end
129
-
130
- def header_code
131
- <<~CODE
132
- #{header.chomp}
133
- CODE
134
- end
135
-
136
- def before_code
137
- <<~CODE
138
- #{before.chomp}
139
-
140
- CODE
141
- end
142
-
143
- def after_code
144
- <<~CODE
145
-
146
- #{after.chomp}
147
- CODE
148
- end
149
-
150
- def footer_code
151
- <<~CODE
152
- #{footer.chomp}
153
- CODE
154
- end
155
-
156
- def separator_code
157
- <<~CODE
158
-
159
- #{thematic_break_code}
160
- CODE
161
- end
162
-
163
- def thematic_break_code
164
- <<~CODE
165
- # #{HYPHEN_MINUS * 78}
166
- CODE
167
- end
168
- end
169
- end
170
- end
data/lib/brutal/format.rb DELETED
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- Dir[File.join(File.dirname(__FILE__), "format", "*.rb")].sort.each do |fname|
4
- require_relative fname
5
- end
6
-
7
- class Brutal
8
- # A collection of formatter classes.
9
- module Format
10
- end
11
- end
@@ -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
@@ -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