diff options
author | Lars Wirzenius <liw@liw.fi> | 2020-05-16 10:04:53 +0300 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2020-05-17 12:11:02 +0300 |
commit | f276c028dd4869a97129140cea28f02f3889ac47 (patch) | |
tree | f354dde229b1cd41e75e3aaa76c9487766bce7c6 | |
parent | 0402565f12623fb56da54e9a9a764edb39129186 (diff) | |
download | subplot-f276c028dd4869a97129140cea28f02f3889ac47.tar.gz |
feat(subplot.md): add acceptance criteria for cleanup functionality
Add acceptance checks for the cleanup functionality, for Python and
Bash templates.
-rw-r--r-- | subplot.md | 185 | ||||
-rw-r--r-- | subplot.py | 30 | ||||
-rw-r--r-- | subplot.yaml | 16 |
3 files changed, 225 insertions, 6 deletions
@@ -691,6 +691,191 @@ then bar was done ~~~~ +## Automatic cleanup in scenarios + +A binding can define a cleanup function, which gets called at the end +of the scenario in reverse order for the successful steps. If a step +fails, all the cleanups for the successful steps are still called. We +test this for every language templat we support. + +~~~{#cleanup.yaml .file .yaml .numberLines} +- given: foo + function: foo + cleanup: foo_cleanup +- given: bar + function: bar + cleanup: bar_cleanup +- given: failure + function: failure + cleanup: failure_cleanup +~~~ + +~~~{#cleanup.py .file .python .numberLines} +def foo(ctx): + pass +def foo_cleanup(ctx): + pass +def bar(ctx): + pass +def bar_cleanup(ctx): + pass +def failure(ctx): + assert 0 +def failure_cleanup(ctx): + pass +~~~ + +~~~{#cleanup.sh .file .bash .numberLines} +foo() { + true +} +foo_cleanup() { + true +} +bar() { + true +} +bar_cleanup() { + true +} +failure() { + return 1 +} +failure_cleanup() { + true +} +~~~ + + +### Cleanup functions gets called on success (Python) + +~~~scenario +given file cleanup-success-python.md +and file cleanup.yaml +and file cleanup.py +when I run sp-codegen --run cleanup-success-python.md -o test.py +then scenario "Cleanup" was run +and step "given foo" was run, and then step "given bar" +and cleanup for "given bar" was run, and then for "given foo" +and program finished successfully +~~~ + + +~~~~~{#cleanup-success-python.md .file .markdown .numberLines} +--- +title: Cleanup +bindings: cleanup.yaml +functions: cleanup.py +template: python +... + +# Cleanup + +~~~scenario +given foo +given bar +~~~ +~~~~~ + + +### Cleanup functions get called on failure (Python) + +~~~scenario +given file cleanup-fail-python.md +and file cleanup.yaml +and file cleanup.py +when I try to run sp-codegen --run cleanup-fail-python.md -o test.py +then scenario "Cleanup" was run +and step "given foo" was run, and then step "given bar" +and cleanup for "given bar" was run, and then for "given foo" +and cleanup for "given failure" was not run +and exit code is non-zero +~~~ + +~~~~~{#cleanup-fail-python.md .file .markdown .numberLines} +--- +title: Cleanup +bindings: cleanup.yaml +functions: cleanup.py +template: python +... + +# Cleanup + +~~~scenario +given foo +given bar +given failure +~~~ +~~~~~ + + +### Cleanup functions gets called on success (Bash) + +~~~scenario +given file cleanup-success-bash.md +and file cleanup.yaml +and file cleanup.sh +when I run sp-codegen --run cleanup-success-bash.md -o test.sh +then scenario "Cleanup" was run +and step "given foo" was run, and then step "given bar" +and cleanup for "given bar" was run, and then for "given foo" +and program finished successfully +~~~ + +~~~~~{#cleanup-success-bash.md .file .markdown .numberLines} +--- +title: Cleanup +bindings: cleanup.yaml +functions: cleanup.sh +template: bash +... + +# Cleanup + +~~~scenario +given foo +given bar +~~~ +~~~~~ + + +### Cleanup functions get called on failure (Bash) + +If a step fails, all the cleanups for the preceding steps are still +called, in reverse order. + +~~~scenario +given file cleanup-fail-bash.md +and file cleanup.yaml +and file cleanup.sh +when I try to run sp-codegen --run cleanup-fail-bash.md -o test.sh +then scenario "Cleanup" was run +and step "given foo" was run, and then step "given bar" +and cleanup for "given bar" was run, and then for "given foo" +and cleanup for "given failure" was not run +and exit code is non-zero +~~~ + +~~~~~{#cleanup-fail-bash.md .file .markdown .numberLines} +--- +title: Cleanup +bindings: cleanup.yaml +functions: cleanup.sh +template: bash +... + +# Cleanup + +~~~scenario +given foo +given bar +given failure +~~~ +~~~~~ + + + ## Capturing parts of steps for functions A scenario step binding can capture parts of a scenario step, to be @@ -35,14 +35,14 @@ def run_docgen_with_date(ctx, md=None, output=None, date=None): exit_code_zero(ctx) -def try_codegen_and_program(ctx, filename=None): +def try_codegen_and_program(ctx, filename=None, testprog=None): codegen = binary("sp-codegen") tmpldir = os.path.join(srcdir, "templates") - runcmd(ctx, [codegen, filename, "-o", "test.py", "--run", "--templates", tmpldir]) + runcmd(ctx, [codegen, filename, "-o", testprog, "--run", "--templates", tmpldir]) -def run_codegen_and_program(ctx, filename=None): - try_codegen_and_program(ctx, filename=filename) +def run_codegen_and_program(ctx, filename=None, testprog=None): + try_codegen_and_program(ctx, filename=filename, testprog=testprog) exit_code_zero(ctx) @@ -111,6 +111,28 @@ def step_was_run(ctx, keyword=None, name=None): stdout_matches(ctx, pattern="\n step: {} {}\n".format(keyword, name)) +def step_was_run_and_then(ctx, keyword1=None, name1=None, keyword2=None, name2=None): + stdout_matches( + ctx, + pattern="\n step: {} {}\n step: {} {}".format( + keyword1, name1, keyword2, name2 + ), + ) + + +def cleanup_was_run(ctx, keyword1=None, name1=None, keyword2=None, name2=None): + stdout_matches( + ctx, + pattern="\n cleanup: {} {}\n cleanup: {} {}\n".format( + keyword1, name1, keyword2, name2 + ), + ) + + +def cleanup_was_not_run(ctx, keyword=None, name=None): + stdout_does_not_match(ctx, pattern="\n cleanup: {} {}\n".format(keyword, name)) + + def exit_code_zero(ctx): if ctx.get("exit") != 0: print("context:", ctx.as_dict()) diff --git a/subplot.yaml b/subplot.yaml index 607e361..8d4187f 100644 --- a/subplot.yaml +++ b/subplot.yaml @@ -17,13 +17,13 @@ - when: I try to run sp-docgen {md} -o {output} function: try_docgen -- when: I run sp-codegen --run {filename} -o test.py +- when: I run sp-codegen --run {filename} -o {testprog} function: run_codegen_and_program - when: I run sp-codegen {filename} -o {testprog} function: run_codegen -- when: I try to run sp-codegen --run {filename} -o test.py +- when: I try to run sp-codegen --run {filename} -o {testprog} function: try_codegen_and_program - when: I run python3 {testprog} {pattern} @@ -84,6 +84,18 @@ function: step_was_run regex: true +- then: step "(?P<keyword1>given|when|then) (?P<name1>.+)" was run, and then step "(?P<keyword2>given|when|then) (?P<name2>.+)" + function: step_was_run_and_then + regex: true + +- then: cleanup for "(?P<keyword1>given|when|then) (?P<name1>.+)" was run, and then for "(?P<keyword2>given|when|then) (?P<name2>.+)" + function: cleanup_was_run + regex: true + +- then: cleanup for "(?P<keyword>given|when|then) (?P<name>.+)" was not run + function: cleanup_was_not_run + regex: true + - then: program finished successfully function: exit_code_zero |