teuton 2.3.10 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|