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.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -1
  3. data/docs/changelog/todo.md +1 -0
  4. data/docs/changelog/v2.4.md +9 -0
  5. data/docs/commands/README.md +8 -17
  6. data/docs/commands/example_check.md +4 -4
  7. data/docs/commands/example_run.md +10 -32
  8. data/docs/dsl/README.md +27 -39
  9. data/docs/dsl/{definition/expect.md → expect.md} +2 -18
  10. data/docs/dsl/{execution/export.md → export.md} +1 -6
  11. data/docs/dsl/{setting/get.md → get.md} +4 -10
  12. data/docs/dsl/{definition/group.md → group.md} +2 -7
  13. data/docs/dsl/{execution/play.md → play.md} +1 -6
  14. data/docs/dsl/{definition/result.md → result.md} +1 -6
  15. data/docs/dsl/{definition/run_remote.md → run.md} +57 -23
  16. data/docs/dsl/{execution/send.md → send.md} +1 -8
  17. data/docs/dsl/{setting/set.md → set.md} +1 -7
  18. data/docs/dsl/{execution/show.md → show.md} +7 -16
  19. data/docs/dsl/target.md +33 -0
  20. data/docs/ideas/todo.md +35 -115
  21. data/docs/learn/01-cmd_new.md +28 -0
  22. data/docs/learn/{01-target.md → 02-target.md} +13 -17
  23. data/docs/learn/03-remote_hosts.md +59 -87
  24. data/docs/learn/04-config.md +147 -0
  25. data/docs/learn/05-use.md +25 -45
  26. data/docs/learn/06-cmd_check.md +50 -0
  27. data/docs/learn/07-target_weight.md +44 -0
  28. data/docs/learn/08-unique_values.md +70 -0
  29. data/docs/learn/09-send.md +20 -0
  30. data/docs/learn/10-debug.md +45 -0
  31. data/docs/learn/11-export.md +35 -0
  32. data/docs/learn/{09-preserve.md → 12-preserve.md} +0 -0
  33. data/docs/learn/{17-hide-feedback.md → 13-feedback.md} +20 -23
  34. data/docs/learn/14-moodle_id.md +24 -0
  35. data/docs/learn/{08-readme.md → 15-readme.md} +5 -9
  36. data/docs/learn/{13-include.md → 16-include.md} +1 -3
  37. data/docs/learn/{14-alias.md → 17-alias.md} +0 -0
  38. data/docs/learn/{07-log.md → 18-log.md} +19 -23
  39. data/docs/learn/{12-get_vars.md → 19-read_vars.md} +3 -3
  40. data/docs/learn/20-macros.md +49 -0
  41. data/docs/learn/{16-exit_codes.md → 21-exit_codes.md} +0 -0
  42. data/docs/learn/{10-result.md → 22-result.md} +3 -3
  43. data/docs/learn/23-test-code.md +54 -0
  44. data/docs/learn/24-test-sql.md +69 -0
  45. data/docs/learn/README.md +24 -18
  46. data/lib/teuton/application.rb +0 -5
  47. data/lib/teuton/case_manager/case/case.rb +1 -1
  48. data/lib/teuton/case_manager/case/dsl/expect.rb +9 -2
  49. data/lib/teuton/case_manager/case/dsl/goto.rb +1 -1
  50. data/lib/teuton/case_manager/case/dsl/log.rb +5 -3
  51. data/lib/teuton/case_manager/case/dsl/target.rb +1 -1
  52. data/lib/teuton/case_manager/case/result/ext_compare.rb +20 -21
  53. data/lib/teuton/case_manager/case/result/ext_filter.rb +15 -8
  54. data/lib/teuton/check/show.rb +1 -1
  55. data/lib/teuton/files/config.yaml +1 -2
  56. data/lib/teuton/files/start.rb +4 -4
  57. data/lib/teuton/readme/dsl.rb +9 -1
  58. data/lib/teuton/readme/readme.rb +8 -1
  59. data/lib/teuton/report/show.rb +8 -0
  60. data/lib/teuton/version.rb +1 -1
  61. metadata +68 -54
  62. data/docs/dsl/definition/run_local.md +0 -33
  63. data/docs/dsl/definition/target.md +0 -40
  64. data/docs/learn/02-config.md +0 -117
  65. data/docs/learn/04-new_test.md +0 -87
  66. data/docs/learn/06-debug.md +0 -110
  67. data/docs/learn/11-moodle_id.md +0 -19
@@ -1,6 +1,6 @@
1
1
  [<< back](README.md)
2
2
 
