teuton 2.4.1 → 2.4.3

Sign up to get free protection for your applications and to get access to all the features.
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}"