teuton 2.3.10 → 2.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 +44 -13
- data/docs/CHANGELOG.md +0 -13
- data/docs/changelog/todo.md +18 -0
- data/docs/changelog/v2.3.md +4 -0
- data/docs/changelog/v2.4.md +6 -2
- data/docs/dsl/execution/export.md +9 -15
- data/docs/dsl/execution/show.md +22 -7
- data/docs/ideas/{ideas.md → todo.md} +8 -16
- data/docs/learn/01-target.md +14 -43
- data/docs/learn/02-config.md +20 -37
- data/docs/learn/03-remote_hosts.md +20 -1
- data/docs/learn/04-new_test.md +4 -4
- data/docs/learn/05-use.md +3 -4
- data/docs/learn/06-debug.md +6 -9
- data/docs/learn/07-log.md +14 -14
- data/docs/learn/08-readme.md +4 -4
- data/docs/learn/13-include.md +13 -6
- data/docs/learn/14-alias.md +14 -8
- data/docs/learn/README.md +7 -7
- data/lib/teuton/case_manager/case/case.rb +1 -5
- data/lib/teuton/case_manager/case/dsl/expect.rb +2 -4
- data/lib/teuton/case_manager/case/dsl/log.rb +1 -2
- data/lib/teuton/case_manager/case/dsl/send.rb +4 -2
- data/lib/teuton/case_manager/case/play.rb +1 -2
- data/lib/teuton/case_manager/case/runner.rb +6 -7
- data/lib/teuton/case_manager/case_manager.rb +15 -11
- data/lib/teuton/case_manager/check_cases.rb +5 -7
- data/lib/teuton/case_manager/dsl.rb +9 -3
- data/lib/teuton/case_manager/export_manager.rb +13 -15
- data/lib/teuton/case_manager/hall_of_fame.rb +20 -16
- data/lib/teuton/case_manager/main.rb +1 -2
- data/lib/teuton/case_manager/report.rb +3 -3
- data/lib/teuton/report/formatter/base_formatter.rb +6 -7
- data/lib/teuton/report/formatter/{array_formatter.rb → default/array.rb} +44 -9
- data/lib/teuton/report/formatter/default/colored_text.rb +7 -0
- data/lib/teuton/report/formatter/default/html.rb +24 -0
- data/lib/teuton/report/formatter/default/json.rb +15 -0
- data/lib/teuton/report/formatter/{txt_formatter.rb → default/txt.rb} +4 -3
- data/lib/teuton/report/formatter/{xml_formatter.rb → default/xml.rb} +10 -4
- data/lib/teuton/report/formatter/default/yaml.rb +15 -0
- data/lib/teuton/report/formatter/formatter.rb +54 -0
- data/lib/teuton/report/formatter/moodle_csv_formatter.rb +4 -10
- data/lib/teuton/report/formatter/{resume_array_formatter.rb → resume/array.rb} +4 -7
- data/lib/teuton/report/formatter/resume/colored_text.rb +7 -0
- data/lib/teuton/report/formatter/{resume_html_formatter.rb → resume/html.rb} +7 -9
- data/lib/teuton/report/formatter/{resume_json_formatter.rb → resume/json.rb} +4 -4
- data/lib/teuton/report/formatter/{resume_txt_formatter.rb → resume/txt.rb} +4 -6
- data/lib/teuton/report/formatter/{resume_yaml_formatter.rb → resume/yaml.rb} +4 -3
- data/lib/teuton/report/report.rb +60 -43
- data/lib/teuton/report/show.rb +38 -24
- data/lib/teuton/version.rb +1 -1
- metadata +33 -34
- data/lib/teuton/case_manager/show.rb +0 -24
- data/lib/teuton/report/close.rb +0 -38
- data/lib/teuton/report/formatter/csv_formatter.rb +0 -25
- data/lib/teuton/report/formatter/formatter_factory.rb +0 -79
- data/lib/teuton/report/formatter/html_formatter.rb +0 -57
- data/lib/teuton/report/formatter/json_formatter.rb +0 -12
- data/lib/teuton/report/formatter/list_formatter.rb +0 -65
- data/lib/teuton/report/formatter/resume_list_formatter.rb +0 -62
- data/lib/teuton/report/formatter/yaml_formatter.rb +0 -15
data/docs/learn/08-readme.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
[<< back](README.md)
|
2
2
|
|
3
|
-
# Example:
|
3
|
+
# Example: readme
|
4
4
|
|
5
5
|
Create README files (with test instructions) from our test definition.
|
6
6
|
|
@@ -35,15 +35,15 @@ There exists some `readme` instructions after `group` and `target` lines.
|
|
35
35
|
To generate automatically a README file from previous test, execute this:
|
36
36
|
|
37
37
|
```
|
38
|
-
teuton readme example/
|
38
|
+
teuton readme example/08-readme > example/08-readme/README.md
|
39
39
|
```
|
40
40
|
|
41
41
|
## Result
|
42
42
|
|
43
|
-
**Let's see the output**: Content of `example/
|
43
|
+
**Let's see the output**: Content of `example/08-readme/README.md` file.
|
44
44
|
|
45
45
|
---
|
46
|
-
#
|
46
|
+
# 08-readme
|
47
47
|
|
48
48
|
## Customize readme output
|
49
49
|
|
data/docs/learn/13-include.md
CHANGED
@@ -2,13 +2,17 @@
|
|
2
2
|
|
3
3
|
# Example: 13-include
|
4
4
|
|
5
|
-
|
5
|
+
Use `tt-include` to include several config files into your main config file.
|
6
|
+
|
7
|
+
## Explanation
|
8
|
+
|
9
|
+
Until now, all the examples we have seen use one configuration file (`config.yaml`) that contain all the parameters required by the test. It is possible to save configuration distributed among several files.
|
6
10
|
|
7
11
|
Suppose we have the following file structure.
|
8
12
|
|
9
13
|
```
|
10
14
|
├── config.yaml
|
11
|
-
├──
|
15
|
+
├── moreconfigfiles
|
12
16
|
│ ├── 02
|
13
17
|
│ │ └── file02.yaml
|
14
18
|
│ ├── file01.yaml
|
@@ -16,15 +20,15 @@ Suppose we have the following file structure.
|
|
16
20
|
└── start.rb
|
17
21
|
```
|
18
22
|
|
19
|
-
`config.yaml` will be the main config file.
|
23
|
+
`config.yaml` will be the main config file. We have defined `tt_include` parameter with a folder wich contains more configuration files.
|
20
24
|
|
21
|
-
In this example the contents of
|
25
|
+
In this example the contents of all files in `moreconfigfiles` folder will be included when reading the config parameters:
|
22
26
|
|
23
27
|
```yaml
|
24
28
|
---
|
25
29
|
# Fiel: config.yaml
|
26
30
|
:global:
|
27
|
-
:tt_include:
|
31
|
+
:tt_include: moreconfigfiles
|
28
32
|
:cases:
|
29
33
|
```
|
30
34
|
|
@@ -41,19 +45,22 @@ CASE RESULTS
|
|
41
45
|
+------+---------+-------+-------+
|
42
46
|
```
|
43
47
|
|
44
|
-
Config files into `
|
48
|
+
Config files into `moreconfigfiles` folder:
|
45
49
|
|
46
50
|
```yaml
|
51
|
+
# moreconfigfiles/file01.yaml
|
47
52
|
:tt_members: file01
|
48
53
|
:username: root
|
49
54
|
```
|
50
55
|
|
51
56
|
```yaml
|
57
|
+
# moreconfigfiles/02/file02.yaml
|
52
58
|
:tt_members: file02
|
53
59
|
:username: quigon
|
54
60
|
```
|
55
61
|
|
56
62
|
```yaml
|
63
|
+
# moreconfigfiles/file03.yml
|
57
64
|
:tt_members: file03
|
58
65
|
:username: vader
|
59
66
|
```
|
data/docs/learn/14-alias.md
CHANGED
@@ -2,7 +2,11 @@
|
|
2
2
|
|
3
3
|
# Example: 14-alias
|
4
4
|
|
5
|
-
|
5
|
+
By using aliases we can adapt a configuration file, so that it can be used with many different tests.
|
6
|
+
|
7
|
+
## Exanation
|
8
|
+
|
9
|
+
Suppose we have a test like the following:
|
6
10
|
|
7
11
|
```ruby
|
8
12
|
group "Using alias" do
|
@@ -16,14 +20,14 @@ group "Using alias" do
|
|
16
20
|
end
|
17
21
|
```
|
18
22
|
|
19
|
-
|
23
|
+
> REMEMBER:
|
24
|
+
> * We only have 2 targets but we could have many more.
|
25
|
+
> * `_username` is equivalent to `get(:username)`
|
20
26
|
|
21
|
-
|
22
|
-
|
23
|
-
Sabemos que el fichero de configuración debe definir los valores para los parámetros `super` y `username`. Queremos aprovechar un fichero de configuración que ya teníamos de otro test, pero tiene el siguiente contenido:
|
27
|
+
Our test requires the `super` parameter but the configuration file has named it as `superuser`. Our configuration file define values for `supername` and `username` parameters. Let's see:
|
24
28
|
|
25
29
|
```yaml
|
26
|
-
#
|
30
|
+
# First version
|
27
31
|
# File: config.yaml
|
28
32
|
global:
|
29
33
|
cases:
|
@@ -32,10 +36,10 @@ cases:
|
|
32
36
|
username: obiwan
|
33
37
|
```
|
34
38
|
|
35
|
-
|
39
|
+
We would like to take advantage of a configuration file that we already had from another test, without big changes. So we add an `alias`:
|
36
40
|
|
37
41
|
```yaml
|
38
|
-
# Version
|
42
|
+
# Alias Version
|
39
43
|
# File: config.yaml
|
40
44
|
alias:
|
41
45
|
super: :superuser
|
@@ -45,3 +49,5 @@ cases:
|
|
45
49
|
superuser: root
|
46
50
|
username: obiwan
|
47
51
|
```
|
52
|
+
|
53
|
+
Now our test will work correctly. Calling `get(:super)` will return the same value as doing `get(:superuser).
|
data/docs/learn/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
|
2
2
|
[<< back](../../README.md)
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
* [Learning](#learning)
|
5
|
+
* [Examples](#examples)
|
6
|
+
* [Videos](#videos)
|
7
7
|
|
8
8
|
# Learning
|
9
9
|
|
@@ -21,16 +21,16 @@ Learn how to use Teuton language to write your own tests:
|
|
21
21
|
- [11 - Moodle ID](11-moodle_id.md)
|
22
22
|
- [12 - Get vars](12-get_vars.md)
|
23
23
|
- [13 - Include](13-include.md)
|
24
|
-
-
|
25
|
-
-
|
26
|
-
- [
|
24
|
+
- [14 - Alias](14-alias.md)
|
25
|
+
- 15 - Macros
|
26
|
+
- [16 - Exit codes](16-exit_codes.md)
|
27
27
|
- [Videos](videos.md)
|
28
28
|
|
29
29
|
# Examples
|
30
30
|
|
31
31
|
More examples
|
32
32
|
* Let's see examples at [teuton-tests](https://github.com/dvarrui/teuton-tests) GitHub repository.
|
33
|
-
* Ask us by email at `teuton.software@protonmail.com
|
33
|
+
* Ask us by email at `teuton.software@protonmail.com`.
|
34
34
|
* [ES - CHAPI19: Teuton demo](https://github.com/dvarrui/proyectos-de-ejemplo/tree/master/charlas/teuton)
|
35
35
|
|
36
36
|
# Videos
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require_relative "../../application"
|
4
4
|
require_relative "../../report/report"
|
5
|
+
require_relative "../../report/show"
|
5
6
|
require_relative "../utils"
|
6
7
|
require_relative "main"
|
7
8
|
require_relative "result/result"
|
@@ -17,7 +18,6 @@ require_relative "builtin/main"
|
|
17
18
|
# * grade
|
18
19
|
# * members
|
19
20
|
# * skip
|
20
|
-
# * show
|
21
21
|
# * read_filename ???
|
22
22
|
class Case
|
23
23
|
include DSL
|
@@ -100,10 +100,6 @@ class Case
|
|
100
100
|
|
101
101
|
alias skip? skip
|
102
102
|
|
103
|
-
def show
|
104
|
-
@report.show
|
105
|
-
end
|
106
|
-
|
107
103
|
private
|
108
104
|
|
109
105
|
def read_filename(filename)
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "colorize"
|
4
|
-
|
5
3
|
module DSL
|
6
4
|
# expect <condition>, :weight => <value>
|
7
5
|
def expect(input, args = {})
|
@@ -10,7 +8,7 @@ module DSL
|
|
10
8
|
elsif input.instance_of?(String) || input.instance_of?(Regexp) || input.instance_of?(Array)
|
11
9
|
expect_any input
|
12
10
|
else
|
13
|
-
puts "[TypeError] expect #{input} (#{input.class})"
|
11
|
+
puts Rainbow("[TypeError] expect #{input} (#{input.class})").red
|
14
12
|
end
|
15
13
|
end
|
16
14
|
|
@@ -30,7 +28,7 @@ module DSL
|
|
30
28
|
app = Application.instance
|
31
29
|
c = app.letter[:bad]
|
32
30
|
c = app.letter[:good] if cond
|
33
|
-
verbose c.
|
31
|
+
verbose Rainbow(c).green
|
34
32
|
end
|
35
33
|
|
36
34
|
def expect_any(input, args = {})
|
@@ -37,9 +37,11 @@ module DSL
|
|
37
37
|
Net::SFTP.start(ip, username, password: password, port: port) do |sftp|
|
38
38
|
sftp.upload!(localfilepath, remotefilepath)
|
39
39
|
end
|
40
|
-
|
40
|
+
msg = Rainbow("[ OK ] #{(get(:tt_members)[0, 15]).ljust(16)} : #{remotefilepath}").green
|
41
|
+
verboseln(msg)
|
41
42
|
rescue
|
42
|
-
|
43
|
+
msg = Rainbow("[ERROR] #{(get(:tt_members)[0, 15]).ljust(16)} : scp #{localfilepath} => #{remotefilepath}").red
|
44
|
+
verboseln(msg)
|
43
45
|
end
|
44
46
|
end
|
45
47
|
|
@@ -9,10 +9,9 @@
|
|
9
9
|
class Case
|
10
10
|
def play
|
11
11
|
if skip?
|
12
|
-
verbose "
|
12
|
+
verbose Rainbow("S").green
|
13
13
|
return false
|
14
14
|
end
|
15
|
-
# TODO: Delete old reports???
|
16
15
|
start_time = Time.now
|
17
16
|
if get(:tt_sequence) == true
|
18
17
|
play_in_sequence
|
@@ -11,11 +11,14 @@ class Case
|
|
11
11
|
ip = @config.get("#{host}_ip".to_sym)
|
12
12
|
|
13
13
|
if protocol.to_s.downcase == "local" || host.to_s == "localhost"
|
14
|
-
|
14
|
+
# Protocol force => local
|
15
|
+
run_cmd_localhost
|
15
16
|
elsif protocol.to_s.downcase == "ssh"
|
16
|
-
|
17
|
+
# Protocol force => ssh
|
18
|
+
run_cmd_remote_ssh(host)
|
17
19
|
elsif protocol.to_s.downcase == "telnet"
|
18
|
-
|
20
|
+
# Protocol force => telnet
|
21
|
+
run_cmd_remote_telnet(host)
|
19
22
|
elsif ip.to_s.downcase == "localhost" || ip.to_s.include?("127.0.0.")
|
20
23
|
run_cmd_localhost
|
21
24
|
elsif ip == "NODATA"
|
@@ -101,17 +104,14 @@ class Case
|
|
101
104
|
rescue Errno::EHOSTUNREACH
|
102
105
|
@sessions[hostname] = :nosession
|
103
106
|
@conn_status[hostname] = :host_unreachable
|
104
|
-
verbose Rainbow(Application.instance.letter[:error]).red.bright
|
105
107
|
log("Host #{ip} unreachable!", :error)
|
106
108
|
rescue Net::SSH::AuthenticationFailed
|
107
109
|
@sessions[hostname] = :nosession
|
108
110
|
@conn_status[hostname] = :error_authentication_failed
|
109
|
-
verbose Rainbow(Application.instance.letter[:error]).red.bright
|
110
111
|
log("SSH::AuthenticationFailed!", :error)
|
111
112
|
rescue Net::SSH::HostKeyMismatch
|
112
113
|
@sessions[hostname] = :nosession
|
113
114
|
@conn_status[hostname] = :host_key_mismatch
|
114
|
-
verbose Rainbow(Application.instance.letter[:error]).red.bright
|
115
115
|
log("SSH::HostKeyMismatch!", :error)
|
116
116
|
log("* The destination server's fingerprint is not matching " \
|
117
117
|
"what is in your local known_hosts file.", :error)
|
@@ -121,7 +121,6 @@ class Case
|
|
121
121
|
rescue => e
|
122
122
|
@sessions[hostname] = :nosession
|
123
123
|
@conn_status[hostname] = :error
|
124
|
-
verbose Rainbow(Application.instance.letter[:error]).red.bright
|
125
124
|
log("[#{e.class}] SSH on <#{username}@#{ip}>" \
|
126
125
|
" exec: #{@action[:command]}", :error)
|
127
126
|
end
|
@@ -1,13 +1,12 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require "rainbow"
|
3
2
|
require "singleton"
|
4
3
|
require_relative "../application"
|
5
4
|
require_relative "../report/report"
|
5
|
+
require_relative "../report/show"
|
6
6
|
require_relative "../utils/configfile_reader"
|
7
7
|
require_relative "case/case"
|
8
8
|
require_relative "export_manager"
|
9
9
|
require_relative "main"
|
10
|
-
require_relative "utils"
|
11
10
|
|
12
11
|
# This class does all the job
|
13
12
|
# Organize the hole job, sending orders to others classes
|
@@ -18,13 +17,11 @@ require_relative "utils"
|
|
18
17
|
# * case_manager/export
|
19
18
|
# * case_manager/hall_of_fame
|
20
19
|
# * case_manager/report
|
21
|
-
# * case_manager/show
|
22
20
|
class CaseManager
|
23
21
|
include Singleton
|
24
22
|
include Utils
|
23
|
+
attr_reader :report, :cases
|
25
24
|
|
26
|
-
##
|
27
|
-
# Initialize CaseManager
|
28
25
|
def initialize
|
29
26
|
@cases = []
|
30
27
|
@report = Report.new(0)
|
@@ -50,12 +47,11 @@ class CaseManager
|
|
50
47
|
# @param args (Hash) Export options
|
51
48
|
def export(args = {})
|
52
49
|
if args.class != Hash
|
53
|
-
puts "[ERROR] CaseManager#export: Argument
|
54
|
-
|
55
|
-
puts "
|
50
|
+
puts "[ERROR] CaseManager#export: Argument error!"
|
51
|
+
puts " Source : export #{args} <#{args.class}>"
|
52
|
+
puts " Usage : export format: 'txt'"
|
56
53
|
raise "[ERROR] CaseManager#export: Argument error!"
|
57
54
|
end
|
58
|
-
# Export report files
|
59
55
|
ExportManager.run(@report, @cases, args)
|
60
56
|
end
|
61
57
|
|
@@ -65,8 +61,16 @@ class CaseManager
|
|
65
61
|
def send(args = {})
|
66
62
|
threads = []
|
67
63
|
puts ""
|
68
|
-
puts "
|
64
|
+
# puts Rainbow("-" * 50).green
|
65
|
+
puts Rainbow("[INFO] Sending files...#{args}").color(:green)
|
69
66
|
@cases.each { |c| threads << Thread.new { c.send(args) } }
|
70
67
|
threads.each(&:join)
|
68
|
+
puts Rainbow("[INFO] Finished").color(:green)
|
69
|
+
# puts Rainbow("-" * 50).green
|
70
|
+
end
|
71
|
+
|
72
|
+
def show(options = {verbose: 1})
|
73
|
+
verbose = options[:verbose]
|
74
|
+
ShowReport.new(@report).call(verbose)
|
71
75
|
end
|
72
76
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require_relative "hall_of_fame"
|
2
2
|
|
3
3
|
class CaseManager
|
4
4
|
private
|
@@ -32,18 +32,16 @@ class CaseManager
|
|
32
32
|
close_main_report(start_time)
|
33
33
|
end
|
34
34
|
|
35
|
-
##
|
36
|
-
# Run all cases
|
37
35
|
def run_all_cases
|
38
36
|
start_time = Time.now
|
37
|
+
verboseln Rainbow("-" * 36).green
|
38
|
+
verboseln Rainbow("Started at #{start_time}").green
|
39
39
|
if Application.instance.global[:tt_sequence] == true
|
40
|
-
verboseln Rainbow("==> Teuton: Running in sequence (#{start_time})").yellow.bright
|
41
40
|
# Run every case in sequence
|
42
41
|
@cases.each(&:play)
|
43
42
|
else
|
44
|
-
verboseln Rainbow("==> Teuton: Running in parallel (#{start_time})").yellow.bright
|
45
|
-
threads = []
|
46
43
|
# Run all cases in parallel
|
44
|
+
threads = []
|
47
45
|
@cases.each { |c| threads << Thread.new { c.play } }
|
48
46
|
threads.each(&:join)
|
49
47
|
end
|
@@ -75,6 +73,6 @@ class CaseManager
|
|
75
73
|
@cases.each { |c| threads << Thread.new { c.close uniques } }
|
76
74
|
threads.each(&:join)
|
77
75
|
|
78
|
-
|
76
|
+
HallOfFame.new(@cases).call
|
79
77
|
end
|
80
78
|
end
|
@@ -8,8 +8,14 @@ def use(filename)
|
|
8
8
|
files = Dir.glob(rbfiles)
|
9
9
|
findfiles = []
|
10
10
|
files.sort.each { |f| findfiles << f if f.include?(filename) }
|
11
|
-
|
12
|
-
|
11
|
+
begin
|
12
|
+
require_relative findfiles.first
|
13
|
+
app.uses << File.basename(findfiles.first)
|
14
|
+
rescue
|
15
|
+
puts "[ERROR] Unknown file : #{filename}"
|
16
|
+
puts " Check line : use '#{filename}'"
|
17
|
+
exit 1
|
18
|
+
end
|
13
19
|
end
|
14
20
|
|
15
21
|
def define_macro(name, *args, &block)
|
@@ -18,7 +24,7 @@ end
|
|
18
24
|
alias def_macro define_macro
|
19
25
|
alias defmacro define_macro
|
20
26
|
|
21
|
-
# Define a group of
|
27
|
+
# Define a group of [target/run/expect]s
|
22
28
|
# @param name (String) Group name
|
23
29
|
# @param block (Block) Tests code
|
24
30
|
def group(name, &block)
|
@@ -8,22 +8,22 @@ module ExportManager
|
|
8
8
|
# @param main_report (Report)
|
9
9
|
# @param cases (Array)
|
10
10
|
# @param input (Hash) Selected export options
|
11
|
-
def self.run(main_report, cases,
|
12
|
-
|
11
|
+
def self.run(main_report, cases, args)
|
12
|
+
options = strings2symbols(args)
|
13
|
+
if options[:format].nil?
|
14
|
+
options[:format] = Application.instance.default[:format]
|
15
|
+
end
|
13
16
|
|
14
|
-
# default :mode=>:all, :format=>:txt
|
15
|
-
format = args[:format] || Application.instance.default[:format]
|
16
|
-
mode = args[:mode] || :all
|
17
17
|
# Step 1: Export case reports
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
end
|
18
|
+
threads = []
|
19
|
+
cases.each { |c| threads << Thread.new { c.export(options) } }
|
20
|
+
threads.each(&:join)
|
21
|
+
|
23
22
|
# Step 2: Export resume report
|
24
|
-
main_report.export_resume
|
23
|
+
main_report.export_resume(options)
|
24
|
+
|
25
25
|
# Step 3: Preserve files if required
|
26
|
-
preserve_files if
|
26
|
+
preserve_files if options[:preserve] == true
|
27
27
|
end
|
28
28
|
|
29
29
|
##
|
@@ -42,7 +42,7 @@ module ExportManager
|
|
42
42
|
end
|
43
43
|
|
44
44
|
##
|
45
|
-
# Preserve output files for current project
|
45
|
+
# Preserve output files for current project execution
|
46
46
|
private_class_method def self.preserve_files
|
47
47
|
app = Application.instance
|
48
48
|
t = Time.now
|
@@ -55,6 +55,4 @@ module ExportManager
|
|
55
55
|
FileUtils.mkdir(logdir)
|
56
56
|
Dir.glob(File.join(srcdir, "**.*")).each { |file| FileUtils.cp(file, logdir) }
|
57
57
|
end
|
58
|
-
# rubocop:enable Metrics/AbcSize
|
59
|
-
# rubocop:enable Metrics/MethodLength
|
60
58
|
end
|
@@ -1,26 +1,30 @@
|
|
1
1
|
require_relative "../application"
|
2
2
|
|
3
3
|
class CaseManager
|
4
|
-
|
4
|
+
class HallOfFame
|
5
|
+
def initialize(cases)
|
6
|
+
@cases = cases
|
7
|
+
end
|
5
8
|
|
6
|
-
|
7
|
-
|
9
|
+
def call
|
10
|
+
celebrities = {}
|
8
11
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
@cases.each do |c|
|
13
|
+
grade = c.grade # report.tail[:grade]
|
14
|
+
label = if celebrities[grade]
|
15
|
+
celebrities[grade] + "*"
|
16
|
+
else
|
17
|
+
"*"
|
18
|
+
end
|
19
|
+
celebrities[grade] = label unless c.skip
|
15
20
|
end
|
16
|
-
celebrities[grade] = label unless c.skip
|
17
|
-
end
|
18
21
|
|
19
|
-
|
20
|
-
|
22
|
+
a = celebrities.sort_by { |key, _value| key }
|
23
|
+
list = a.reverse
|
21
24
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
+
app = Application.instance
|
26
|
+
app.options[:case_number] = @cases.size
|
27
|
+
app.hall_of_fame = list
|
28
|
+
end
|
25
29
|
end
|
26
30
|
end
|
@@ -25,8 +25,8 @@ class CaseManager
|
|
25
25
|
@report.tail[:duration] = finish_time - start_time
|
26
26
|
|
27
27
|
duration = format("%3.3f", (finish_time - start_time))
|
28
|
-
|
29
|
-
verboseln Rainbow("
|
28
|
+
verboseln Rainbow("\nFinished in #{duration} seconds").green
|
29
|
+
verboseln Rainbow("-" * 36).green
|
30
30
|
verboseln " "
|
31
31
|
|
32
32
|
app = Application.instance
|
@@ -37,7 +37,7 @@ class CaseManager
|
|
37
37
|
skip: true,
|
38
38
|
id: "-",
|
39
39
|
grade: 0.0,
|
40
|
-
letter: "",
|
40
|
+
letter: "S",
|
41
41
|
members: "-",
|
42
42
|
conn_status: {},
|
43
43
|
moodle_id: "",
|
@@ -1,18 +1,17 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
class BaseFormatter
|
4
2
|
def initialize(report)
|
5
|
-
@head = report.head
|
6
|
-
@lines = report.lines
|
7
|
-
@tail = report.tail
|
3
|
+
@head = report.head.clone
|
4
|
+
@lines = report.lines.clone
|
5
|
+
@tail = report.tail.clone
|
6
|
+
@ext = "unkown"
|
8
7
|
end
|
9
8
|
|
10
|
-
def process
|
9
|
+
def process(options = {})
|
11
10
|
raise "Empty method!"
|
12
11
|
end
|
13
12
|
|
14
13
|
def init(filename)
|
15
|
-
@filename = filename
|
14
|
+
@filename = "#{filename}.#{@ext}"
|
16
15
|
@file = File.open(@filename, "w")
|
17
16
|
end
|
18
17
|
|