teuton 2.3.11 → 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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +44 -13
  3. data/docs/CHANGELOG.md +0 -13
  4. data/docs/changelog/todo.md +18 -0
  5. data/docs/changelog/v2.4.md +6 -2
  6. data/docs/dsl/execution/export.md +9 -15
  7. data/docs/dsl/execution/show.md +22 -7
  8. data/docs/ideas/{ideas.md → todo.md} +8 -16
  9. data/docs/learn/01-target.md +14 -43
  10. data/docs/learn/02-config.md +20 -37
  11. data/docs/learn/03-remote_hosts.md +20 -1
  12. data/docs/learn/04-new_test.md +4 -4
  13. data/docs/learn/05-use.md +3 -4
  14. data/docs/learn/06-debug.md +6 -9
  15. data/docs/learn/07-log.md +14 -14
  16. data/docs/learn/08-readme.md +4 -4
  17. data/docs/learn/13-include.md +13 -6
  18. data/docs/learn/14-alias.md +14 -8
  19. data/docs/learn/README.md +7 -7
  20. data/lib/teuton/case_manager/case/case.rb +1 -5
  21. data/lib/teuton/case_manager/case/dsl/expect.rb +2 -4
  22. data/lib/teuton/case_manager/case/dsl/log.rb +1 -2
  23. data/lib/teuton/case_manager/case/dsl/send.rb +4 -2
  24. data/lib/teuton/case_manager/case/play.rb +1 -2
  25. data/lib/teuton/case_manager/case/runner.rb +6 -7
  26. data/lib/teuton/case_manager/case_manager.rb +15 -11
  27. data/lib/teuton/case_manager/check_cases.rb +5 -7
  28. data/lib/teuton/case_manager/dsl.rb +1 -1
  29. data/lib/teuton/case_manager/export_manager.rb +13 -15
  30. data/lib/teuton/case_manager/hall_of_fame.rb +20 -16
  31. data/lib/teuton/case_manager/main.rb +1 -2
  32. data/lib/teuton/case_manager/report.rb +3 -3
  33. data/lib/teuton/report/formatter/base_formatter.rb +6 -7
  34. data/lib/teuton/report/formatter/{array_formatter.rb → default/array.rb} +44 -9
  35. data/lib/teuton/report/formatter/default/colored_text.rb +7 -0
  36. data/lib/teuton/report/formatter/default/html.rb +24 -0
  37. data/lib/teuton/report/formatter/default/json.rb +15 -0
  38. data/lib/teuton/report/formatter/{txt_formatter.rb → default/txt.rb} +4 -3
  39. data/lib/teuton/report/formatter/{xml_formatter.rb → default/xml.rb} +10 -4
  40. data/lib/teuton/report/formatter/default/yaml.rb +15 -0
  41. data/lib/teuton/report/formatter/formatter.rb +54 -0
  42. data/lib/teuton/report/formatter/moodle_csv_formatter.rb +4 -10
  43. data/lib/teuton/report/formatter/{resume_array_formatter.rb → resume/array.rb} +4 -7
  44. data/lib/teuton/report/formatter/resume/colored_text.rb +7 -0
  45. data/lib/teuton/report/formatter/{resume_html_formatter.rb → resume/html.rb} +7 -9
  46. data/lib/teuton/report/formatter/{resume_json_formatter.rb → resume/json.rb} +4 -4
  47. data/lib/teuton/report/formatter/{resume_txt_formatter.rb → resume/txt.rb} +4 -6
  48. data/lib/teuton/report/formatter/{resume_yaml_formatter.rb → resume/yaml.rb} +4 -3
  49. data/lib/teuton/report/report.rb +60 -43
  50. data/lib/teuton/report/show.rb +38 -24
  51. data/lib/teuton/version.rb +1 -1
  52. metadata +32 -33
  53. data/lib/teuton/case_manager/show.rb +0 -24
  54. data/lib/teuton/report/close.rb +0 -38
  55. data/lib/teuton/report/formatter/csv_formatter.rb +0 -25
  56. data/lib/teuton/report/formatter/formatter_factory.rb +0 -79
  57. data/lib/teuton/report/formatter/html_formatter.rb +0 -57
  58. data/lib/teuton/report/formatter/json_formatter.rb +0 -12
  59. data/lib/teuton/report/formatter/list_formatter.rb +0 -65
  60. data/lib/teuton/report/formatter/resume_list_formatter.rb +0 -62
  61. data/lib/teuton/report/formatter/yaml_formatter.rb +0 -15
