teuton 2.4.1 → 2.4.3
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 +3 -1
- data/docs/changelog/todo.md +1 -0
- data/docs/changelog/v2.4.md +9 -0
- data/docs/commands/README.md +8 -17
- data/docs/commands/example_check.md +4 -4
- data/docs/commands/example_run.md +10 -32
- data/docs/dsl/README.md +27 -39
- data/docs/dsl/{definition/expect.md → expect.md} +2 -18
- data/docs/dsl/{execution/export.md → export.md} +1 -6
- data/docs/dsl/{setting/get.md → get.md} +4 -10
- data/docs/dsl/{definition/group.md → group.md} +2 -7
- data/docs/dsl/{execution/play.md → play.md} +1 -6
- data/docs/dsl/{definition/result.md → result.md} +1 -6
- data/docs/dsl/{definition/run_remote.md → run.md} +57 -23
- data/docs/dsl/{execution/send.md → send.md} +1 -8
- data/docs/dsl/{setting/set.md → set.md} +1 -7
- data/docs/dsl/{execution/show.md → show.md} +7 -16
- data/docs/dsl/target.md +33 -0
- data/docs/ideas/todo.md +35 -115
- data/docs/learn/01-cmd_new.md +28 -0
- data/docs/learn/{01-target.md → 02-target.md} +13 -17
- data/docs/learn/03-remote_hosts.md +59 -87
- data/docs/learn/04-config.md +147 -0
- data/docs/learn/05-use.md +25 -45
- data/docs/learn/06-cmd_check.md +50 -0
- data/docs/learn/07-target_weight.md +44 -0
- data/docs/learn/08-unique_values.md +70 -0
- data/docs/learn/09-send.md +20 -0
- data/docs/learn/10-debug.md +45 -0
- data/docs/learn/11-export.md +35 -0
- data/docs/learn/{09-preserve.md → 12-preserve.md} +0 -0
- data/docs/learn/{17-hide-feedback.md → 13-feedback.md} +20 -23
- data/docs/learn/14-moodle_id.md +24 -0
- data/docs/learn/{08-readme.md → 15-readme.md} +5 -9
- data/docs/learn/{13-include.md → 16-include.md} +1 -3
- data/docs/learn/{14-alias.md → 17-alias.md} +0 -0
- data/docs/learn/{07-log.md → 18-log.md} +19 -23
- data/docs/learn/{12-get_vars.md → 19-read_vars.md} +3 -3
- data/docs/learn/20-macros.md +49 -0
- data/docs/learn/{16-exit_codes.md → 21-exit_codes.md} +0 -0
- data/docs/learn/{10-result.md → 22-result.md} +3 -3
- data/docs/learn/23-test-code.md +54 -0
- data/docs/learn/24-test-sql.md +69 -0
- data/docs/learn/README.md +24 -18
- data/lib/teuton/application.rb +0 -5
- data/lib/teuton/case_manager/case/case.rb +1 -1
- data/lib/teuton/case_manager/case/dsl/expect.rb +9 -2
- data/lib/teuton/case_manager/case/dsl/goto.rb +1 -1
- data/lib/teuton/case_manager/case/dsl/log.rb +5 -3
- data/lib/teuton/case_manager/case/dsl/target.rb +1 -1
- data/lib/teuton/case_manager/case/result/ext_compare.rb +20 -21
- data/lib/teuton/case_manager/case/result/ext_filter.rb +15 -8
- data/lib/teuton/check/show.rb +1 -1
- data/lib/teuton/files/config.yaml +1 -2
- data/lib/teuton/files/start.rb +4 -4
- data/lib/teuton/readme/dsl.rb +9 -1
- data/lib/teuton/readme/readme.rb +8 -1
- data/lib/teuton/report/show.rb +8 -0
- data/lib/teuton/version.rb +1 -1
- metadata +68 -54
- data/docs/dsl/definition/run_local.md +0 -33
- data/docs/dsl/definition/target.md +0 -40
- data/docs/learn/02-config.md +0 -117
- data/docs/learn/04-new_test.md +0 -87
- data/docs/learn/06-debug.md +0 -110
- data/docs/learn/11-moodle_id.md +0 -19
@@ -1,6 +1,6 @@
|
|
1
1
|
[<< back](README.md)
|
2
2
|
|
3
|
-
#
|
3
|
+
# result
|
4
4
|
|
5
5
|
Sometimes it can be useful to look at the information returned by the "run" command. For this we use the **"result" object**.
|
6
6
|
|
@@ -20,11 +20,11 @@ end
|
|
20
20
|
|
21
21
|
**Example 2:** When we are debugging our test and we want to see the content of the "result" object on the screen, we will use `result.debug`.
|
22
22
|
|
23
|
-
```
|
23
|
+
```ruby
|
24
24
|
group "Checking users" do
|
25
25
|
users = ["root", "vader"]
|
26
26
|
|
27
|
-
users
|
27
|
+
for name in users do
|
28
28
|
target "Exists username #{name}"
|
29
29
|
run "id #{name}"
|
30
30
|
result.debug
|
@@ -0,0 +1,54 @@
|
|
1
|
+
[<<back](README.md)
|
2
|
+
|
3
|
+
# Test code
|
4
|
+
|
5
|
+
Let's test code using teuton.
|
6
|
+
|
7
|
+
**Example:**
|
8
|
+
|
9
|
+
* Ask students to make a program that performs addition and multiplication.
|
10
|
+
* Define targets `sum` and `mul`:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
# File: start.rb
|
14
|
+
group "Test code example" do
|
15
|
+
# Reading filepath from config file
|
16
|
+
filepath = "./#{get(:folder)}/#{get(:filename)}"
|
17
|
+
|
18
|
+
target "Sum"
|
19
|
+
run "#{filepath} 3 4"
|
20
|
+
expect [ "Sum", "7" ] # Using Array/List of required items
|
21
|
+
|
22
|
+
target "Mul"
|
23
|
+
run "#{filepath} 3 4"
|
24
|
+
expect /Mul\s+=\s+12/ # Using a regular expresion
|
25
|
+
end
|
26
|
+
```
|
27
|
+
|
28
|
+
* Define config params:
|
29
|
+
|
30
|
+
```yaml
|
31
|
+
# File: config.yaml
|
32
|
+
---
|
33
|
+
global:
|
34
|
+
folder: examples/23-test-code/code
|
35
|
+
cases:
|
36
|
+
- tt_members: student_1
|
37
|
+
filename: math_1.py
|
38
|
+
- tt_members: student_2
|
39
|
+
filename: math_2b.py
|
40
|
+
```
|
41
|
+
|
42
|
+
* Put students files into `code` folder.
|
43
|
+
* Now run Teuton test:
|
44
|
+
|
45
|
+
```
|
46
|
+
❯ teuton examples/23-test-code
|
47
|
+
|
48
|
+
CASE RESULTS
|
49
|
+
+------+-----------+-------+-------+
|
50
|
+
| CASE | MEMBERS | GRADE | STATE |
|
51
|
+
| 01 | student_1 | 100.0 | ✔ |
|
52
|
+
| 02 | student_2 | 100.0 | ✔ |
|
53
|
+
+------+-----------+-------+-------+
|
54
|
+
```
|
@@ -0,0 +1,69 @@
|
|
1
|
+
[<<back](README.md)
|
2
|
+
|
3
|
+
# Test SQL and database
|
4
|
+
|
5
|
+
**Exercise**
|
6
|
+
|
7
|
+
* Ask students to make a Sqlite Database. Create a table called `characters` with `name` varchar, and `rol` varchar.
|
8
|
+
* Database example:
|
9
|
+
|
10
|
+
```
|
11
|
+
❯ sqlite3 examples/24-test-sql/database_01.db
|
12
|
+
|
13
|
+
sqlite> .schema characters
|
14
|
+
CREATE TABLE characters ( name varchar(255), rol varchar(255));
|
15
|
+
|
16
|
+
sqlite> select * from characters;
|
17
|
+
Obiwan|Jedi
|
18
|
+
```
|
19
|
+
|
20
|
+
* Query example:
|
21
|
+
|
22
|
+
```
|
23
|
+
❯ cat examples/24-test-sql/query_01.sql
|
24
|
+
|
25
|
+
select * from characters where rol='Jedi';
|
26
|
+
```
|
27
|
+
|
28
|
+
**Teuton test**
|
29
|
+
|
30
|
+
* Define targets:
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
group "Test SQL and database" do
|
34
|
+
database = "#{get(:folder)}/#{get(:database)}"
|
35
|
+
query = "#{get(:folder)}/#{get(:query)}"
|
36
|
+
|
37
|
+
target "Database schema"
|
38
|
+
run "sqlite3 #{database} '.schema characters'"
|
39
|
+
expect "name varchar", "rol varchar"
|
40
|
+
|
41
|
+
target "Query Jedi"
|
42
|
+
run "sqlite3 #{database} '.read #{query}'"
|
43
|
+
expect "Obiwan", "Jedi"
|
44
|
+
end
|
45
|
+
```
|
46
|
+
|
47
|
+
* Configure params:
|
48
|
+
|
49
|
+
```yaml
|
50
|
+
---
|
51
|
+
global:
|
52
|
+
folder: examples/24-test-sql
|
53
|
+
cases:
|
54
|
+
- tt_members: student_1_name
|
55
|
+
database: database_01.db
|
56
|
+
query: query_01.sql
|
57
|
+
```
|
58
|
+
|
59
|
+
**Test output**
|
60
|
+
|
61
|
+
```
|
62
|
+
❯ teuton examples/24-test-sql
|
63
|
+
|
64
|
+
CASE RESULTS
|
65
|
+
+------+----------------+-------+-------+
|
66
|
+
| CASE | MEMBERS | GRADE | STATE |
|
67
|
+
| 01 | student_1_name | 100.0 | ✔ |
|
68
|
+
+------+----------------+-------+-------+
|
69
|
+
```
|
data/docs/learn/README.md
CHANGED
@@ -1,27 +1,33 @@
|
|
1
|
-
|
2
1
|
[<< back](../../README.md)
|
3
2
|
|
4
3
|
# Learn
|
5
4
|
|
6
5
|
Learn how write your own Teuton tests:
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
7
|
+
1. [Creating NEW test](01-cmd_new.md)
|
8
|
+
1. [Evaluating TARGET](02-target.md)
|
9
|
+
1. [Checking REMOTE HOSTS](03-remote_hosts.md)
|
10
|
+
1. [Reading CONFIG file](04-config.md)
|
11
|
+
1. [Using several files](05-use.md)
|
12
|
+
1. [CHECK test syntax](06-cmd_check.md)
|
13
|
+
1. [Target WEIGHT](07-target_weight.md)
|
14
|
+
1. [UNIQUE values](08-unique_values.md)
|
15
|
+
1. [SEND report copies to remote hosts](09-send.md)
|
16
|
+
1. [DEBUG results](10-debug.md)
|
17
|
+
1. [Export other FORMATS](11-export.md)
|
18
|
+
1. [PRESERVE old reports](12-preserve.md)
|
19
|
+
1. [Hide FEEDBACK from reports](13-feedback.md)
|
20
|
+
1. [MOODLE ID](14-moodle_id.md)
|
21
|
+
1. [Build README from test](15-readme.md)
|
22
|
+
1. [INCLUDE more configuration files](16-include.md)
|
23
|
+
1. [ALIAS](17-alias.md)
|
24
|
+
1. [LOG messages](18-log.md)
|
25
|
+
1. [Don't get params, just read vars](19-read_vars.md)
|
26
|
+
1. [MACROS](20-macros.md)
|
27
|
+
1. [Checking exit codes](21-exit_codes.md)
|
28
|
+
1. [RESULT object](22-result.md)
|
29
|
+
1. [Test code](23-test-code.md)
|
30
|
+
1. [Test SQL and database](24-test-sql.md)
|
25
31
|
|
26
32
|
Mores examples at [teuton-tests](https://github.com/dvarrui/teuton-tests) GitHub repository.
|
27
33
|
|
data/lib/teuton/application.rb
CHANGED
@@ -1,13 +1,8 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
require "singleton"
|
4
|
-
require_relative "version"
|
5
2
|
require_relative "utils/name_file_finder"
|
6
3
|
|
7
|
-
# This Singleton contains application params
|
8
4
|
class Application
|
9
5
|
include Singleton
|
10
|
-
include Teuton
|
11
6
|
|
12
7
|
attr_reader :letter
|
13
8
|
attr_reader :running_basedir, :output_basedir
|
@@ -54,8 +54,15 @@ module DSL
|
|
54
54
|
expect2 input, expected: output
|
55
55
|
end
|
56
56
|
|
57
|
-
def expect_none(input, args = {})
|
58
|
-
|
57
|
+
# def expect_none(input, args = {})
|
58
|
+
def expect_nothing(args = {})
|
59
|
+
expect2 result.count.eq(0), args
|
60
|
+
end
|
61
|
+
|
62
|
+
def expect_none(input = nil, args = {})
|
63
|
+
if input.nil?
|
64
|
+
# nothing to do
|
65
|
+
elsif input.instance_of? Array
|
59
66
|
input.each { |i| result.find(i) }
|
60
67
|
else
|
61
68
|
result.find(input)
|
@@ -7,12 +7,14 @@ module DSL
|
|
7
7
|
# @param text (String)
|
8
8
|
# @param type (Symbol) Values :info, :warn or :error
|
9
9
|
def log(text = "", type = :info)
|
10
|
-
s = ""
|
10
|
+
s = " INFO"
|
11
11
|
s = Rainbow("WARN!").color(:yellow) if type == :warn
|
12
12
|
s = Rainbow("ERROR").bg(:red) if type == :error
|
13
13
|
t = Time.now
|
14
14
|
f = format("%<hour>02d:%<min>02d:%<sec>02d", {hour: t.hour, min: t.min, sec: t.sec})
|
15
|
-
|
15
|
+
msg = "[#{f}] #{s}: #{text}"
|
16
|
+
msg = "[#{f}] #{text}" if s == ""
|
17
|
+
@report.lines << msg
|
16
18
|
end
|
17
|
-
|
19
|
+
alias_method :msg, :log
|
18
20
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
#
|
3
|
+
# Extension of Result class
|
4
4
|
class Result
|
5
5
|
def eq(input)
|
6
6
|
# Return true when content is equal than input
|
@@ -22,10 +22,10 @@ class Result
|
|
22
22
|
end
|
23
23
|
value == input
|
24
24
|
end
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
25
|
+
alias_method :eq?, :eq
|
26
|
+
alias_method :equal, :eq
|
27
|
+
alias_method :equal?, :eq
|
28
|
+
alias_method :is_equal?, :eq
|
29
29
|
|
30
30
|
def neq(external)
|
31
31
|
@expected = "Not equal to #{external}"
|
@@ -44,9 +44,9 @@ class Result
|
|
44
44
|
end
|
45
45
|
internal != external
|
46
46
|
end
|
47
|
-
|
48
|
-
|
49
|
-
|
47
|
+
alias_method :neq?, :neq
|
48
|
+
alias_method :not_equal, :neq
|
49
|
+
alias_method :not_equal?, :neq
|
50
50
|
|
51
51
|
def ge(input)
|
52
52
|
@expected = "Greater or equal to #{input}"
|
@@ -65,8 +65,8 @@ class Result
|
|
65
65
|
end
|
66
66
|
value >= input
|
67
67
|
end
|
68
|
-
|
69
|
-
|
68
|
+
alias_method :greater_or_equal, :ge
|
69
|
+
alias_method :greater_or_equal?, :ge
|
70
70
|
|
71
71
|
def gt(input)
|
72
72
|
@expected = "Greater than #{input}"
|
@@ -85,8 +85,8 @@ class Result
|
|
85
85
|
end
|
86
86
|
value > input
|
87
87
|
end
|
88
|
-
|
89
|
-
|
88
|
+
alias_method :greater, :gt
|
89
|
+
alias_method :greater_than, :gt
|
90
90
|
|
91
91
|
def le(input)
|
92
92
|
@expected = "Lesser or equal to #{input}"
|
@@ -106,8 +106,8 @@ class Result
|
|
106
106
|
end
|
107
107
|
value <= input
|
108
108
|
end
|
109
|
-
|
110
|
-
|
109
|
+
alias_method :lesser_or_equal, :le
|
110
|
+
alias_method :lesser_or_equal?, :le
|
111
111
|
|
112
112
|
def lt(input)
|
113
113
|
@expected = "Lesser than #{input}"
|
@@ -126,9 +126,9 @@ class Result
|
|
126
126
|
end
|
127
127
|
value < input
|
128
128
|
end
|
129
|
-
|
130
|
-
|
131
|
-
|
129
|
+
alias_method :lesser, :lt
|
130
|
+
alias_method :smaller, :lt
|
131
|
+
alias_method :lesser_than, :lt
|
132
132
|
|
133
133
|
# Return 'true' if the parameter value is near to the target value.
|
134
134
|
# To get this we consider a 10% desviation or less, as an acceptable result.
|
@@ -142,8 +142,7 @@ class Result
|
|
142
142
|
|
143
143
|
false
|
144
144
|
end
|
145
|
-
|
146
|
-
|
147
|
-
|
145
|
+
alias_method :near_to, :near_to?
|
146
|
+
alias_method :near?, :near_to?
|
147
|
+
alias_method :near, :near_to?
|
148
148
|
end
|
149
|
-
# rubocop:enable Metrics/ClassLength
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
#
|
3
|
+
# Result class extension
|
4
4
|
class Result
|
5
5
|
# TODO: Error line 102 undefined include? method for 0 Fixnum...
|
6
6
|
def find(filter)
|
@@ -15,9 +15,9 @@ class Result
|
|
15
15
|
end
|
16
16
|
self
|
17
17
|
end
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
alias_method :grep, :find
|
19
|
+
alias_method :grep!, :find
|
20
|
+
alias_method :find!, :find
|
21
21
|
|
22
22
|
def first
|
23
23
|
@alterations << "first"
|
@@ -25,14 +25,21 @@ class Result
|
|
25
25
|
self
|
26
26
|
end
|
27
27
|
|
28
|
-
def not_find(
|
29
|
-
@alterations << "not_find(#{
|
28
|
+
def not_find(filter)
|
29
|
+
@alterations << "not_find(#{filter})"
|
30
30
|
return self if @content.size.zero?
|
31
31
|
|
32
|
-
|
32
|
+
case filter.class.to_s
|
33
|
+
when "Array"
|
34
|
+
filter.each { |i| not_find(i.to_s) }
|
35
|
+
when "String" || "Integer"
|
36
|
+
@content.reject! { |i| i.include?(filter.to_s) }
|
37
|
+
when "Regexp"
|
38
|
+
@content.reject! { |i| filter.match(i) }
|
39
|
+
end
|
33
40
|
self
|
34
41
|
end
|
35
|
-
|
42
|
+
alias_method :grep_v, :not_find
|
36
43
|
|
37
44
|
def since(filter)
|
38
45
|
@alterations << "since(#{filter})"
|
data/lib/teuton/check/show.rb
CHANGED
@@ -131,7 +131,7 @@ class Laboratory
|
|
131
131
|
st.add_separator
|
132
132
|
st.add_row ["Groups", @stats[:groups]]
|
133
133
|
st.add_row ["Targets", @stats[:targets]]
|
134
|
-
st.add_row ["
|
134
|
+
st.add_row ["Runs", @stats[:hosts]]
|
135
135
|
@hosts.each_pair { |k, v| st.add_row [" * #{k}", v] }
|
136
136
|
st.add_row ["Uniques", @stats[:uniques]]
|
137
137
|
st.add_row ["Logs", @stats[:uniques]]
|
data/lib/teuton/files/start.rb
CHANGED
data/lib/teuton/readme/dsl.rb
CHANGED
@@ -87,10 +87,18 @@ class Readme
|
|
87
87
|
end
|
88
88
|
|
89
89
|
# If a method call is missing, then delegate to concept parent.
|
90
|
-
def method_missing(method, args = {})
|
90
|
+
# def method_missing(method, args = {})
|
91
|
+
def method_missing(method, *args, &block)
|
91
92
|
m = method.to_s
|
92
93
|
if m[0] == "_"
|
93
94
|
instance_eval("get(:#{m[1, m.size - 1]})", __FILE__, __LINE__)
|
95
|
+
elsif not Application.instance.macros[m].nil?
|
96
|
+
puts "macro exec: #{m}"
|
97
|
+
code = ""
|
98
|
+
args[0].keys.each { |key| code += "set(:#{key}, '#{args[0][key]}')\n" }
|
99
|
+
puts code
|
100
|
+
# instance_eval(code)
|
101
|
+
# Application.instance.macros[m].call
|
94
102
|
end
|
95
103
|
end
|
96
104
|
|
data/lib/teuton/readme/readme.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require_relative "../application"
|
2
2
|
require_relative "../utils/configfile_reader"
|
3
3
|
require_relative "../case_manager/case/result/result"
|
4
|
+
require_relative "../version"
|
4
5
|
require_relative "dsl"
|
5
6
|
require_relative "lang"
|
6
7
|
|
@@ -14,6 +15,11 @@ def use(filename)
|
|
14
15
|
require_relative use[0]
|
15
16
|
end
|
16
17
|
|
18
|
+
def define_macro(name, *args, &block)
|
19
|
+
puts "macro: #{name}"
|
20
|
+
Application.instance.macros[name] = {args: args, block: block}
|
21
|
+
end
|
22
|
+
|
17
23
|
def group(name, &block)
|
18
24
|
Application.instance.groups << {name: name, block: block}
|
19
25
|
end
|
@@ -58,6 +64,7 @@ class Readme
|
|
58
64
|
@verbose = app.verbose
|
59
65
|
@result = Result.new
|
60
66
|
@data = {}
|
67
|
+
@data[:macros] = []
|
61
68
|
@data[:logs] = []
|
62
69
|
@data[:groups] = []
|
63
70
|
@data[:play] = []
|
@@ -86,7 +93,7 @@ class Readme
|
|
86
93
|
puts "```"
|
87
94
|
puts format(Lang.get(:testname), app.test_name)
|
88
95
|
puts format(Lang.get(:date), Time.now)
|
89
|
-
puts format(Lang.get(:version),
|
96
|
+
puts format(Lang.get(:version), Teuton::VERSION)
|
90
97
|
puts "```"
|
91
98
|
puts "\n"
|
92
99
|
puts "# #{app.test_name}\n"
|
data/lib/teuton/report/show.rb
CHANGED
@@ -1,6 +1,14 @@
|
|
1
1
|
require "rainbow"
|
2
|
+
require "terminal-table"
|
2
3
|
require_relative "../application"
|
3
4
|
|
5
|
+
# | Verbosity level | Description |
|
6
|
+
# | :-------------: | ----------- |
|
7
|
+
# | 0 | No output |
|
8
|
+
# | 1 | Default output messages |
|
9
|
+
# | 2 | Show hall of fame |
|
10
|
+
# | 3 | Show final values |
|
11
|
+
# | 4 | Show Initial values |
|
4
12
|
class ShowReport
|
5
13
|
def initialize(report)
|
6
14
|
@report = report
|
data/lib/teuton/version.rb
CHANGED