omnitest 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (140) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.gitmodules +0 -0
  4. data/.groc.json +7 -0
  5. data/.rspec +6 -0
  6. data/.rubocop.yml +5 -0
  7. data/.rubocop_todo.yml +47 -0
  8. data/.travis.yml +12 -0
  9. data/.yardopts +3 -0
  10. data/Gemfile +26 -0
  11. data/README.md +341 -0
  12. data/Rakefile +33 -0
  13. data/appveyor.yml +9 -0
  14. data/bin/omnidoc +5 -0
  15. data/bin/omnitask +5 -0
  16. data/bin/omnitest +5 -0
  17. data/bower.json +21 -0
  18. data/doc-src/index.md.tt +341 -0
  19. data/doc-src/project_sets.md.tt +31 -0
  20. data/doc-src/usage/crosstask.md.tt +86 -0
  21. data/doc-src/usage/omnitest.md.tt +87 -0
  22. data/features/bootstrapping.feature +25 -0
  23. data/features/cloning.feature +32 -0
  24. data/features/fixtures/configs/omnitest_sample.yaml +11 -0
  25. data/features/fixtures/configs/skeptic_empty.yaml +12 -0
  26. data/features/fixtures/configs/skeptic_hello_world.yaml +10 -0
  27. data/features/show.feature +38 -0
  28. data/features/states.feature +40 -0
  29. data/features/step_definitions/sdk_steps.rb +22 -0
  30. data/features/support/env.rb +9 -0
  31. data/lib/omnitest.rb +211 -0
  32. data/lib/omnitest/cli.rb +297 -0
  33. data/lib/omnitest/command.rb +103 -0
  34. data/lib/omnitest/command/generate.rb +29 -0
  35. data/lib/omnitest/command/generators/code2doc.rb +79 -0
  36. data/lib/omnitest/command/generators/dashboard.rb +148 -0
  37. data/lib/omnitest/command/generators/documentation.rb +119 -0
  38. data/lib/omnitest/command/list.rb +62 -0
  39. data/lib/omnitest/command/project_action.rb +26 -0
  40. data/lib/omnitest/command/scenario_action.rb +20 -0
  41. data/lib/omnitest/command/show.rb +148 -0
  42. data/lib/omnitest/command/task.rb +27 -0
  43. data/lib/omnitest/command/test.rb +41 -0
  44. data/lib/omnitest/configuration.rb +53 -0
  45. data/lib/omnitest/documentation_generator.rb +68 -0
  46. data/lib/omnitest/project.rb +100 -0
  47. data/lib/omnitest/project_logger.rb +273 -0
  48. data/lib/omnitest/project_set.rb +47 -0
  49. data/lib/omnitest/reporters.rb +27 -0
  50. data/lib/omnitest/reporters/hash_reporter.rb +32 -0
  51. data/lib/omnitest/reporters/json_reporter.rb +12 -0
  52. data/lib/omnitest/reporters/markdown_reporter.rb +26 -0
  53. data/lib/omnitest/reporters/yaml_reporter.rb +12 -0
  54. data/lib/omnitest/run_action.rb +44 -0
  55. data/lib/omnitest/version.rb +3 -0
  56. data/lib/omnitest/workflow.rb +5 -0
  57. data/mkdocs.yml +8 -0
  58. data/omnitest.gemspec +39 -0
  59. data/omnitest.yaml +5 -0
  60. data/resources/assets/angular/angular.min.js +217 -0
  61. data/resources/assets/angular/angular.min.js.map +8 -0
  62. data/resources/assets/angular/json-formatter.min.css +6 -0
  63. data/resources/assets/angular/json-formatter.min.js +7 -0
  64. data/resources/assets/angular/ng-table.map +1 -0
  65. data/resources/assets/angular/ng-table.min.css +3 -0
  66. data/resources/assets/angular/ng-table.min.js +3 -0
  67. data/resources/assets/angular/ui-bootstrap-tpls.min.js +10 -0
  68. data/resources/assets/bootstrap/bootstrap.min.css +9 -0
  69. data/resources/assets/fonts/glyphicons-halflings-regular.eot +0 -0
  70. data/resources/assets/fonts/glyphicons-halflings-regular.svg +229 -0
  71. data/resources/assets/fonts/glyphicons-halflings-regular.ttf +0 -0
  72. data/resources/assets/fonts/glyphicons-halflings-regular.woff +0 -0
  73. data/resources/assets/pygments/autumn.css +58 -0
  74. data/resources/assets/pygments/borland.css +46 -0
  75. data/resources/assets/pygments/bw.css +34 -0
  76. data/resources/assets/pygments/colorful.css +61 -0
  77. data/resources/assets/pygments/default.css +62 -0
  78. data/resources/assets/pygments/emacs.css +61 -0
  79. data/resources/assets/pygments/friendly.css +61 -0
  80. data/resources/assets/pygments/fruity.css +69 -0
  81. data/resources/assets/pygments/github.css +61 -0
  82. data/resources/assets/pygments/manni.css +61 -0
  83. data/resources/assets/pygments/monokai.css +64 -0
  84. data/resources/assets/pygments/murphy.css +61 -0
  85. data/resources/assets/pygments/native.css +69 -0
  86. data/resources/assets/pygments/pastie.css +60 -0
  87. data/resources/assets/pygments/perldoc.css +58 -0
  88. data/resources/assets/pygments/tango.css +69 -0
  89. data/resources/assets/pygments/trac.css +59 -0
  90. data/resources/assets/pygments/vim.css +69 -0
  91. data/resources/assets/pygments/vs.css +33 -0
  92. data/resources/assets/pygments/zenburn.css +1 -0
  93. data/resources/assets/style.css +56 -0
  94. data/resources/code_sample.tt +2 -0
  95. data/resources/generators/dashboard/files/dashboard.html.tt +51 -0
  96. data/resources/generators/dashboard/files/dashboard.js +26 -0
  97. data/resources/generators/dashboard/templates/_test_report.html.haml +91 -0
  98. data/resources/generators/todo/templates/todo.md.tt +6 -0
  99. data/resources/generators/todo/todo_template.rb +1 -0
  100. data/samples/.gitignore +2 -0
  101. data/samples/_markdown.md +5 -0
  102. data/samples/bootstrap.sh +2 -0
  103. data/samples/clone.sh +2 -0
  104. data/samples/code2doc.sh +5 -0
  105. data/samples/default_bootstrap.rb +7 -0
  106. data/samples/detect.sh +2 -0
  107. data/samples/exec.sh +2 -0
  108. data/samples/omnitest.yaml +24 -0
  109. data/samples/omnitest_simple.yaml +8 -0
  110. data/samples/scripts/bootstrap +3 -0
  111. data/samples/show.sh +4 -0
  112. data/samples/skeptic.yaml +13 -0
  113. data/samples/skeptic_simple.yaml +9 -0
  114. data/samples/test.sh +2 -0
  115. data/samples/tests/omnitest/validators.rb +23 -0
  116. data/samples/verify.sh +3 -0
  117. data/scripts/bootstrap.ps1 +7 -0
  118. data/scripts/run_script.sh +4 -0
  119. data/skeptic.yaml +26 -0
  120. data/spec/fabricators/project_fabricator.rb +19 -0
  121. data/spec/fabricators/scenario_fabricator.rb +6 -0
  122. data/spec/fabricators/test_manifest_fabricator.rb +41 -0
  123. data/spec/fabricators/validator_fabricator.rb +12 -0
  124. data/spec/fixtures/factorial.py +18 -0
  125. data/spec/fixtures/omnitest.yaml +11 -0
  126. data/spec/fixtures/skeptic.yaml +16 -0
  127. data/spec/fixtures/src-doc/_scenario.md.erb +1 -0
  128. data/spec/fixtures/src-doc/quine.md.erb +20 -0
  129. data/spec/omnitest/cli_spec.rb +38 -0
  130. data/spec/omnitest/configuration_spec.rb +25 -0
  131. data/spec/omnitest/documentation_generator_spec.rb +59 -0
  132. data/spec/omnitest/file_finder_spec.rb +21 -0
  133. data/spec/omnitest/project_spec.rb +65 -0
  134. data/spec/omnitest_spec.rb +13 -0
  135. data/spec/spec_helper.rb +32 -0
  136. data/spec/thor_spy.rb +66 -0
  137. data/tests/omnitest/bootstrap_validations.rb +7 -0
  138. data/tests/omnitest/show_validations.rb +22 -0
  139. data/yard_macros.rb +25 -0
  140. metadata +470 -0
