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
data/docs/learn/05-use.md CHANGED
@@ -1,39 +1,28 @@
1
1
  [<< back](README.md)
2
2
 
3
- # Example: 05-use
3
+ # use
4
4
 
5
- Learn how to:
6
- * Organize huge amount of groups/targets into several files.
7
- * Checking Windows OS infrastructure (host1).
5
+ `use` keyword allow us organize huge amount of groups/targets into several files.
8
6
 
9
- 1. [Tree directory](#tree-directory)
10
- 2. [Execution section](#execution-section)
11
- 3. [Users file](#users-file)
12
- 4. [Network file](#network-file)
7
+ ## Example
13
8
 
14
- ## Tree directory
15
-
16
- This example has more files:
9
+ > This example requires Windows OS on remote machine.
17
10
 
18
11
  ```bash
19
- > tree example/04-use
20
-
21
- example/04-require
12
+ tree examples/05-use
13
+ examples/05-use
14
+ ├── lib
15
+ │   ├── network.rb
16
+ │   └── users.rb
22
17
  ├── config.yaml
23
- ├── network.rb
24
- ├── README.md
25
- ├── start.rb
26
- └── users.rb
18
+ └── start.rb
27
19
  ```
28
20
 
29
- ## Execution section
30
-
31
- Previous `start.rb` file is now splited in: start.rb, users.rb and network.rb.
32
-
33
- Let's see current `start.rb` file:
21
+ * `start.rb` file is now splited into: `start.rb`, `users.rb` and `network.rb`.
34
22
 
35
23
  ```ruby
36
- use 'users'
24
+ # File: start.rb
25
+ use 'lib/users'
37
26
  use 'network'
38
27
 
39
28
  play do
@@ -42,40 +31,31 @@ play do
42
31
  end
43
32
  ```
44
33
 
45
- * `use`, indicates external rb file that will be included/imported into main rb file. It's a good idea to organize project files, when the number of groups/targets is high.
46
-
47
- ## Users file
48
-
49
- > Require Windows OS on remote machine.
34
+ * `use`, indicates that we require external file, that will be imported into our start.rb file.
35
+ * Notice that you can specify relative route `use 'lib/users'`, or only filename `use 'network'`. In the second case, teuton will search a file with that name into project folders.
50
36
 
51
- Let's see `users.rb` file
37
+ > It's a good idea to organize project files, when the number of groups/targets is high.
52
38
 
53
39
  ```ruby
54
- group "Use file: User configuration" do
40
+ # File: users.rb
55
41
 
56
- target "Create user #{gett(:username)}"
42
+ group "Using file: users" do
43
+ target "Create user #{get(:username)}"
57
44
  run "net user", on: :host1
58
45
  expect get(:username)
59
-
60
46
  end
61
47
  ```
62
48
 
63
- ## Network file
64
-
65
- > Require Windows OS on remote machine.
66
-
67
- Let's see `network.rb` file:
68
-
69
49
  ```ruby
70
- group "Use file: Network configuracion" do
50
+ # File: network.rb
71
51
 
72
- target "Update computer name with #{gett(:host1_hostname)}"
52
+ group "Using file: network" do
53
+ target "Update computer name with #{get(:hostname)}"
73
54
  run "hostname", on: :host1
74
- expect_one get(:host1_hostname)
55
+ expect_one get(:hostname)
75
56
 
76
57
  target "Ensure DNS Server is working"
77
- run "nslookup www.google.es", on: :host1
78
- expect "Nombre:"
79
-
58
+ run "host www.google.es", on: :host1
59
+ expect "www.google.es has address "
80
60
  end
81
61
  ```
@@ -0,0 +1,50 @@
1
+
2
+ [<< back](README.md)
3
+
4
+ # check test
5
+
6
+ Check Teuton test syntax and show statistics.
7
+
8
+ ```
9
+ ❯ teuton check examples/05-use
10
+
11
+ +--------------------------+
12
+ | GROUP: Using file: users |
13
+ +--------------------------+
14
+ (001) target Create user get(username)
15
+ weight 1.0
16
+ run 'id get(username)' on host1
17
+ expect get(username) (String)
18
+
19
+ +----------------------------+
20
+ | GROUP: Using file: network |
21
+ +----------------------------+
22
+ (002) target Update computer name with get(hostname)
23
+ weight 1.0
24
+ run 'hostname' on host1
25
+ expect_one get(hostname) (String)
26
+
27
+ (003) target Ensure DNS Server is working
28
+ weight 1.0
29
+ run 'host www.google.es' on host1
30
+ expect www.google.es has address (String)
31
+
32
+ +-------------+-------+
33
+ | DSL Stats | Count |
34
+ +-------------+-------+
35
+ | Groups | 2 |
36
+ | Targets | 3 |
37
+ | Runs | 3 |
38
+ | * host1 | 3 |
39
+ | Uniques | 0 |
40
+ | Logs | 0 |
41
+ | | |
42
+ | Gets | 5 |
43
+ | * username | 3 |
44
+ | * hostname | 2 |
45
+ | Sets | 0 |
46
+ +-------------+-------+
47
+ +----------------------+
48
+ | Revising CONFIG file |
49
+ +----------------------+
50
+ ```
@@ -0,0 +1,44 @@
1
+ [<< back](README.md)
2
+
3
+ # Target weight
4
+
5
+ * Changing default target weight:
6
+
7
+ ```ruby
8
+ # File: network.rb
9
+
10
+ group "Using file: network" do
11
+ target "Update computer name with #{get(:hostname)}"
12
+ run "hostname", on: :host1
13
+ expect_one get(:hostname)
14
+
15
+ target "Ensure DNS Server is working", weight: 2.0
16
+ run "host www.google.es", on: :host1
17
+ expect "www.google.es has address "
18
+ end
19
+ ```
20
+
21
+ ```
22
+ ❯ teuton check examples/07-target_weight
23
+
24
+ +--------------------------+
25
+ | GROUP: Using file: users |
26
+ +--------------------------+
27
+ (001) target Create user get(username)
28
+ weight 1.0
29
+ run 'id get(username)' on host1
30
+ expect get(username) (String)
31
+
32
+ +----------------------------+
33
+ | GROUP: Using file: network |
34
+ +----------------------------+
35
+ (002) target Update computer name with get(hostname)
36
+ weight 1.0
37
+ run 'hostname' on host1
38
+ expect_one get(hostname) (String)
39
+
40
+ (003) target Ensure DNS Server is working
41
+ weight 2.0
42
+ run 'host www.google.es' on host1
43
+ expect www.google.es has address (String)
44
+ ```
@@ -0,0 +1,70 @@
1
+ [<< back](README.md)
2
+
3
+ # Unique value
4
+
5
+ * `unique NAME, VALUE` keyword defines unique values.
6
+ * All cases that do not comply with this requirement will obtain a score of 0 and it will be reflected in the reports.
7
+
8
+ Example:
9
+
10
+ ```ruby
11
+ # File: lib/unique.rb
12
+
13
+ group "Unique value: hostname" do
14
+ run "hostname -f", on: :host1
15
+
16
+ unique "Host name", result.value
17
+ end
18
+ ```
19
+
20
+ Cheking test:
21
+
22
+ ```
23
+ ❯ teuton check examples/08-unique_values
24
+
25
+ +--------------------------+
26
+ | GROUP: Using file: users |
27
+ +--------------------------+
28
+ (001) target Create user get(username)
29
+ weight 1.0
30
+ run 'id get(username)' on host1
31
+ expect get(username) (String)
32
+
33
+ +----------------------------+
34
+ | GROUP: Using file: network |
35
+ +----------------------------+
36
+ (002) target Update computer name with get(hostname)
37
+ weight 1.0
38
+ run 'hostname' on host1
39
+ expect_one get(hostname) (String)
40
+
41
+ (003) target Ensure DNS Server is working
42
+ weight 2.0
43
+ run 'host www.google.es' on host1
44
+ expect www.google.es has address (String)
45
+
46
+ +-------------------------------+
47
+ | GROUP: Unique value: hostname |
48
+ +-------------------------------+
49
+ run 'hostname -f' on host1
50
+ ! Unique value for <Host name>
51
+
52
+ +-------------+-------+
53
+ | DSL Stats | Count |
54
+ +-------------+-------+
55
+ | Groups | 3 |
56
+ | Targets | 3 |
57
+ | Runs | 4 |
58
+ | * host1 | 4 |
59
+ | Uniques | 1 |
60
+ | Logs | 1 |
61
+ | | |
62
+ | Gets | 5 |
63
+ | * username | 3 |
64
+ | * hostname | 2 |
65
+ | Sets | 0 |
66
+ +-------------+-------+
67
+ +----------------------+
68
+ | Revising CONFIG file |
69
+ +----------------------+
70
+ ```
@@ -0,0 +1,20 @@
1
+ [<< back](README.md)
2
+
3
+ # Send
4
+
5
+ * [export](../dsl/export.md) keyword generate reports into diferents formats:
6
+ * [send](../dsl/send.md) keyword send report copies to every remote host.
7
+
8
+ ## Example
9
+
10
+ ```ruby
11
+ play do
12
+ show
13
+ export
14
+ send copy_to: :host1
15
+ end
16
+ ```
17
+
18
+ * `show`, show process log on screen.
19
+ * `export`, create reports with `txt` format.
20
+ * `send copy_to: :host1`, copy output report into remote machine (host1).
@@ -0,0 +1,45 @@
1
+ [<< back](README.md)
2
+
3
+ # debug
4
+
5
+ * Debug your tests.
6
+
7
+ ```
8
+ > tree examples/10-debug
9
+
10
+ examples/10-debug
11
+ ├── config.yaml
12
+ ├── external.rb
13
+ ├── internal.rb
14
+ └── start.rb
15
+ ```
16
+
17
+ Tests grows and becames huge, with a lot of targets (That isn't a problem). Then, we organize them spliting into several files and invoke `use` keywork from our main rb file to load other files (That's good idea).
18
+
19
+ Sometimes we need to verify or check rb file consistency and syntax, and we will do it with `teuton check PATH/TO/PROJECT/FOLDER`.
20
+
21
+ ## Debug
22
+
23
+ Every time we invoke `run` keywork, an OS command is executed. The output is showed on screen and saved into **result** internal object.
24
+
25
+ We could debug it invoking `result.debug` into our tests. Let's see an example from `external.rb` file:
26
+
27
+ ```ruby
28
+ # File: external.rb
29
+
30
+ group "Windows: external configuration from localhost" do
31
+
32
+ target "From localhost, check if exist connectivity with #{get(:windows_ip)}"
33
+ run "ping #{get(:windows_ip)} -c 1"
34
+ result.debug
35
+ expect_one "0% packet loss"
36
+ result.debug
37
+
38
+ target "From localhost, check if Netbios-ssn service working on #{get(:windows_ip)}"
39
+ run "nmap -Pn #{get(:windows_ip)}"
40
+ expect "139/tcp", "open"
41
+
42
+ end
43
+ ```
44
+
45
+ `result.debug` it's usefull when you are verifying command output captured by Teuton.
@@ -0,0 +1,35 @@
1
+ [<< back](README.md)
2
+
3
+ # Export
4
+
5
+ * [export](../dsl/export.md) keyword generate reports into diferents formats:
6
+
7
+ Example
8
+ ```ruby
9
+ play do
10
+ show
11
+ export format: :txt
12
+ export format: :html
13
+ export format: :json
14
+ end
15
+ ```
16
+
17
+ * `show`, show process on screen.
18
+ * `export format: :txt`, create reports with `txt` format.
19
+ * `export format: :html`, create reports with `html` format.
20
+ * `export format: :json`, create reports with `json` format.
21
+
22
+ Firs run `teuton examples/11-export`, then we have:
23
+
24
+ ```
25
+ ❯ tree var/11-export
26
+
27
+ var/11-export
28
+ ├── case-01.html
29
+ ├── case-01.json
30
+ ├── case-01.txt
31
+ ├── moodle.csv
32
+ ├── resume.html
33
+ ├── resume.json
34
+ └── resume.txt
35
+ ```
File without changes
@@ -1,12 +1,22 @@
1
1
  [<< back](README.md)
2
2
 
3
- # Example: 17-hide-feedback
3
+ # Feedback
4
4
 
5
- When exporting with `feedback: false` option we hide some items from exported reports. Hiden items: command, alterations, expected and result.
5
+ Exporting with false feedback option `export feedback: false`, hide some items from output reports. Hiden items: command, alterations, expected and result.
6
6
 
7
7
  > More information about [export](../dsl/execution/export.md) keyword.
8
8
 
9
- ## Explanation
9
+ Example
10
+
11
+ ```ruby
12
+ play do
13
+ show
14
+ export feedback: false
15
+ export format: "html", feedback: false
16
+ end
17
+ ```
18
+
19
+ ## Description
10
20
 
11
21
  Every time teuton is run, all cases are evaluated and when exporting the results, by default, all the information collected during the evaluation process is logged.
12
22
 
@@ -20,33 +30,20 @@ Each "target" contains the following fields:
20
30
  Some of these fields should always be visible, such as: id, description, check, score, and weight. And others, more related to the process that perform teuton for verification can be hidden using the "feedback: false" parameter.
21
31
 
22
32
  With "feedback: false" the fields are hidden: command, alterations, expected and result.
23
- Más información sobre este texto de origen
24
- Para obtener más información sobre la traducción, se necesita el texto de origen
25
- Enviar comentarios
26
- Paneles laterales
27
33
 
28
- ## Execution section
29
-
30
- Take a look at our test execution section (Play):
31
- ```ruby
32
- play do
33
- show
34
- export feedback: false
35
- end
36
- ```
37
34
 
38
- ## Result
35
+ ## Results
39
36
 
40
- Executing `teuton run example/17-hide-feedback`:
37
+ Executing `teuton run examples/13-feedback`, we get this output:
41
38
 
42
39
  ```
43
40
  GROUPS
44
- - Hide feedback from reports
41
+ - Preserve output reports
45
42
  01 (1.0/1.0)
46
- Description : Exits user root
47
- Command : *******
43
+ Description : Exits user david
44
+ Command : ********
48
45
  Duration : 0.002 (local)
49
- Alterations : ******************
46
+ Alterations : *******************
50
47
  Expected : ************** (String)
51
- Result : * (Integer)
48
+ Result : ******** (String)
52
49
  ```
@@ -0,0 +1,24 @@
1
+ [<< back](README.md)
2
+
3
+ # Moodle
4
+
5
+ As a teacher, probably you are using Moodle platform. So, you want to upload the results of the evaluation carried out by Teuton into Moodle.
6
+
7
+ Teuton generates a file called `moodle.csv` with the grades of each student into CSV format. This file is suitable to import into Moodle platform.
8
+
9
+ ## tt_moodle_id
10
+
11
+ Add a new field called `tt_moodle_id` to each case in "config.yaml". Fill it with the student's identification (For example, the email registered on the Moodle, or ID number, etc.).
12
+
13
+ Example:
14
+
15
+ ```
16
+ global:
17
+ cases:
18
+ - tt_members: Darth Vader
19
+ tt_moodle_id: vader@starwars.com
20
+ - tt_members: Obiwan Kenobi
21
+ tt_moodle_id: obiwan@starwars.com
22
+ ```
23
+
24
+ Now, when running test "moodle.csv" will be generated with all student grades.
@@ -4,10 +4,6 @@
4
4
 
5
5
  Create README files (with test instructions) from our test definition.
6
6
 
7
- 1. [Definition section](#definition-section)
8
- 2. [Execute command](#execute-command)
9
- 3. [Result](#result)
10
-
11
7
  ## Definition section
12
8
 
13
9
  Take a look at our test definition section (Group):
@@ -35,23 +31,23 @@ There exists some `readme` instructions after `group` and `target` lines.
35
31
  To generate automatically a README file from previous test, execute this:
36
32
 
37
33
  ```
38
- teuton readme example/08-readme > example/08-readme/README.md
34
+ teuton readme example/15-readme > example/15-readme/README.md
39
35
  ```
40
36
 
41
37
  ## Result
42
38
 
43
- **Let's see the output**: Content of `example/08-readme/README.md` file.
39
+ **Let's see the output**: Content of `example/15-readme/README.md` file.
44
40
 
45
41
  ---
46
- # 08-readme
42
+
43
+ # 15-readme
47
44
 
48
45
  ## Customize readme output
49
46
 
50
- This is our README example.
47
+ This is our readme example.
51
48
  And here we'll see how to use readme keyword
52
49
 
53
50
  Go to [LOCALHOST](#required-hosts) host, and do next:
54
51
  * Create user david.
55
52
  * Help: you can use 'useradd' command to create users.
56
53
  * Remember: Only root is permitted to create new users.
57
- ---
@@ -1,11 +1,9 @@
1
1
  [<< back](README.md)
2
2
 
3
- # Example: 13-include
3
+ # include
4
4
 
5
5
  Use `tt-include` to include several config files into your main config file.
6
6
 
7
- ## Explanation
8
-
9
7
  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.
10
8
 
11
9
  Suppose we have the following file structure.
File without changes
@@ -1,33 +1,27 @@
1
1
  [<< back](README.md)
2
2
 
3
- # Example: 07-log
3
+ # 18-log
4
4
 
5
- Let's learn how to create log messages.
5
+ * `log TEXT`, save TEXT into output report.
6
6
 
7
- 1. [Definition section](#definition-section)
8
- 2. [Run test](#execution-section)
9
- 3. [Result](#result)
7
+ Example
10
8
 
11
- ## Definition section
12
-
13
- Test definition section (Group):
14
9
  ```ruby
15
10
  group "Learning about log messages" do
16
- log 'Using log messages...'
11
+ log "Using log messages."
17
12
 
18
13
  target "Create user david"
19
- run "id david"
14
+ run "id david"
15
+ log result.value
20
16
  expect "david"
21
17
 
22
- log 'Problem detected!', :error
18
+ log "Problem detected!", :error
19
+ log "This is a warning", :warn
20
+ log "Hi, there!", :info
23
21
  end
24
22
  ```
25
23
 
26
- > In this example, localhost's OS must be GNU/Linux (any other compatible OS) because the command used is `id david`.
27
-
28
- ## Result
29
-
30
- **Let's see example**: Content of `var/07-log/case-01.txt` file.
24
+ Content of `var/18-log/case-01.txt` file.
31
25
 
32
26
  ```
33
27
  CONFIGURATION
@@ -35,12 +29,15 @@ CONFIGURATION
35
29
  | tt_members | anonymous |
36
30
  | tt_sequence | false |
37
31
  | tt_skip | false |
38
- | tt_testname | 07-log |
32
+ | tt_testname | 18-log |
39
33
  +-------------+-----------+
40
34
 
41
35
  LOGS
42
- [13:45:02] : Using log messages...
43
- [13:45:02] ERROR: Problem detected!
36
+ [09:14:22] INFO: Using log messages.
37
+ [09:14:22] INFO: uid=1000(david) gid=1000(david) grupos=495(cdrom),493(disk),487(video),474(wheel),464(wireshark),459(docker),456(vboxusers),1000(david)
38
+ [09:14:22] ERROR: Problem detected!
39
+ [09:14:22] WARN!: This is a warning
40
+ [09:14:22] INFO: Hi, there!
44
41
 
45
42
  GROUPS
46
43
  - Learning about log messages
@@ -55,9 +52,9 @@ GROUPS
55
52
  RESULTS
56
53
  +--------------+---------------------------+
57
54
  | case_id | 01 |
58
- | start_time | 2022-12-24 13:45:02 +0000 |
59
- | finish_time | 2022-12-24 13:45:02 +0000 |
60
- | duration | 0.001900685 |
55
+ | start_time | 2023-01-26 09:14:22 +0000 |
56
+ | finish_time | 2023-01-26 09:14:22 +0000 |
57
+ | duration | 0.002012326 |
61
58
  | unique_fault | 0 |
62
59
  | max_weight | 1.0 |
63
60
  | good_weight | 1.0 |
@@ -65,4 +62,3 @@ RESULTS
65
62
  | fail_counter | 0 |
66
63
  | grade | 100 |
67
64
  +--------------+---------------------------+
68
- ```
@@ -1,10 +1,10 @@
1
1
  [<< back](README.md)
2
2
 
3
- # Example: 12-get_vars
3
+ # Read vars
4
4
 
5
- To read the variables from the configuration file we already have the `get` statement. Example, to read `dirname` we do `get(:dirname)`.
5
+ To get paramm values from the configuration file we already have the `get` statement. Example, to read `dirname` we do `get(:dirname)`.
6
6
 
7
- **Example 1:** Using `get` to read vars.
7
+ **Example 1:** Using `get` to get values.
8
8
 
9
9
  ```ruby
10
10
  # "get(:dirname)" reads dirname var from config file
@@ -0,0 +1,49 @@
1
+ [<< back](README.md)
2
+
3
+ # Macros
4
+
5
+ Macros is a technique to make it easier to write and reuse code.
6
+
7
+ **Example**
8
+
9
+ * We start from a set of repeated targets.
10
+
11
+ ```ruby
12
+ target "Exist user fran"
13
+ run "id fran"
14
+ expect_one "root"
15
+
16
+ target "Exist user root"
17
+ run "id root"
18
+ expect_one "root"
19
+
20
+ target "Exist user david"
21
+ run "id david"
22
+ expect_one "david"
23
+ ```
24
+
25
+ * Define a macro with the repeated block:
26
+
27
+ ```ruby
28
+ define_macro "user_exists", :name do
29
+ target "Exist user #{get(:name)}"
30
+ run "id #{get(:name)}"
31
+ expect_one get(:name)
32
+ end
33
+ ```
34
+
35
+ * Replace the previous targets with macro calls. There are 3 ways to invoke the macro:
36
+
37
+ ```ruby
38
+ user_exists(name: "fran")
39
+ user_exists(name: "root")
40
+ user_exists(name: "david")
41
+ ```
42
+
43
+ **Notice**: There are 3 ways to invoke the macro:
44
+
45
+ ```ruby
46
+ user_exists(name: "fran")
47
+ macro "user_exists", name: "fran"
48
+ macro_user_exists(name: "fran")
49
+ ```
File without changes