teuton 0.0.1
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 +7 -0
- data/bin/teuton +4 -0
- data/lib/teuton/application.rb +53 -0
- data/lib/teuton/case_manager/case/builtin/main.rb +24 -0
- data/lib/teuton/case_manager/case/builtin/package.rb +20 -0
- data/lib/teuton/case_manager/case/builtin/service.rb +32 -0
- data/lib/teuton/case_manager/case/builtin/user.rb +20 -0
- data/lib/teuton/case_manager/case/case.rb +114 -0
- data/lib/teuton/case_manager/case/close.rb +29 -0
- data/lib/teuton/case_manager/case/config.rb +76 -0
- data/lib/teuton/case_manager/case/dsl/check.rb +24 -0
- data/lib/teuton/case_manager/case/dsl/deprecated.rb +14 -0
- data/lib/teuton/case_manager/case/dsl/expect.rb +78 -0
- data/lib/teuton/case_manager/case/dsl/getset.rb +22 -0
- data/lib/teuton/case_manager/case/dsl/goto.rb +35 -0
- data/lib/teuton/case_manager/case/dsl/log.rb +14 -0
- data/lib/teuton/case_manager/case/dsl/main.rb +11 -0
- data/lib/teuton/case_manager/case/dsl/missing.rb +12 -0
- data/lib/teuton/case_manager/case/dsl/send.rb +69 -0
- data/lib/teuton/case_manager/case/dsl/target.rb +16 -0
- data/lib/teuton/case_manager/case/dsl/unique.rb +11 -0
- data/lib/teuton/case_manager/case/main.rb +7 -0
- data/lib/teuton/case_manager/case/play.rb +59 -0
- data/lib/teuton/case_manager/case/result/ext_array.rb +43 -0
- data/lib/teuton/case_manager/case/result/ext_compare.rb +147 -0
- data/lib/teuton/case_manager/case/result/ext_filter.rb +68 -0
- data/lib/teuton/case_manager/case/result/result.rb +73 -0
- data/lib/teuton/case_manager/case/runner.rb +134 -0
- data/lib/teuton/case_manager/case_manager.rb +76 -0
- data/lib/teuton/case_manager/check_cases.rb +73 -0
- data/lib/teuton/case_manager/dsl.rb +31 -0
- data/lib/teuton/case_manager/export_manager.rb +20 -0
- data/lib/teuton/case_manager/hall_of_fame.rb +28 -0
- data/lib/teuton/case_manager/main.rb +6 -0
- data/lib/teuton/case_manager/report.rb +52 -0
- data/lib/teuton/case_manager/show.rb +19 -0
- data/lib/teuton/case_manager/utils.rb +57 -0
- data/lib/teuton/command/create.rb +20 -0
- data/lib/teuton/command/download.rb +26 -0
- data/lib/teuton/command/main.rb +9 -0
- data/lib/teuton/command/play.rb +34 -0
- data/lib/teuton/command/readme.rb +23 -0
- data/lib/teuton/command/test.rb +35 -0
- data/lib/teuton/command/update.rb +27 -0
- data/lib/teuton/command/version.rb +13 -0
- data/lib/teuton/files/start.rb +13 -0
- data/lib/teuton/project/configfile_reader.rb +49 -0
- data/lib/teuton/project/laboratory/builtin.rb +23 -0
- data/lib/teuton/project/laboratory/dsl.rb +117 -0
- data/lib/teuton/project/laboratory/laboratory.rb +55 -0
- data/lib/teuton/project/laboratory/show.rb +161 -0
- data/lib/teuton/project/name_file_finder.rb +129 -0
- data/lib/teuton/project/project.rb +62 -0
- data/lib/teuton/project/project_creator.rb +79 -0
- data/lib/teuton/project/readme/dsl.rb +109 -0
- data/lib/teuton/project/readme/lang.rb +30 -0
- data/lib/teuton/project/readme/readme.rb +156 -0
- data/lib/teuton/rake_function/check.rb +39 -0
- data/lib/teuton/rake_function/install.rb +36 -0
- data/lib/teuton/report/close.rb +34 -0
- data/lib/teuton/report/formatter/array_formatter.rb +84 -0
- data/lib/teuton/report/formatter/base_formatter.rb +33 -0
- data/lib/teuton/report/formatter/csv_formatter.rb +31 -0
- data/lib/teuton/report/formatter/formatter_factory.rb +73 -0
- data/lib/teuton/report/formatter/html_formatter.rb +81 -0
- data/lib/teuton/report/formatter/json_formatter.rb +17 -0
- data/lib/teuton/report/formatter/list_formatter.rb +71 -0
- data/lib/teuton/report/formatter/moodle_csv_formatter.rb +28 -0
- data/lib/teuton/report/formatter/resume_array_formatter.rb +49 -0
- data/lib/teuton/report/formatter/resume_json_formatter.rb +16 -0
- data/lib/teuton/report/formatter/resume_list_formatter.rb +62 -0
- data/lib/teuton/report/formatter/resume_txt_formatter.rb +102 -0
- data/lib/teuton/report/formatter/resume_yaml_formatter.rb +16 -0
- data/lib/teuton/report/formatter/txt_formatter.rb +102 -0
- data/lib/teuton/report/formatter/xml_formatter.rb +42 -0
- data/lib/teuton/report/formatter/yaml_formatter.rb +18 -0
- data/lib/teuton/report/report.rb +55 -0
- data/lib/teuton/report/show.rb +111 -0
- data/lib/teuton/utils/verbose.rb +15 -0
- data/lib/teuton.rb +17 -0
- metadata +263 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../../application'
|
|
4
|
+
require_relative '../configfile_reader'
|
|
5
|
+
require_relative '../../case_manager/case/result/result'
|
|
6
|
+
require_relative 'dsl'
|
|
7
|
+
require_relative 'lang'
|
|
8
|
+
|
|
9
|
+
def use(filename)
|
|
10
|
+
filename += '.rb'
|
|
11
|
+
app = Application.instance
|
|
12
|
+
rbfiles = File.join(app.project_path, '**', filename)
|
|
13
|
+
files = Dir.glob(rbfiles)
|
|
14
|
+
use = []
|
|
15
|
+
files.sort.each { |f| use << f if f.include?(filename) }
|
|
16
|
+
require_relative use[0]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def group(name, &block)
|
|
20
|
+
Application.instance.groups << { name: name, block: block }
|
|
21
|
+
end
|
|
22
|
+
alias task group
|
|
23
|
+
|
|
24
|
+
def start(&block)
|
|
25
|
+
# don't do nothing
|
|
26
|
+
end
|
|
27
|
+
alias play start
|
|
28
|
+
|
|
29
|
+
# Creates README.md file from RB script file
|
|
30
|
+
class Readme
|
|
31
|
+
attr_reader :result
|
|
32
|
+
attr_reader :data
|
|
33
|
+
|
|
34
|
+
def initialize(script_path, config_path)
|
|
35
|
+
@path = {}
|
|
36
|
+
@path[:script] = script_path
|
|
37
|
+
@path[:dirname] = File.dirname(script_path)
|
|
38
|
+
@path[:filename] = File.basename(script_path, '.rb')
|
|
39
|
+
@path[:config] = config_path
|
|
40
|
+
reset
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def reset
|
|
44
|
+
app = Application.instance
|
|
45
|
+
@config = ConfigFileReader.read(app.config_path)
|
|
46
|
+
@verbose = app.verbose
|
|
47
|
+
@result = Result.new
|
|
48
|
+
@data = {}
|
|
49
|
+
@data[:logs] = []
|
|
50
|
+
@data[:groups] = []
|
|
51
|
+
@data[:play] = []
|
|
52
|
+
reset_action
|
|
53
|
+
@setted_params = {}
|
|
54
|
+
@cases_params = []
|
|
55
|
+
@global_params = {}
|
|
56
|
+
@required_hosts = {}
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def process_content
|
|
60
|
+
Application.instance.groups.each do |g|
|
|
61
|
+
@current = { name: g[:name], readme: [], actions: [] }
|
|
62
|
+
@data[:groups] << @current
|
|
63
|
+
reset_action
|
|
64
|
+
instance_eval(&g[:block])
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def reset_action
|
|
69
|
+
@action = { readme: [] }
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def show
|
|
73
|
+
process_content
|
|
74
|
+
show_head
|
|
75
|
+
show_content
|
|
76
|
+
show_tail
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def show_content
|
|
80
|
+
@data[:groups].each do |group|
|
|
81
|
+
next if group[:actions].empty?
|
|
82
|
+
|
|
83
|
+
puts "\n## #{group[:name]}\n\n"
|
|
84
|
+
group[:readme].each { |line| puts "#{line}\n" }
|
|
85
|
+
previous_host = nil
|
|
86
|
+
group[:actions].each_with_index do |item, index|
|
|
87
|
+
if item[:host].nil? && index.positive?
|
|
88
|
+
item[:host] = group[:actions][0][:host]
|
|
89
|
+
end
|
|
90
|
+
if previous_host.nil? || item[:host] != previous_host
|
|
91
|
+
previous_host = item[:host] || 'null'
|
|
92
|
+
puts format(Lang::get(:goto), previous_host.upcase)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
weight = ''
|
|
96
|
+
weight = "(x#{item[:weight]}) " if item[:weight] != 1.0
|
|
97
|
+
puts "* #{weight}#{item[:target]}"
|
|
98
|
+
item[:readme].each { |line| puts " * #{line}\n" }
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def show_head
|
|
104
|
+
app = Application.instance
|
|
105
|
+
puts '```'
|
|
106
|
+
puts format(Lang::get(:testname), app.test_name)
|
|
107
|
+
puts format(Lang::get(:date), Time.now)
|
|
108
|
+
puts format(Lang::get(:version), Application::VERSION)
|
|
109
|
+
puts '```'
|
|
110
|
+
puts "# README.md\n"
|
|
111
|
+
|
|
112
|
+
i = 1
|
|
113
|
+
unless @required_hosts.empty?
|
|
114
|
+
puts Lang::get(:hosts)
|
|
115
|
+
puts "\n"
|
|
116
|
+
puts '| ID | Host | Configuration |'
|
|
117
|
+
puts '| -- | ---- | ------------- |'
|
|
118
|
+
@required_hosts.each_pair do |k, v|
|
|
119
|
+
c = []
|
|
120
|
+
v.each_pair { |k2,v2| c << "#{k2}=#{v2}" }
|
|
121
|
+
puts "|#{i}|#{k.upcase}|#{c.join(', ')}|"
|
|
122
|
+
i += 1
|
|
123
|
+
end
|
|
124
|
+
puts "\n> NOTE: SSH Service installation is required on every host."
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
unless @cases_params.empty?
|
|
128
|
+
@cases_params.uniq!.sort!
|
|
129
|
+
puts Lang::get(:params)
|
|
130
|
+
@cases_params.uniq.each { |i| puts format('* %s', i) }
|
|
131
|
+
puts "\n> NOTE:"
|
|
132
|
+
puts "> * Teuton software must known this information!"
|
|
133
|
+
puts "> * Save every ':param: value' into config file."
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def show_tail
|
|
138
|
+
return if @global_params.empty?
|
|
139
|
+
|
|
140
|
+
app = Application.instance
|
|
141
|
+
puts "\n---"
|
|
142
|
+
puts "# ANEXO"
|
|
143
|
+
puts "\n\#\# Global params"
|
|
144
|
+
puts Lang::get(:global)
|
|
145
|
+
puts "\n"
|
|
146
|
+
puts '| Global param | Value |'
|
|
147
|
+
puts '| ------------ | ----- |'
|
|
148
|
+
@global_params.each_pair { |k,v| puts "|#{k}|#{v}|" }
|
|
149
|
+
puts "\n\#\# Created params"
|
|
150
|
+
puts Lang::get(:created)
|
|
151
|
+
puts "\n"
|
|
152
|
+
puts '| Created params | Value |'
|
|
153
|
+
puts '| -------------- | ----- |'
|
|
154
|
+
@setted_params.each_pair { |k,v| puts "|#{k}|#{v}|" }
|
|
155
|
+
end
|
|
156
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Method RakeFunction#check
|
|
4
|
+
module RakeFunction
|
|
5
|
+
def self.check(gems)
|
|
6
|
+
puts "[INFO] Version #{Application::VERSION}"
|
|
7
|
+
check_gems gems
|
|
8
|
+
check_tests
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.check_gems(gems)
|
|
12
|
+
fails = filter_uninstalled_gems(gems)
|
|
13
|
+
puts "[ERROR] Gems to install!: #{fails.join(',')}" unless fails == []
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.check_tests
|
|
17
|
+
testfile = File.join('.', 'tests', 'all.rb')
|
|
18
|
+
a = File.read(testfile).split("\n")
|
|
19
|
+
b = a.select { |i| i.include? '_test' }
|
|
20
|
+
|
|
21
|
+
d = File.join('.', 'tests', '**', '*_test.rb')
|
|
22
|
+
e = Dir.glob(d)
|
|
23
|
+
|
|
24
|
+
unless b.size == e.size
|
|
25
|
+
puts "[FAIL] Some ruby tests are not executed by #{testfile}"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
puts "[INFO] Running #{testfile}"
|
|
29
|
+
system(testfile)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def self.filter_uninstalled_gems(list)
|
|
33
|
+
cmd = `gem list`.split("\n")
|
|
34
|
+
names = cmd.map { |i| i.split(' ')[0] }
|
|
35
|
+
fails = []
|
|
36
|
+
list.each { |i| fails << i unless names.include?(i) }
|
|
37
|
+
fails
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Methods Module RakeFunction
|
|
4
|
+
# * opensuse
|
|
5
|
+
# * debian
|
|
6
|
+
# * install_gems
|
|
7
|
+
module RakeFunction
|
|
8
|
+
def self.opensuse(packages)
|
|
9
|
+
names = %w[openssh make gcc ruby-dev]
|
|
10
|
+
options = '--non-interactive'
|
|
11
|
+
names.each do |n|
|
|
12
|
+
system("zypper #{options} install #{n}")
|
|
13
|
+
end
|
|
14
|
+
install_gems packages, '--no-ri'
|
|
15
|
+
create_symbolic_link
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.debian(packages)
|
|
19
|
+
names = %w[ssh make gcc ruby-dev]
|
|
20
|
+
names.each { |name| system("apt-get install -y #{name}") }
|
|
21
|
+
install_gems packages, '--no-ri'
|
|
22
|
+
create_symbolic_link
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.install_gems(list, options = '')
|
|
26
|
+
fails = filter_uninstalled_gems(list)
|
|
27
|
+
if !fails.empty?
|
|
28
|
+
puts "[INFO] Installing gems (options = #{options})..."
|
|
29
|
+
fails.each do |name|
|
|
30
|
+
system("gem install #{name} #{options}")
|
|
31
|
+
end
|
|
32
|
+
else
|
|
33
|
+
puts '[ OK ] Gems installed'
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Close Show methods for Report class.
|
|
4
|
+
class Report
|
|
5
|
+
def close
|
|
6
|
+
app = Application.instance
|
|
7
|
+
max = 0.0
|
|
8
|
+
good = 0.0
|
|
9
|
+
fail = 0.0
|
|
10
|
+
fail_counter = 0
|
|
11
|
+
@lines.each do |i|
|
|
12
|
+
if i.class.to_s == 'Hash'
|
|
13
|
+
max += i[:weight] if i[:weight].positive?
|
|
14
|
+
if i[:check]
|
|
15
|
+
good += i[:weight]
|
|
16
|
+
@history += app.letter[:good]
|
|
17
|
+
else
|
|
18
|
+
fail += i[:weight]
|
|
19
|
+
fail_counter += 1
|
|
20
|
+
@history += app.letter[:bad]
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
@tail[:max_weight] = max
|
|
25
|
+
@tail[:good_weight] = good
|
|
26
|
+
@tail[:fail_weight] = fail
|
|
27
|
+
@tail[:fail_counter] = fail_counter
|
|
28
|
+
|
|
29
|
+
i = good.to_f / max.to_f
|
|
30
|
+
i = 0 if i.nan?
|
|
31
|
+
@tail[:grade] = (100.0 * i).round
|
|
32
|
+
@tail[:grade] = 0 if @tail[:unique_fault].positive?
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'base_formatter'
|
|
4
|
+
|
|
5
|
+
# ArrayFormatter class: format report data into an array
|
|
6
|
+
class ArrayFormatter < BaseFormatter
|
|
7
|
+
def initialize(report)
|
|
8
|
+
super(report)
|
|
9
|
+
@data = {}
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def process
|
|
13
|
+
build_data
|
|
14
|
+
w @data.to_s # Write data into ouput file
|
|
15
|
+
deinit
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def build_data
|
|
19
|
+
build_initial_data
|
|
20
|
+
build_history_data
|
|
21
|
+
build_final_data
|
|
22
|
+
build_hof_data
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def build_initial_data
|
|
26
|
+
head = {}
|
|
27
|
+
@head.each { |key, value| head[key] = value }
|
|
28
|
+
@data[:config] = head
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def build_history_data
|
|
32
|
+
@data[:logs] = []
|
|
33
|
+
groups = []
|
|
34
|
+
title = nil
|
|
35
|
+
targets = []
|
|
36
|
+
@lines.each do |i|
|
|
37
|
+
if i.class.to_s == 'Hash'
|
|
38
|
+
value = 0.0
|
|
39
|
+
value = i[:weight] if i[:check]
|
|
40
|
+
if i[:groupname] != title
|
|
41
|
+
# Add currentgroup
|
|
42
|
+
groups << { title: title, targets: targets } unless title.nil?
|
|
43
|
+
# Create new group
|
|
44
|
+
title = i[:groupname]
|
|
45
|
+
targets = []
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
target = {}
|
|
49
|
+
target[:target_id] = format('%02d', i[:id])
|
|
50
|
+
target[:check] = i[:check]
|
|
51
|
+
target[:score] = value
|
|
52
|
+
target[:weight] = i[:weight]
|
|
53
|
+
target[:description] = i[:description]
|
|
54
|
+
target[:command] = i[:command]
|
|
55
|
+
target[:conn_type] = i[:conn_type]
|
|
56
|
+
target[:duration] = i[:duration]
|
|
57
|
+
target[:alterations] = i[:alterations]
|
|
58
|
+
target[:expected] = i[:expected]
|
|
59
|
+
target[:result] = i[:result]
|
|
60
|
+
targets << target
|
|
61
|
+
else
|
|
62
|
+
@data[:logs] << i.to_s # Add log line
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
groups << { title: title, targets: targets } unless title.nil?
|
|
67
|
+
@data[:groups] = groups
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def build_final_data
|
|
71
|
+
tail = {}
|
|
72
|
+
@tail.each { |key, value| tail[key] = value }
|
|
73
|
+
@data[:results] = tail
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def build_hof_data
|
|
77
|
+
app = Application.instance
|
|
78
|
+
@data[:hall_of_fame] = {}
|
|
79
|
+
return if app.options[:case_number] < 3
|
|
80
|
+
fame = {}
|
|
81
|
+
app.hall_of_fame.each { |line| fame[line[0]] = line[1] }
|
|
82
|
+
@data[:hall_of_fame] = fame
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# BaseFormatter class
|
|
4
|
+
class BaseFormatter
|
|
5
|
+
def initialize(report)
|
|
6
|
+
@head = report.head
|
|
7
|
+
@lines = report.lines
|
|
8
|
+
@tail = report.tail
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def init(filename)
|
|
12
|
+
@filename = filename
|
|
13
|
+
@file = File.open(@filename, 'w')
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def w(text)
|
|
17
|
+
@file.write text.to_s # write into output file
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def process
|
|
21
|
+
raise 'Empty method!'
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def deinit
|
|
25
|
+
@file.close
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def trim(input)
|
|
29
|
+
output = input.to_s
|
|
30
|
+
output = "...#{input[input.size - 50, input.size]}" if output.size > 65
|
|
31
|
+
output.to_s
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
|
|
2
|
+
require_relative 'base_formatter'
|
|
3
|
+
|
|
4
|
+
class CSVFormatter < BaseFormatter
|
|
5
|
+
def initialize(report)
|
|
6
|
+
super(report)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def process
|
|
10
|
+
d = ';'
|
|
11
|
+
@head.each { |key,value| w "HEAD#{d}#{key}#{d}#{value}\n" }
|
|
12
|
+
@datagroups.each { |item| process_datagroup(item,d) }
|
|
13
|
+
@tail.each { |key,value| w "TAIL#{d}#{key}#{d}#{value}\n" }
|
|
14
|
+
deinit
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def process_datagroup(pGroup, delimiter=';')
|
|
18
|
+
d = delimiter
|
|
19
|
+
a = "DATAGROUP"+pGroup.order.to_s+d
|
|
20
|
+
pGroup.head.each { |key,value| w a+"HEAD"+d+key.to_s+d+value.to_s+"\n" }
|
|
21
|
+
pGroup.lines.each do |i|
|
|
22
|
+
if i.class.to_s=='Hash' then
|
|
23
|
+
w a + "LINES#{d}ACTION#{d}#{i[:id]}#{d}#{i[:weight]}#{d}" +
|
|
24
|
+
"#{i[:description]}\n"
|
|
25
|
+
else
|
|
26
|
+
w a + "LINES#{d}LOG#{d}#{i}\n"
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
pGroup.tail.each { |key,value| w a+"TAIL"+d+key.to_s+d+value.to_s+"\n" }
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rainbow'
|
|
4
|
+
require_relative 'json_formatter'
|
|
5
|
+
require_relative 'list_formatter'
|
|
6
|
+
require_relative 'txt_formatter'
|
|
7
|
+
require_relative 'yaml_formatter'
|
|
8
|
+
require_relative 'resume_json_formatter'
|
|
9
|
+
require_relative 'resume_list_formatter'
|
|
10
|
+
require_relative 'resume_yaml_formatter'
|
|
11
|
+
require_relative 'resume_txt_formatter'
|
|
12
|
+
require_relative 'moodle_csv_formatter'
|
|
13
|
+
require_relative 'csv_formatter'
|
|
14
|
+
require_relative 'html_formatter'
|
|
15
|
+
require_relative 'xml_formatter'
|
|
16
|
+
|
|
17
|
+
# FormaterFactory module
|
|
18
|
+
module FormatterFactory
|
|
19
|
+
def self.get(report, format, filename)
|
|
20
|
+
case format
|
|
21
|
+
when :colored_text
|
|
22
|
+
f = TXTFormatter.new(report,true)
|
|
23
|
+
when :csv
|
|
24
|
+
f = CSVFormatter.new(report)
|
|
25
|
+
when :html
|
|
26
|
+
f = HTMLFormatter.new(report)
|
|
27
|
+
when :json
|
|
28
|
+
f = JSONFormatter.new(report)
|
|
29
|
+
when :list
|
|
30
|
+
f = ListFormatter.new(report)
|
|
31
|
+
when :moodle_csv
|
|
32
|
+
f = MoodleCSVFormatter.new(report)
|
|
33
|
+
when :resume_txt
|
|
34
|
+
f = ResumeTXTFormatter.new(report, false)
|
|
35
|
+
when :resume_colored_text
|
|
36
|
+
f = ResumeTXTFormatter.new(report, true)
|
|
37
|
+
when :resume_json
|
|
38
|
+
f = ResumeJSONFormatter.new(report)
|
|
39
|
+
when :resume_list
|
|
40
|
+
f = ResumeListFormatter.new(report)
|
|
41
|
+
when :resume_yaml
|
|
42
|
+
f = ResumeYAMLFormatter.new(report)
|
|
43
|
+
when :txt
|
|
44
|
+
f = TXTFormatter.new(report,false)
|
|
45
|
+
when :xml
|
|
46
|
+
f = XMLFormatter.new(report)
|
|
47
|
+
when :yaml
|
|
48
|
+
f = YAMLFormatter.new(report)
|
|
49
|
+
else
|
|
50
|
+
raise Rainbow("[ERROR] FormaterFactory #{format} unkown!").red.bright
|
|
51
|
+
end
|
|
52
|
+
f.init(filename)
|
|
53
|
+
f
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def self.ext(format)
|
|
57
|
+
data = { cvs: 'csv',
|
|
58
|
+
colored_text: 'txt',
|
|
59
|
+
json: 'json',
|
|
60
|
+
list: 'txt',
|
|
61
|
+
resume_colored_text: 'txt',
|
|
62
|
+
resume_csv: 'csv',
|
|
63
|
+
resume_json: 'json',
|
|
64
|
+
resume_list: 'txt',
|
|
65
|
+
resume_txt: 'txt',
|
|
66
|
+
resume_yaml: 'yaml',
|
|
67
|
+
txt: 'txt',
|
|
68
|
+
yaml: 'yaml' }
|
|
69
|
+
return format.to_s if data[format].nil?
|
|
70
|
+
|
|
71
|
+
data[format]
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
|
|
2
|
+
require_relative 'base_formatter'
|
|
3
|
+
|
|
4
|
+
class HTMLFormatter < BaseFormatter
|
|
5
|
+
|
|
6
|
+
def initialize(pReport)
|
|
7
|
+
super(pReport)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def process
|
|
11
|
+
puts "<html>"
|
|
12
|
+
puts "<head><title>Checking Machines</title></head>"
|
|
13
|
+
puts "<body>"
|
|
14
|
+
puts "<header><h1><a name=\"index\">Checking Machines v0.4</a></h1>"
|
|
15
|
+
puts '<ul>'
|
|
16
|
+
@head.each do |key,value|
|
|
17
|
+
puts "<li><b>"+key.to_s+": </b>"+value.to_s+"</li>" if key!=:title
|
|
18
|
+
end
|
|
19
|
+
puts '</ul>'
|
|
20
|
+
puts "<table border=1 >"
|
|
21
|
+
puts "<thead><tr><td>Members</td><td>Grade</td><td>Fails</td></tr></thead>"
|
|
22
|
+
puts "<tbody>"
|
|
23
|
+
|
|
24
|
+
counter=0
|
|
25
|
+
@datagroups.each do |i|
|
|
26
|
+
counter+=1
|
|
27
|
+
puts "<tr><td><a href=\"#group"+counter.to_s+"\">"+i.head[:members]+"</a></td>"
|
|
28
|
+
puts "<td>"+i.tail[:grade].to_s+"</td>"
|
|
29
|
+
puts "<td>"+i.tail[:fail_counter].to_s+"</td></tr>"
|
|
30
|
+
end
|
|
31
|
+
puts "</tbody></table></header>"
|
|
32
|
+
puts "<h1>Cases</h1>"
|
|
33
|
+
|
|
34
|
+
counter=0
|
|
35
|
+
@datagroups.each do |i|
|
|
36
|
+
counter+=1
|
|
37
|
+
process_datagroup(i,counter)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
puts '<ul>'
|
|
41
|
+
@tail.each do |key,value|
|
|
42
|
+
puts "<li><b>"+key.to_s+": </b>"+value.to_s+"</li>"
|
|
43
|
+
end
|
|
44
|
+
puts '</ul>'
|
|
45
|
+
puts "</body></html>"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def process_datagroup(pGroup, pCounter)
|
|
49
|
+
puts "<h2><a name=\"group"+pCounter.to_s+"\">Case members "+@head[:members]+"</a> (<a href=\"#index\">up</a>)</h2>"
|
|
50
|
+
puts "<table border=1 >"
|
|
51
|
+
puts "<thead><tr><td>Params</td><td>Results</td></tr></thead>"
|
|
52
|
+
puts "<tbody><tr>"
|
|
53
|
+
puts "<td><ul>"
|
|
54
|
+
pGroup.head.each do |key,value|
|
|
55
|
+
puts "<li><b>"+key.to_s+"</b>= "+value.to_s+"</li>" if key!=:members
|
|
56
|
+
end
|
|
57
|
+
puts "</ul></td>"
|
|
58
|
+
puts '<td><ul>'
|
|
59
|
+
pGroup.tail.each do |key,value|
|
|
60
|
+
puts "<li><b>"+key.to_s+"</b>= "+value.to_s+"</li>"
|
|
61
|
+
end
|
|
62
|
+
puts '</ul></td>'
|
|
63
|
+
|
|
64
|
+
puts '</tr></tbdody></table>'
|
|
65
|
+
puts '<h3>Test log</h3>'
|
|
66
|
+
puts '<ul>'
|
|
67
|
+
pGroup.lines.each do |i|
|
|
68
|
+
if i.class.to_s=='Hash' then
|
|
69
|
+
value=0.0
|
|
70
|
+
value=i[:weight] if i[:check]
|
|
71
|
+
a="<li>"+i[:id].to_s+" ("+value.to_s+") [weight="+i[:weight].to_s+"] "
|
|
72
|
+
a+="<i>"+i[:description]+"</i>: "+i[:command]+"</li>"
|
|
73
|
+
puts a
|
|
74
|
+
else
|
|
75
|
+
puts "<li>"+i.to_s+"</li>"
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
puts '</ul>'
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'array_formatter'
|
|
4
|
+
|
|
5
|
+
# JSONFormatter class
|
|
6
|
+
class JSONFormatter < ArrayFormatter
|
|
7
|
+
def initialize(report)
|
|
8
|
+
super(report)
|
|
9
|
+
@data = {}
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def process
|
|
13
|
+
build_data
|
|
14
|
+
w @data.to_json # Write data into ouput file
|
|
15
|
+
deinit
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'array_formatter'
|
|
4
|
+
|
|
5
|
+
# ListFormatter class
|
|
6
|
+
class ListFormatter < ArrayFormatter
|
|
7
|
+
def initialize(report)
|
|
8
|
+
super(report)
|
|
9
|
+
@data = {}
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def process
|
|
13
|
+
build_data
|
|
14
|
+
process_config
|
|
15
|
+
process_logs
|
|
16
|
+
process_groups
|
|
17
|
+
process_results
|
|
18
|
+
process_hof
|
|
19
|
+
deinit
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def process_config
|
|
25
|
+
w "CONFIGURATION\n"
|
|
26
|
+
@data[:config].sort.each { |key,value| w " * #{key} : #{value}\n" }
|
|
27
|
+
w "\n\n"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def process_logs
|
|
31
|
+
return if @data[:logs].size == 0
|
|
32
|
+
|
|
33
|
+
w "\nLOGS\n"
|
|
34
|
+
@data[:logs].each { |line| w " * #{line}\n" }
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def process_groups
|
|
38
|
+
return if @data[:groups].size == 0
|
|
39
|
+
|
|
40
|
+
w "\nGROUPS\n"
|
|
41
|
+
@data[:groups].each { |g| process_group g }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def process_results
|
|
45
|
+
w "\nRESULTS\n"
|
|
46
|
+
@data[:results].each do |key,value|
|
|
47
|
+
w " * #{key.to_s} : #{value.to_s}\n"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def process_hof
|
|
52
|
+
return if @data[:hall_of_fame].size < 3
|
|
53
|
+
|
|
54
|
+
w "\nHALL OF FAME\n"
|
|
55
|
+
@data[:hall_of_fame].each do |line|
|
|
56
|
+
w " #{line[0]} #{line[1]}\n"
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
private
|
|
61
|
+
|
|
62
|
+
def process_group(group)
|
|
63
|
+
tab = ' '
|
|
64
|
+
w "- #{group[:title]}\n"
|
|
65
|
+
group[:targets].each do |i|
|
|
66
|
+
w tab*2 + "#{format("%02d", i[:target_id].to_i)}"
|
|
67
|
+
w " (#{i[:score]}/#{i[:weight]}) "
|
|
68
|
+
w "#{i[:description]}\n"
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'resume_array_formatter'
|
|
4
|
+
|
|
5
|
+
# MoodleCSVFormatter class
|
|
6
|
+
class MoodleCSVFormatter < ResumeArrayFormatter
|
|
7
|
+
def initialize(report)
|
|
8
|
+
super(report)
|
|
9
|
+
@data = {}
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def process
|
|
13
|
+
build_data
|
|
14
|
+
process_cases
|
|
15
|
+
deinit
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def process_cases
|
|
21
|
+
# MoodleID, Grade, Feedback
|
|
22
|
+
w "MoodleID, TeutonGrade, TeutonFeedback\n"
|
|
23
|
+
@data[:cases].each do |line|
|
|
24
|
+
w "#{line[:moodle_id]},#{line[:grade]}," \
|
|
25
|
+
"#{line[:moodle_feedback]}\n" unless line[:skip]
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|