@@ -0,0 +1,86 @@
1
+ ## Crosstasking (via Psychic)
2
+
3
+ Omnitest needs to be able to run tasks in any of the projects before it can run tests. Omnitest uses [psychic](https://github.com/omnitest/psychic), to run tasks. Psychic creates a uniform interface for running similar tasks in different projects, delegating to project specific task runners (like Rake, Make, npm run, or gradle) when necessary.
4
+
5
+ The first task you probably want to run is `bootstrap` in order to make sure the projects project is ready to test. Generally the `bootstrap` task will invoke a dependency manager like Bundler, npm, or pip.
6
+
7
+ ```sh
8
+ $ bundle exec omnitest bootstrap
9
+ <%= scenario_output_snippet 'omnitest', 'bootstrap', include_command: false, format: :raw %>
10
+ ```
11
+
12
+ ### Custom tasks
13
+
14
+ There are a few default tasks like `bootstrap` that are built into omnitest (and psychic). The default tasks exist to match common test workflows (like the Travis-CI stages or Maven lifecycle), but you can also have omnitest invoke custom tasks.
15
+
16
+ So you could tell omnitest to invoke custom tasks like `documentation`, `metrics`, `lint` or `gitstats`:
17
+
18
+ ```sh
19
+ $ bundle exec omnitest task lint
20
+ -----> Starting Omnitest (v0.2.0)
21
+ -----> Running task lint for ruby
22
+ Executing bundle exec rubocop -D
23
+ warning: parser/current is loading parser/ruby21, which recognizes
24
+ warning: 2.1.5-compliant syntax, but you are running 2.1.4.
25
+ Inspecting 2 files
26
+ ..
27
+
28
+ 2 files inspected, no offenses detected
29
+ -----> Running task lint for java
30
+ Executing gradle checkstyleMain
31
+ :compileJava UP-TO-DATE
32
+ :processResources UP-TO-DATE
33
+ :classes UP-TO-DATE
34
+ :checkstyleMain[ant:checkstyle] /Users/Thoughtworker/repos/rackspace/polytrix/samples/sdks/java/src/main/java/HelloWorld.java:0: Missing package-info.java file.
35
+ [ant:checkstyle] /Users/Thoughtworker/repos/rackspace/polytrix/samples/sdks/java/src/main/java/HelloWorld.java:1: Line is longer than 100 characters (found 101).
36
+ [ant:checkstyle] /Users/Thoughtworker/repos/rackspace/polytrix/samples/sdks/java/src/main/java/HelloWorld.java:3: Missing a Javadoc comment.
37
+ [ant:checkstyle] /Users/Thoughtworker/repos/rackspace/polytrix/samples/sdks/java/src/main/java/Quine.java:1: Missing a Javadoc comment.
38
+ [ant:checkstyle] /Users/Thoughtworker/repos/rackspace/polytrix/samples/sdks/java/src/main/java/Quine.java:2:1: warning: '{' should be on the previous line.
39
+ [ant:checkstyle] /Users/Thoughtworker/repos/rackspace/polytrix/samples/sdks/java/src/main/java/Quine.java:4:3: warning: '{' should be on the previous line.
40
+ [ant:checkstyle] /Users/Thoughtworker/repos/rackspace/polytrix/samples/sdks/java/src/main/java/Quine.java:24: warning: 'for' construct must use '{}'s.
41
+ [ant:checkstyle] /Users/Thoughtworker/repos/rackspace/polytrix/samples/sdks/java/src/main/java/Quine.java:24:8: 'for' is not followed by whitespace.
42
+ [ant:checkstyle] /Users/Thoughtworker/repos/rackspace/polytrix/samples/sdks/java/src/main/java/Quine.java:24:30: warning: ')' is preceded with whitespace.
43
+ [ant:checkstyle] /Users/Thoughtworker/repos/rackspace/polytrix/samples/sdks/java/src/main/java/Quine.java:26: warning: 'for' construct must use '{}'s.
44
+ [ant:checkstyle] /Users/Thoughtworker/repos/rackspace/polytrix/samples/sdks/java/src/main/java/Quine.java:26:8: 'for' is not followed by whitespace.
45
+ [ant:checkstyle] /Users/Thoughtworker/repos/rackspace/polytrix/samples/sdks/java/src/main/java/Quine.java:27:28: warning: '(' is followed by whitespace.
46
+ [ant:checkstyle] /Users/Thoughtworker/repos/rackspace/polytrix/samples/sdks/java/src/main/java/Quine.java:27:54: warning: ')' is preceded with whitespace.
47
+ [ant:checkstyle] /Users/Thoughtworker/repos/rackspace/polytrix/samples/sdks/java/src/main/java/Quine.java:28: warning: 'for' construct must use '{}'s.
48
+ [ant:checkstyle] /Users/Thoughtworker/repos/rackspace/polytrix/samples/sdks/java/src/main/java/Quine.java:28:8: 'for' is not followed by whitespace.
49
+ [ant:checkstyle] /Users/Thoughtworker/repos/rackspace/polytrix/samples/sdks/java/src/main/java/Quine.java:29:28: warning: '(' is followed by whitespace.
50
+ [ant:checkstyle] /Users/Thoughtworker/repos/rackspace/polytrix/samples/sdks/java/src/main/java/Quine.java:29:33: warning: ')' is preceded with whitespace.
51
+ FAILED
52
+
53
+ FAILURE: Build failed with an exception.
54
+
55
+ * What went wrong:
56
+ Execution failed for task ':checkstyleMain'.
57
+ > Checkstyle rule violations were found. See the report at: file:///Users/Thoughtworker/repos/rackspace/polytrix/samples/sdks/java/build/reports/checkstyle/main.xml
58
+
59
+ * Try:
60
+ Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
61
+
62
+ BUILD FAILED
63
+
64
+ Total time: 4.904 secs
65
+ -----> Running task lint for python
66
+ Executing ./scripts/lint.sh
67
+ New python executable in omnitest_python/bin/python
68
+ Installing setuptools, pip...done.
69
+ katas/hello_world.py:2:22: W292 no newline at end of file
70
+ katas/quine.py:2:8: E228 missing whitespace around modulo operator
71
+ -----> Omnitest is finished. (0m8.49s)
72
+ ```
73
+
74
+ This is equivalent to running `psychic task lint` in each directory. See [psychic](https://github.com/omnitest/psychic) for more details about how psychic decides what command to invoke for any given task.
75
+
76
+ ### Workflows
77
+
78
+ Coming soon....
79
+
80
+ A workflow is a group of tasks that you want to run together on each project.
81
+
82
+ The "commit test" workflow is the most common. This is basically a workflow that runs all the tests and checks that should be run before commiting a change. The [Travis-CI lifecycle](http://docs.travis-ci.com/user/build-lifecycle/) and [Maven Lifecycle](http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html) (excluding the "deploy" stage in both cases) are examples.
83
+
84
+ Another workflow I've seen is the "morning" workflow. This workflow makes sure each of the projects are ready to start development. This is often similar to a "commit test" workflow, but it will also make sure you have a clean development environment, have fetched the latest upstream changes (from both version control and dependency management systems).
85
+
86
+ Another possibility would be a "end of sprint" or "pre-release" workflow. This could be very different than the two examples above. It may focus on collecting metrics or building and publishing release notes.
@@ -0,0 +1,87 @@
1
+ ## Omnitesting (via Skeptic)
2
+
3
+ The `omnitest test` command will the same tests in each project, using spies to capture data and validate the behavior. This is for running tests that are shared across all projects to test for shared behavior. You can use `omnitask` to run each projects own test.
4
+
5
+ Currently this is used for testing a code sample for each scenario. Omnitest will run the sample and capture the process's exit code, stdout and stderr. You can register additional "spies" with skeptic in order to capture additional information or perform additional validation. For example, there are spies that use the [Pacto](https://github.com/thoughtworks/pacto) project to capture HTTP requests and compare them with the RESTful services that were expected to be called for the scenario.
6
+
7
+ ### Defining test scenarios
8
+
9
+ Omnitest uses [Skeptic](https://github.com/omnitest/skeptic) to run tests, so the test scenarios are listed in a file called `skeptic.yaml`. The `suites` section of skeptic.yaml defines the tests you want to run. The suites contain scenarios ("samples"). Here is a simple file that defines a few scenarios:
10
+
11
+ <%= file_snippet 'samples/skeptic_simple.yaml' %>
12
+
13
+ You can also define properties for running samples with the "global_env" and "env" on suites. Here's a more complete example that shows defines some properties:
14
+
15
+ <%= file_snippet 'samples/skeptic.yaml' %>
16
+
17
+ ### Available Commands
18
+
19
+ You can always see the available commands by running:
20
+ <%= exec_snippet 'bundle exec omnitest help' %>
21
+
22
+ You can see that most omnitest commands take two optional arguments: `[PROJECT|REGEXP|all] [SCENARIO|REGEXP|all]`. The first selects which projects a command applies to and the second selects which scenarios. See the documentation on [Project Sets](project_sets) for more information about selecting projects with the first parameter. The second argument, for selecting scenarios, has similar behavior:
23
+ - If omitted the command will apply to all scenarios.
24
+ - If a value is provided:
25
+ - If the value is "all" then the command applies to all scenarios. This only exists to make it possible to pass a third parameter, if necessary.
26
+ - If the value exactly matches the name of a scenario then only that scenario will be selected.
27
+ - If it does not match a scenario then it will be used as a regular expression to match other scenarios.
28
+
29
+ ### Listing Tests
30
+
31
+ Omnitest keeps track of the test results so you don't need to test all projects or scenarios in a single run. You can use the command `omnitest list` to get quick summary of the latest results on the command line.
32
+
33
+ <%= exec_snippet 'bundle exec omnitest list', cwd: 'samples' %>
34
+
35
+
36
+ The list command can also illustrate the behavior of the two parameters for narrowing the scope of any omnitest command. For example you could list the results for the ruby project:
37
+
38
+ <%= exec_snippet 'bundle exec omnitest list ruby', cwd: 'samples' %>
39
+
40
+ Or you could list only the quine results for ruby and java:
41
+
42
+ <%= exec_snippet 'bundle exec omnitest list "(ruby|java)" quine', cwd: 'samples' %>
43
+
44
+ ### Running Tests
45
+
46
+ The command `omnitest test` is for testing scenarios. If you run the command `omnitest test` in each project it will test every scenario in all projects. You can narrow the scope of what you want to test by selecting projects with the first parameter and tests with the second parameter.
47
+
48
+ For example, you could just run test quine scenario for the python project:
49
+
50
+ <%= exec_snippet 'bundle exec omnitest test python quine', cwd: 'samples' %>
51
+
52
+ Or, you could run all of the ruby tests:
53
+
54
+ <%= exec_snippet 'bundle exec omnitest test ruby', cwd: 'samples' %>
55
+
56
+ ### Running individual phases
57
+
58
+ The test command actually runs a series of phases. You can run these phases individually, which may be useful if you're still developing the samples or tests and just want to check that they work up to a certain point. If you run any of these phases they will run all of the previous phases but will stop at your target phase.
59
+
60
+ There are two phases that apply at the project level:
61
+ - clone: Make sure the project is available, if it is missing attempt to get it from version control.
62
+ - bootstrap: Run the bootstrap task for the project to install dependenices.
63
+
64
+ And three phases for each scenario:
65
+ - detect: Find the code samples associated with the scenario.
66
+ - exec: Run the code sample and capture the result.
67
+ - verify: Validate the results captured by exec with any validators setup for that scenario.
68
+
69
+ So if you only want to make sure that all of the samples execute, without validating the results to make sure they performed as expected, you could run `omnitest exec`.
70
+
71
+ ### Viewing Detailed Results
72
+
73
+ #### On the Console
74
+
75
+ The command `omnitest show` will display detailed results for the scenarios as text in your console.
76
+
77
+ <%= exec_snippet 'bundle exec omnitest show ruby hello', cwd: 'samples' %>
78
+
79
+ You can get even more information (including the actual code sample that was executed, with syntax highlighting if your console supports color) with the `--verbose` tag:
80
+
81
+ <%= exec_snippet 'bundle exec omnitest show ruby hello --verbose', cwd: 'samples' %>
82
+
83
+ #### Generating HTML reports
84
+
85
+ You can also generate a variety of reports with the `omnidoc` command. The most useful is `omnidoc dashboard`, which will generate a dashboard showing a grid of test results that looks similar to the `omnidoc list` command, where each item is linked to additional details about the result that is similar to the `omnidoc show` command for that scenario.
86
+
87
+ See the [omnidoc](omnidoc) documentation for more details.
@@ -0,0 +1,25 @@
1
+ Feature: Boostrapping
2
+
3
+ Omnitest uses the [script/bootstrap](http://wynnnetherland.com/linked/2013012801/bootstrapping-consistency) pattern to prepare projects for testing. You can hook into any package manager, compiler, build tool, or any other toolchain to prepare to build and run samples.
4
+
5
+ Scenario: Bootstrapping all projects
6
+ Given the ruby project
7
+ And the java project
8
+ And the python project
9
+ And the sample omnitest config
10
+ And the hello_world skeptic config
11
+ When I run `bundle exec omnitest bootstrap`
12
+ Then the output should contain "-----> Bootstrapping java"
13
+ Then the output should contain "-----> Bootstrapping python"
14
+ Then the output should contain "-----> Bootstrapping ruby"
15
+
16
+ Scenario: Bootstrapping selected projects
17
+ Given the ruby project
18
+ And the java project
19
+ And the python project
20
+ And the sample omnitest config
21
+ And the hello_world skeptic config
22
+ When I run `bundle exec omnitest bootstrap "(java|ruby)"`
23
+ Then the output should contain "-----> Bootstrapping java"
24
+ Then the output should not contain "-----> Bootstrapping python"
25
+ Then the output should contain "-----> Bootstrapping ruby"
@@ -0,0 +1,32 @@
1
+ @wip
2
+ Feature: Cloning
3
+
4
+ Omnitest can clone projects from git.
5
+
6
+ Scenario: Cloning all projects
7
+ Given the sample omnitest config
8
+ When I run `bundle exec omnitest clone`
9
+ Then the output should contain "-----> Cloning java"
10
+ Then the output should contain "-----> Cloning python"
11
+ Then the output should contain "-----> Cloning ruby"
12
+
13
+ Scenario: Cloning selected projects
14
+ Given the ruby project
15
+ And the java project
16
+ And the python project
17
+ And the sample omnitest config
18
+ When I run `bundle exec omnitest clone "(java|ruby)"`
19
+ Then the output should contain "-----> Cloning java"
20
+ Then the output should not contain "-----> Cloning python"
21
+ Then the output should contain "-----> Cloning ruby"
22
+
23
+ Scenario: Cloning by scenario
24
+ Given the ruby project
25
+ And the java project
26
+ And the python project
27
+ And the sample omnitest config
28
+ And the hello_world skeptic config
29
+ When I run `bundle exec omnitest clone hello`
30
+ Then the output should contain "-----> Cloning java"
31
+ Then the output should contain "-----> Cloning python"
32
+ Then the output should contain "-----> Cloning ruby"
@@ -0,0 +1,11 @@
1
+ ---
2
+ projects:
3
+ ruby:
4
+ language: 'ruby'
5
+ basedir: 'sdks/ruby'
6
+ java:
7
+ language: 'java'
8
+ basedir: 'sdks/java'
9
+ python:
10
+ language: 'python'
11
+ basedir: 'sdks/python'
@@ -0,0 +1,12 @@
1
+ ---
2
+ global_env:
3
+ LOCALE: <%= ENV['LANG'] %>
4
+ FAVORITE_NUMBER: 5
5
+ suites:
6
+ Katas:
7
+ env:
8
+ NAME: 'Max'
9
+ samples:
10
+ Tutorials:
11
+ env:
12
+ samples:
@@ -0,0 +1,10 @@
1
+ ---
2
+ global_env:
3
+ LOCALE: <%= ENV['LANG'] %>
4
+ FAVORITE_NUMBER: 5
5
+ suites:
6
+ Katas:
7
+ env:
8
+ NAME: 'Max'
9
+ samples:
10
+ - hello world
@@ -0,0 +1,38 @@
1
+ Feature: Show
2
+
3
+ Scenario: Initial state
4
+ Given the ruby project
5
+ And the java project
6
+ And the python project
7
+ And the sample omnitest config
8
+ And the hello_world skeptic config
9
+ When I run `bundle exec omnitest show ruby 'hello world'`
10
+ Then the output should contain:
11
+ """
12
+ katas-hello_world-ruby: <Not Found>
13
+ Test suite: Katas
14
+ Test scenario: hello world
15
+ Project: ruby
16
+ Source: sdks/ruby/katas/hello_world.rb
17
+ """
18
+
19
+ @no-clobber
20
+ Scenario: State after testing
21
+ Given I run `bundle exec omnitest test ruby`
22
+ When I run `bundle exec omnitest show ruby 'hello world'`
23
+ Then the output should contain:
24
+ """
25
+ katas-hello_world-ruby: Fully Verified (1 of 1)
26
+ Test suite: Katas
27
+ Test scenario: hello world
28
+ Project: ruby
29
+ Source: sdks/ruby/katas/hello_world.rb
30
+ Execution result:
31
+ Exit Status: 0
32
+ Stdout:
33
+ Hello, world!
34
+ Stderr:
35
+ Validations:
36
+ default validator: ✓ Passed
37
+ Data from spies:
38
+ """
@@ -0,0 +1,40 @@
1
+ Feature: States
2
+
3
+ Scenario: Initial state
4
+ Given the ruby project
5
+ And the java project
6
+ And the python project
7
+ And the sample omnitest config
8
+ And the hello_world skeptic config
9
+ When I run `bundle exec omnitest list`
10
+ Then the output should contain:
11
+ """
12
+ Suite Scenario Project Status
13
+ Katas hello world ruby <Not Found>
14
+ Katas hello world java <Not Found>
15
+ Katas hello world python <Not Found>
16
+ """
17
+
18
+ @no-clobber
19
+ Scenario: State after execution
20
+ Given I run `bundle exec omnitest exec python`
21
+ When I run `bundle exec omnitest list`
22
+ Then the output should contain:
23
+ """
24
+ Suite Scenario Project Status
25
+ Katas hello world ruby <Not Found>
26
+ Katas hello world java <Not Found>
27
+ Katas hello world python Executed
28
+ """
29
+
30
+ @no-clobber
31
+ Scenario: State after verification
32
+ Given I run `bundle exec omnitest verify ruby`
33
+ When I run `bundle exec omnitest list`
34
+ Then the output should contain:
35
+ """
36
+ Suite Scenario Project Status
37
+ Katas hello world ruby Fully Verified (1 of 1)
38
+ Katas hello world java <Not Found>
39
+ Katas hello world python Executed
40
+ """
@@ -0,0 +1,22 @@
1
+ require 'yaml'
2
+
3
+ Given(/^the (\w+) project$/) do |sdk|
4
+ FileUtils.mkdir_p "#{current_dir}/sdks"
5
+ FileUtils.cp_r "samples/sdks/#{sdk}", "#{current_dir}/sdks"
6
+ end
7
+
8
+ Given(/^the (\w+) omnitest config$/) do |config|
9
+ FileUtils.cp_r "features/fixtures/configs/omnitest_#{config}.yaml", "#{current_dir}/omnitest.yaml"
10
+ end
11
+
12
+ Given(/^the (\w+) skeptic config$/) do |config|
13
+ FileUtils.cp_r "features/fixtures/configs/skeptic_#{config}.yaml", "#{current_dir}/skeptic.yaml"
14
+ end
15
+
16
+ Then(/^the file "(.*?)" should contain yaml matching:$/) do |file, content|
17
+ in_current_dir do
18
+ actual_content = YAML.load(File.read(file))
19
+ expected_content = YAML.load(content)
20
+ expect(actual_content).to eq(expected_content)
21
+ end
22
+ end
@@ -0,0 +1,9 @@
1
+ require 'simplecov'
2
+ SimpleCov.start
3
+
4
+ require 'aruba/cucumber'
5
+ require 'aruba/jruby'
6
+
7
+ Before do
8
+ @aruba_timeout_seconds = RUBY_PLATFORM == 'java' ? 60 : 30
9
+ end
@@ -0,0 +1,211 @@
1
+ require 'omnitest/version'
2
+ require 'omnitest/core'
3
+ require 'omnitest/psychic'
4
+ require 'omnitest/skeptic'
5
+ require 'omnitest/run_action'
6
+ require 'omnitest/project'
7
+ require 'omnitest/workflow'
8
+ require 'omnitest/project_set'
9
+ require 'omnitest/project_logger'
10
+ require 'omnitest/configuration'
11
+ require 'omnitest/documentation_generator'
12
+
13
+ module Omnitest
14
+ include Omnitest::Core::Logger
15
+ include Omnitest::Core::Logging
16
+
17
+ # File extensions that Omnitest can automatically detect/execute
18
+ SUPPORTED_EXTENSIONS = %w(py rb js)
19
+
20
+ module Delegators
21
+ # @api private
22
+ # @!macro delegate_to_skeptic
23
+ # @method $1()
24
+ def delegate_to_skeptic_class(meth)
25
+ define_method(meth) { |*args, &block| Skeptic.public_send(meth, *args, &block) }
26
+ end
27
+
28
+ # @api private
29
+ # @!macro delegate_to_psychic
30
+ # @method $1()
31
+ def delegate_to_psychic_class(meth)
32
+ define_method(meth) { |*args, &block| Psychic.public_send(meth, *args, &block) }
33
+ end
34
+
35
+ # @api private
36
+ # @!macro delegate_to_psychic
37
+ # @method $1()
38
+ def delegate_to_psychic_instance(meth)
39
+ define_method(meth) { |*args, &block| psychic.public_send(meth, *args, &block) }
40
+ end
41
+
42
+ # @api private
43
+ # @!macro delegate_to_projects
44
+ # @method $1()
45
+ def delegate_to_projects(meth)
46
+ define_method(meth) do |*args, &block|
47
+ project_regex = args.shift
48
+ run_action(filter_projects(project_regex), meth, configuration.concurrency, *args, &block)
49
+ end
50
+ end
51
+
52
+ # @api private
53
+ # @!macro delegate_to_scenarios
54
+ # @method $1()
55
+ def delegate_to_scenarios(meth)
56
+ define_method(meth) do |*args, &block|
57
+ project_regex = args.shift
58
+ scenario_regex = args.shift
59
+ scenarios(project_regex, scenario_regex).map { |s| s.public_send(meth, *args, &block) }
60
+ end
61
+ end
62
+ end
63
+
64
+ class << self
65
+ include Core::Configurable
66
+ include RunAction
67
+ extend Delegators
68
+
69
+ DEFAULT_PROJECT_SET_FILE = 'omnitest.yaml'
70
+ DEFAULT_TEST_MANIFEST_FILE = 'skeptic.yaml'
71
+
72
+ # @return [Logger] the common Omnitest logger
73
+ attr_accessor :logger
74
+
75
+ attr_accessor :psychic
76
+
77
+ attr_accessor :wants_to_quit
78
+
79
+ def new_logger(project) # (test, project, index)
80
+ name = project.name # instance_name(test, project)
81
+ index = Omnitest.projects.index(project) || 0
82
+ ProjectLogger.new(
83
+ stdout: STDOUT,
84
+ color: Core::Color::COLORS[index % Core::Color::COLORS.size].to_sym,
85
+ logdev: File.join(Omnitest.configuration.log_root, "#{name}.log"),
86
+ level: Omnitest::Core::Util.to_logger_level(Omnitest.configuration.log_level),
87
+ progname: name
88
+ )
89
+ end
90
+
91
+ def basedir
92
+ @basedir ||= psychic.basedir
93
+ end
94
+
95
+ # @private
96
+ def trap_interrupt
97
+ trap('INT') do
98
+ exit!(1) if Omnitest.wants_to_quit
99
+ Omnitest.wants_to_quit = true
100
+ STDERR.puts "\nInterrupt detected... Interrupt again to force quit."
101
+ end
102
+ end
103
+
104
+ def update_config!(options)
105
+ trap_interrupt
106
+ @logger = Omnitest.default_file_logger
107
+ project_set_file = options.file || DEFAULT_PROJECT_SET_FILE
108
+ @basedir = File.dirname project_set_file
109
+ skeptic_file = options.skeptic || DEFAULT_TEST_MANIFEST_FILE
110
+
111
+ Omnitest.configure do | config |
112
+ config.concurrency = options.concurrency
113
+ config.log_level = options.log_level || :info
114
+ config.project_set = project_set_file
115
+ config.skeptic.manifest_file = skeptic_file
116
+ config.travis = options.travis if options.respond_to? :travis
117
+ end
118
+ @test_dir = options.test_dir || File.expand_path('tests/omnitest/', @basedir)
119
+ end
120
+
121
+ delegate_to_skeptic_class :validate
122
+
123
+ delegate_to_projects :task
124
+
125
+ delegate_to_projects :workflow
126
+
127
+ delegate_to_projects :clone
128
+
129
+ delegate_to_projects :bootstrap
130
+
131
+ delegate_to_scenarios :test
132
+
133
+ delegate_to_scenarios :clear
134
+
135
+ delegate_to_scenarios :code2doc
136
+
137
+ Skeptic::Scenario::FSM::TRANSITIONS.each do | transition |
138
+ delegate_to_scenarios transition
139
+ end
140
+
141
+ def setup
142
+ # This autoload should probably be in Skeptic's initializer...
143
+ autoload_omnitest_files(@test_dir) unless @test_dir.nil? || !File.directory?(@test_dir)
144
+ end
145
+
146
+ def scenarios(project_regexp = 'all', scenario_regexp = 'all', options = {})
147
+ filtered_projects = filter_projects(project_regexp, options)
148
+ filtered_scenarios = filtered_projects.map(&:skeptic).flat_map do | skeptic |
149
+ skeptic.scenarios scenario_regexp, options
150
+ end
151
+
152
+ fail UserError, "No scenarios for regex `#{scenario_regexp}', try running `omnitest list'" if filtered_scenarios.empty?
153
+ filtered_scenarios
154
+ end
155
+
156
+ def filter_projects(regexp = 'all', _options = {})
157
+ return Omnitest.projects if regexp.nil? || regexp == 'all'
158
+
159
+ filtered_projects = Omnitest.projects.find { |s| s.name == regexp }
160
+ return [filtered_projects] if filtered_projects
161
+
162
+ filtered_projects ||= Omnitest.projects.select { |s| s.name =~ /#{regexp}/i }
163
+ fail UserError, "No projects matching regex `#{regexp}', known projects: #{Omnitest.projects.map(&:name)}" if filtered_projects.empty?
164
+
165
+ filtered_projects
166
+ end
167
+
168
+ # Returns a default file logger which emits on standard output and to a
169
+ # log file.
170
+ #
171
+ # @return [Logger] a logger
172
+ def default_file_logger
173
+ logfile = File.expand_path(File.join('.omnitest', 'logs', 'omnitest.log'))
174
+ ProjectLogger.new(stdout: $stdout, logdev: logfile, level: Core::Util.to_logger_level(configuration.log_level))
175
+ end
176
+
177
+ # The {Omnitest::TestManifest} that describes the test scenarios known to Omnitest.
178
+ def manifest
179
+ configuration.skeptic.manifest
180
+ end
181
+
182
+ # The set of {Omnitest::Project}s registered with Omnitest.
183
+ def projects
184
+ configuration.project_set.projects.values
185
+ end
186
+
187
+ # @api private
188
+ def psychic
189
+ @psychic ||= Omnitest::Psychic.new(cwd: Omnitest.basedir, logger: logger, travis: Omnitest.configuration.travis)
190
+ end
191
+
192
+ # Returns whether or not standard output is associated with a terminal
193
+ # device (tty).
194
+ #
195
+ # @return [true,false] is there a tty?
196
+ def tty?
197
+ $stdout.tty?
198
+ end
199
+
200
+ protected
201
+
202
+ def autoload_omnitest_files(dir)
203
+ $LOAD_PATH.unshift dir
204
+ Dir["#{dir}/**/*.rb"].each do | file_to_require |
205
+ # TODO: Need a better way to skip generators or only load validators
206
+ next if file_to_require.match %r{generators/.*/files/}
207
+ require Omnitest::Core::FileSystem.relativize(file_to_require, dir).to_s.gsub('.rb', '')
208
+ end
209
+ end
210
+ end
211
+ end