@@ -1,6 +1,6 @@
1
1
  [<< back](README.md)
2
2
 
3
- # Example: 07-readme
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/learn-08-readme > example/learn-08-readme/README.md
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/learn-08-readme/README.md` file.
43
+ **Let's see the output**: Content of `example/08-readme/README.md` file.
44
44
 
45
45
  ---
46
- # learn-08-readme
46
+ # 08-readme
47
47
 
48
48
  ## Customize readme output
49
49
 
@@ -2,13 +2,17 @@
2
2
 
3
3
  # Example: 13-include
4
4
 
5
- Until now, all the tests we have seen came with a configuration file (`config.yaml`) that contained all the parameters that will later be used in the test. It is also possible to have the information distributed among several configuration files.
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
- ├── include_this_files
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. Using `tt_include` parameter, we define a folder where the rest of the configuration files will be.
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 the files in the include_this_files folder will be included in the configuration:
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: include_this_files
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 `include_this_files` folder:
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
  ```
@@ -2,7 +2,11 @@
2
2
 
3
3
  # Example: 14-alias
4
4
 
5
- Supongamos que tenemos un test como el siguiente:
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
- Tenemos sólo 2 targets pero podríamos tener muchos más.
23
+ > REMEMBER:
24
+ > * We only have 2 targets but we could have many more.
25
+ > * `_username` is equivalent to `get(:username)`
20
26
 
