brutal 1.3.0 → 1.4.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/README.md +16 -43
- data/bin/brutal +1 -1
- data/lib/brutal/file.rb +20 -3
- data/lib/brutal/scaffold.rb +46 -21
- data/lib/brutal/yaml.rb +2 -2
- data/lib/brutal.rb +22 -12
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 31ea2d6a9b38faaa03aaed25dfc8b18158a8d243b9aed42e0f4a3a488c8386a3
|
4
|
+
data.tar.gz: f73e4a2798de7a55deb006898919498a9d6344fcd3ec94728a379bf723370ae2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f5a9b52b8608bdf327bb14ad782cde378901285a3d9de0b28d273184480586f868da0b10bf32ac47980bfbc0b637b6bc058de2c42bdb600b4add7bb1865207e0
|
7
|
+
data.tar.gz: 302e2bf37546bc813caa05eedb38f2ad496123e6ba37b186d449ea2e5782945ef5d652d8cdc05a25c08045a472144ad6efa30f4316c23f5e3ca9ecdbdd8c8818
|
data/README.md
CHANGED
@@ -59,7 +59,8 @@ Just type `brutal` in a Ruby project's folder and watch the magic happen.
|
|
59
59
|
|
60
60
|
## Usage
|
61
61
|
|
62
|
-
__Brutal__ needs a configuration file
|
62
|
+
__Brutal__ needs a configuration file to know how to write your tests.
|
63
|
+
Currently, only the YAML format is supported.
|
63
64
|
This file is composed of 4 top-level sections:
|
64
65
|
|
65
66
|
* `header` - Specifies the code to execute before generating the test suite.
|
@@ -67,59 +68,31 @@ This file is composed of 4 top-level sections:
|
|
67
68
|
* `contexts` - Specifies a list of variables to populate the subject's template.
|
68
69
|
* `actuals` - Specifies templates to challenge evaluated subjects & get results.
|
69
70
|
|
70
|
-
|
71
|
-
|
72
|
-
Currently, only the YAML format is supported.
|
73
|
-
|
74
|
-
### Getting started
|
75
|
-
|
76
|
-
1. Create a `.brutal.yml` file in your application's root directory.
|
77
|
-
The following example `.brutal.yml` defines the shape of a Hello test suite:
|
71
|
+
This file is by default called `.brutal.yml`, but it would be possible to name it differently by passing it as an argument to the brutal command such as:
|
78
72
|
|
79
|
-
```
|
80
|
-
|
81
|
-
subject: |
|
82
|
-
"Hello " + "%{string}"
|
83
|
-
|
84
|
-
contexts:
|
85
|
-
string:
|
86
|
-
- Alice
|
87
|
-
- Bob
|
88
|
-
|
89
|
-
actuals:
|
90
|
-
- "%{subject}.to_s"
|
91
|
-
- "%{subject}.length"
|
73
|
+
```sh
|
74
|
+
brutal test_hello_world.yml
|
92
75
|
```
|
93
76
|
|
94
|
-
|
77
|
+
This would create a `test_hello_world.rb` file containing the test suite.
|
95
78
|
|
96
|
-
|
79
|
+
To avoid accidentally overwriting a file, the `--no-force` option can be used:
|
97
80
|
|
98
|
-
```
|
99
|
-
|
100
|
-
|
101
|
-
# ------------------------------------------------------------------------------
|
102
|
-
|
103
|
-
actual = begin
|
104
|
-
"Hello " + "Alice"
|
105
|
-
end
|
106
|
-
|
107
|
-
raise if actual.to_s != "Hello Alice"
|
108
|
-
raise if actual.length != 11
|
81
|
+
```sh
|
82
|
+
brutal test_hello_world.yml --no-force
|
83
|
+
```
|
109
84
|
|
110
|
-
|
85
|
+
> A test_hello_world.rb file already exists!
|
111
86
|
|
112
|
-
|
113
|
-
"Hello " + "Bob"
|
114
|
-
end
|
87
|
+
### Getting started
|
115
88
|
|
116
|
-
|
117
|
-
|
118
|
-
|
89
|
+
1. Create a `.brutal.yml` file in your application's root directory. For example: <https://github.com/fixrb/brutal/blob/v1.4.0/examples/hello_world_v1/.brutal.yml>
|
90
|
+
2. Run the `brutal` command from the same directory.
|
91
|
+
3. Read the generated `test.rb` file in the same directory: <https://github.com/fixrb/brutal/blob/v1.4.0/examples/hello_world_v1/test.rb>
|
119
92
|
|
120
93
|
### More examples
|
121
94
|
|
122
|
-
https://github.com/fixrb/brutal/
|
95
|
+
<https://github.com/fixrb/brutal/blob/v1.4.0/examples/>
|
123
96
|
|
124
97
|
## Rake integration example
|
125
98
|
|
data/bin/brutal
CHANGED
data/lib/brutal/file.rb
CHANGED
@@ -11,10 +11,27 @@ module Brutal
|
|
11
11
|
DEFAULT_CONFIG_FILENAME = ".brutal.yml"
|
12
12
|
DEFAULT_GENERATED_FILENAME = "test.rb"
|
13
13
|
|
14
|
-
def self.
|
15
|
-
|
14
|
+
def self.generated_pathname(pathname)
|
15
|
+
filename = pathname.split(separator).fetch(-1)
|
16
16
|
|
17
|
-
filename
|
17
|
+
if filename == DEFAULT_CONFIG_FILENAME
|
18
|
+
directory_parts = pathname.split(separator)[..-2]
|
19
|
+
path_parts = directory_parts + [DEFAULT_GENERATED_FILENAME]
|
20
|
+
return path_parts.join(separator)
|
21
|
+
end
|
22
|
+
|
23
|
+
pathname.gsub(/.[^.]+\z/, ".rb")
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.override_protection(pathname)
|
27
|
+
return true unless ::File.exist?(pathname)
|
28
|
+
|
29
|
+
abort "A #{pathname} file already exists!"
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.separator
|
33
|
+
::File::SEPARATOR
|
18
34
|
end
|
35
|
+
private_class_method :separator
|
19
36
|
end
|
20
37
|
end
|
data/lib/brutal/scaffold.rb
CHANGED
@@ -42,20 +42,35 @@ module Brutal
|
|
42
42
|
#
|
43
43
|
# @return [String]
|
44
44
|
def to_s
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
45
|
+
ruby_lines.join(separator_ruby_code)
|
46
|
+
end
|
47
|
+
|
48
|
+
def attributes(*values)
|
49
|
+
context_names.each_with_index.inject({}) do |h, (name, i)|
|
50
|
+
h.merge(name.to_sym => inspect(values.fetch(i)))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def context_names
|
55
|
+
contexts.keys.sort
|
56
|
+
end
|
49
57
|
|
50
|
-
|
58
|
+
def contexts_values
|
59
|
+
context_names.map { |context_name| contexts.fetch(context_name) }
|
60
|
+
end
|
51
61
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
end
|
62
|
+
def combinations_values
|
63
|
+
Array(contexts_values[0]).product(*Array(contexts_values[1..]))
|
64
|
+
end
|
56
65
|
|
57
|
-
|
66
|
+
def ruby_lines
|
67
|
+
[header_ruby_code] + actual_ruby_codes
|
68
|
+
end
|
58
69
|
|
70
|
+
def actual_ruby_codes
|
71
|
+
combinations_values.map do |values|
|
72
|
+
actual_str = format(inspect(subject), **attributes(*values))
|
73
|
+
string = actual_ruby_code(actual_str)
|
59
74
|
actual = eval(actual_str) # rubocop:disable Security/Eval, Lint/UselessAssignment
|
60
75
|
|
61
76
|
actuals.each do |actual_value|
|
@@ -64,25 +79,35 @@ module Brutal
|
|
64
79
|
end
|
65
80
|
|
66
81
|
string
|
67
|
-
end
|
82
|
+
end
|
68
83
|
end
|
69
84
|
|
70
|
-
def
|
71
|
-
|
72
|
-
|
73
|
-
|
85
|
+
def actual_ruby_code(actual_str)
|
86
|
+
<<~RUBY_CODE
|
87
|
+
actual = begin
|
88
|
+
#{actual_str.gsub(/^/, ' ')}
|
89
|
+
end
|
90
|
+
|
91
|
+
RUBY_CODE
|
74
92
|
end
|
75
93
|
|
76
|
-
def
|
77
|
-
|
94
|
+
def header_ruby_code
|
95
|
+
<<~RUBY_CODE
|
96
|
+
#{header.chomp}
|
97
|
+
RUBY_CODE
|
78
98
|
end
|
79
99
|
|
80
|
-
def
|
81
|
-
|
100
|
+
def separator_ruby_code
|
101
|
+
<<~RUBY_CODE
|
102
|
+
|
103
|
+
#{thematic_break_ruby_code}
|
104
|
+
RUBY_CODE
|
82
105
|
end
|
83
106
|
|
84
|
-
def
|
85
|
-
|
107
|
+
def thematic_break_ruby_code
|
108
|
+
<<~RUBY_CODE
|
109
|
+
# #{'-' * 78}
|
110
|
+
RUBY_CODE
|
86
111
|
end
|
87
112
|
end
|
88
113
|
end
|
data/lib/brutal/yaml.rb
CHANGED
@@ -16,8 +16,8 @@ module Brutal
|
|
16
16
|
::YAML.safe_load(yaml, symbolize_names: false)
|
17
17
|
end
|
18
18
|
|
19
|
-
def self.parse?(
|
20
|
-
filename_extension =
|
19
|
+
def self.parse?(pathname)
|
20
|
+
filename_extension = pathname.split(".")[1..][-1]
|
21
21
|
FILENAME_EXTENSIONS.include?(filename_extension)
|
22
22
|
end
|
23
23
|
end
|
data/lib/brutal.rb
CHANGED
@@ -9,16 +9,8 @@
|
|
9
9
|
|
10
10
|
# The Brutal namespace.
|
11
11
|
module Brutal
|
12
|
-
def self.generate!(
|
13
|
-
|
14
|
-
|
15
|
-
hash = if Yaml.parse?(filename)
|
16
|
-
Yaml.parse(file)
|
17
|
-
else
|
18
|
-
raise ::ArgumentError, "Unrecognized extension. " \
|
19
|
-
"Impossible to parse #{filename.inspect}."
|
20
|
-
end
|
21
|
-
|
12
|
+
def self.generate!(pathname, force: true)
|
13
|
+
hash = parse(pathname)
|
22
14
|
conf = Configuration.load(hash)
|
23
15
|
|
24
16
|
ruby = Scaffold.new(conf.header,
|
@@ -26,8 +18,26 @@ module Brutal
|
|
26
18
|
*conf.actuals,
|
27
19
|
**conf.contexts)
|
28
20
|
|
29
|
-
|
21
|
+
write(pathname, ruby, force: force)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.parse(pathname)
|
25
|
+
return Yaml.parse(read(pathname)) if Yaml.parse?(pathname)
|
26
|
+
|
27
|
+
raise ::ArgumentError, "Unrecognized extension. " \
|
28
|
+
"Impossible to parse #{pathname.inspect}."
|
29
|
+
end
|
30
|
+
private_class_method :parse
|
31
|
+
|
32
|
+
def self.read(pathname)
|
33
|
+
File::Read.new(pathname).call
|
34
|
+
end
|
35
|
+
private_class_method :read
|
30
36
|
|
31
|
-
|
37
|
+
def self.write(pathname, ruby, force:)
|
38
|
+
new_pathname = File.generated_pathname(pathname)
|
39
|
+
File.override_protection(new_pathname) unless force
|
40
|
+
File::Write.new(new_pathname).call(ruby)
|
32
41
|
end
|
42
|
+
private_class_method :write
|
33
43
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: brutal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cyril Kato
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-08-
|
11
|
+
date: 2022-08-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|