3
- # Example: 10-result
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.each do |name|
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
- - [01 - Target](01-target.md)
9
- - [02 - Config file](02-config.md)
10
- - [03 - Remote hosts](03-remote_hosts.md)
11
- - [04 - Create new test](04-new_test.md)
12
- - [05 - Use](05-use.md)
13
- - [06 - Debug](06-debug.md)
14
- - [07 - Log](07-log.md)
15
- - [08 - Readme](08-readme.md)
16
- - [09 - Preserve](09-preserve.md)
17
- - [10 - Result object](10-result.md)
18
- - [11 - Moodle ID](11-moodle_id.md)
19
- - [12 - Get vars](12-get_vars.md)
20
- - [13 - Include](13-include.md)
21
- - [14 - Alias](14-alias.md)
22
- - 15 - Macros
23
- - [16 - Exit codes](16-exit_codes.md)
24
- - [17 - Hide feedback](17-hide-feedback.md)
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
 
@@ -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
@@ -99,7 +99,7 @@ class Case
99
99
  @report.head[:tt_members] || "noname"
100
100
  end
101
101
 
102
- alias skip? skip
102
+ alias_method :skip?, :skip
103
103
 
104
104
  private
105
105
 
@@ -54,8 +54,15 @@ module DSL
54
54
  expect2 input, expected: output
55
55
  end
56
56
 
57
- def expect_none(input, args = {})
58
- if input.instance_of? Array
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)
@@ -31,5 +31,5 @@ module DSL
31
31
  run_cmd_on(host)
32
32
  @action[:duration] = (Time.now - start_time).round(3)
33
33
  end
34
- alias on goto
34
+ alias_method :on, :goto
35
35
  end
@@ -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
- @report.lines << "[#{f}] #{s}: #{text}"
15
+ msg = "[#{f}] #{s}: #{text}"
16
+ msg = "[#{f}] #{text}" if s == ""
17
+ @report.lines << msg
16
18
  end
17
- alias msg log
19
+ alias_method :msg, :log
18
20
  end
@@ -12,5 +12,5 @@ module DSL
12
12
  w = args[:weight] || 1.0
13
13
  weight(w)
14
14
  end
15
- alias goal target
15
+ alias_method :goal, :target
16
16
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # This is an extension of Result class
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
- alias eq? eq
26
- alias equal eq
27
- alias equal? eq
28
- alias is_equal? eq
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
- alias neq? neq
48
- alias not_equal neq
49
- alias not_equal? neq
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
- alias greater_or_equal ge
69
- alias greater_or_equal? ge
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
- alias greater gt
89
- alias greater_than gt
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
- alias lesser_or_equal le
110
- alias lesser_or_equal? le
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
- alias lesser lt
130
- alias smaller lt
131
- alias lesser_than lt
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
- alias near_to near_to?
146
- alias near? near_to?
147
- alias near near_to?
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
- # This is an extension of Result class
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
- alias grep find
19
- alias grep! find
20
- alias find! find
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(p_filter)
29
- @alterations << "not_find(#{p_filter})"
28
+ def not_find(filter)
29
+ @alterations << "not_find(#{filter})"
30
30
  return self if @content.size.zero?
31
31
 
32
- @content.reject! { |i| i.include?(p_filter) }
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
- alias grep_v not_find
42
+ alias_method :grep_v, :not_find
36
43
 
37
44
  def since(filter)
38
45
  @alterations << "since(#{filter})"
@@ -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 ["Goto", @stats[:hosts]]
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]]
@@ -1,5 +1,4 @@
1
1
  ---
2
2
  global:
3
3
  cases:
4
- - tt_members: MEMBERS
5
- tt_moodle_id: MOODLE_ID
4
+ - tt_members: NAMES_TO-CHANGE
@@ -1,7 +1,7 @@
1
- group "GROUP NAME" do
2
- target "TARGET_1 DESCRIPTION"
3
- run "COMMAND_1"
4
- expect "TEXT_1"
1
+ group "NAME-TO-CHANGE" do
2
+ target "DESC_TO-CHANGE"
3
+ run "COMMAND_TO-CHANGE"
4
+ expect "TEXT_TO-CHANGE"
5
5
  end
6
6
 
7
7
  play do
@@ -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
 
@@ -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), Application::VERSION)
96
+ puts format(Lang.get(:version), Teuton::VERSION)
90
97
  puts "```"
91
98
  puts "\n"
92
99
  puts "# #{app.test_name}\n"
@@ -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
@@ -1,5 +1,5 @@
1
1
  module Teuton
2
- VERSION = "2.4.1"
2
+ VERSION = "2.4.3"
3
3
  APPNAME = "teuton"
4
4
  GEMNAME = "teuton"
5
5
  DOCKERNAME = "dvarrui/#{GEMNAME}"