21
- > Recordemos que `_username` es equivalente a `get(:username)`
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
- # Version 1
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
- Podemos comprobar que nuestro test require el parámetro `super` pero el fichero de configuración lo ha nombrado como `superuser`.
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 2
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
- 1. [Learning](#learning)
5
- 2. [Examples](#examples)
6
- 3. [Videos](#videos)
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
- - Example 14 - Alias
25
- - Example 15 - Macros
26
- - [Example 16 - Exit codes](16-exit_codes.md)
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` or Twitter at `@SoftwareTeuton`.
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.colorize(:green)
31
+ verbose Rainbow(c).green
34
32
  end
35
33
 
36
34
  def expect_any(input, args = {})
@@ -1,5 +1,4 @@
1
- # frozen_string_literal: true
2
-
1
+ require "rainbow"
3
2
  ##
4
3
  # Define DSL#log function
5
4
  module DSL
@@ -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
- verboseln("=> [ OK ] #{(get(:tt_members)[0, 15]).ljust(16)} : #{remotefilepath}")
40
+ msg = Rainbow("[ OK ] #{(get(:tt_members)[0, 15]).ljust(16)} : #{remotefilepath}").green
41
+ verboseln(msg)
41
42
  rescue
42
- verboseln("=> [ERROR] #{(get(:tt_members)[0, 15]).ljust(16)} : scp #{localfilepath} => #{remotefilepath}")
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 "Skipping case <#{@config.get(:tt_members)}>\n"
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
- run_cmd_localhost # Protocol force => local
14
+ # Protocol force => local
15
+ run_cmd_localhost
15
16
  elsif protocol.to_s.downcase == "ssh"
16
- run_cmd_remote_ssh(host) # Protocol force => ssh
17
+ # Protocol force => ssh
18
+ run_cmd_remote_ssh(host)
17
19
  elsif protocol.to_s.downcase == "telnet"
18
- run_cmd_remote_telnet(host) # Protocol force => telnet
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
- # frozen_string_literal: true
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 = <#{args}>, " \
54
- "class = #{args.class}"
55
- puts " Usage: export :format => :colored_text"
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 "[INFO] Sending files...#{args}"
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
- # frozen_string_literal: true
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
- build_hall_of_fame
76
+ HallOfFame.new(@cases).call
79
77
  end
80
78
  end
@@ -24,7 +24,7 @@ end
24
24
  alias def_macro define_macro
25
25
  alias defmacro define_macro
26
26
 
27
- # Define a group of tests
27
+ # Define a group of [target/run/expect]s
28
28
  # @param name (String) Group name
29
29
  # @param block (Block) Tests code
30
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, input)
12
- args = strings2symbols(input)
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
- if %i[details all].include? mode
19
- threads = []
20
- cases.each { |c| threads << Thread.new { c.export format } }
21
- threads.each(&:join)
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 format if %i[resume all].include? mode
23
+ main_report.export_resume(options)
24
+
25
25
  # Step 3: Preserve files if required
26
- preserve_files if args[:preserve] == true
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
- private
4
+ class HallOfFame
5
+ def initialize(cases)
6
+ @cases = cases
7
+ end
5
8
 
6
- def build_hall_of_fame
7
- celebrities = {}
9
+ def call
10
+ celebrities = {}
8
11
 
9
- @cases.each do |c|
10
- grade = c.grade # report.tail[:grade]
11
- label = if celebrities[grade]
12
- celebrities[grade] + "*"
13
- else
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
- a = celebrities.sort_by { |key, _value| key }
20
- list = a.reverse
22
+ a = celebrities.sort_by { |key, _value| key }
23
+ list = a.reverse
21
24
 
22
- app = Application.instance
23
- app.options[:case_number] = @cases.size
24
- app.hall_of_fame = list
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
@@ -1,4 +1,3 @@
1
1
  require_relative "check_cases"
2
- require_relative "hall_of_fame"
3
2
  require_relative "report"
4
- require_relative "show"
3
+ require_relative "utils"
@@ -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
- verbose Rainbow("\n==> Teuton: Duration=#{duration}").yellow.bright
29
- verboseln Rainbow(" (#{finish_time})").yellow.bright
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
 
@@ -1,6 +1,5 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "base_formatter"
1
+ require_relative "../base_formatter"
2
+ require_relative "../../../application"
4
3
 
5
4
  class ArrayFormatter < BaseFormatter
6
5
  def initialize(report)
@@ -8,26 +7,28 @@ class ArrayFormatter < BaseFormatter
8
7
  @data = {}
9
8
  end
10
9
 
11
- def process
12
- build_data
10
+ def process(options = {})
11
+ build_data(options)
13
12
  w @data.to_s # Write data into ouput file
14
13
  deinit
15
14
  end
16
15
 
17
- def build_data
16
+ def build_data(options)
18
17
  build_initial_data
19
- build_history_data
18
+ build_history_data(options)
20
19
  build_final_data
21
20
  build_hof_data
22
21
  end
23
22
 
23
+ private
24
+
24
25
  def build_initial_data
25
26
  head = {}
26
27
  @head.each { |key, value| head[key] = value }
27
28
  @data[:config] = head
28
29
  end
29
30
 
30
- def build_history_data
31
+ def build_history_data(options)
31
32
  @data[:logs] = []
32
33
  groups = []
33
34
  title = nil
@@ -54,12 +55,22 @@ class ArrayFormatter < BaseFormatter
54
55
  target[:score] = value
55
56
  target[:weight] = i[:weight]
56
57
  target[:description] = i[:description]
57
- target[:command] = i[:command]
58
+
58
59
  target[:conn_type] = i[:conn_type]
59
60
  target[:duration] = i[:duration]
61
+
62
+ target[:command] = i[:command]
60
63
  target[:alterations] = i[:alterations]
61
64
  target[:expected] = i[:expected]
62
65
  target[:result] = i[:result]
66
+
67
+ if options[:feedback] == false
68
+ target[:command] = "*" * i[:command].size
69
+ target[:alterations] = "*" * i[:alterations].size
70
+ target[:expected] = "*" * i[:expected].size
71
+ target[:result] = "*" * i[:result].size
72
+ end
73
+
63
74
  targets << target
64
75
  end
65
76
 
@@ -82,4 +93,28 @@ class ArrayFormatter < BaseFormatter
82
93
  app.hall_of_fame.each { |line| fame[line[0]] = line[1] }
83
94
  @data[:hall_of_fame] = fame
84
95
  end
96
+
97
+ def config
98
+ @data[:config]
99
+ end
100
+
101
+ def results
102
+ @data[:results]
103
+ end
104
+
105
+ def logs
106
+ @data[:logs]
107
+ end
108
+
109
+ def groups
110
+ @data[:groups]
111
+ end
112
+
113
+ def hall_of_fame
114
+ @data[:hall_of_fame]
115
+ end
116
+
117
+ def version
118
+ Application::VERSION
119
+ end
85
120
  end
@@ -0,0 +1,7 @@
1
+ require_relative "txt"
2
+
3
+ class ColoredTextFormatter < TXTFormatter
4
+ def initialize(report)
5
+ super(report, true)
6
+ end
7
+ end