From fc0481c1d8a33a7efa0a2247f897671a118bba75 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Sun, 14 Jul 2013 19:23:43 +0100 Subject: Implement ASSUMING --- yarn | 42 ++++++++++++++++++++++++-------------- yarn.tests/assuming-failure.script | 23 +++++++++++++++++++++ yarn.tests/assuming.script | 23 +++++++++++++++++++++ yarn.tests/setup | 3 +++ yarnlib/block_parser.py | 4 ++++ yarnlib/block_parser_tests.py | 24 ++++++++++++---------- 6 files changed, 93 insertions(+), 26 deletions(-) create mode 100755 yarn.tests/assuming-failure.script create mode 100755 yarn.tests/assuming.script create mode 100755 yarn.tests/setup diff --git a/yarn b/yarn index fb6e5a3..6845345 100755 --- a/yarn +++ b/yarn @@ -22,6 +22,7 @@ import logging import os import re import shutil +import sys import tempfile import time import ttystatus @@ -225,36 +226,47 @@ class YarnRunner(cliapp.Application): os.mkdir(datadir) self.info('DATADIR is %s' % datadir) + assuming = [s for s in scenario.steps if s.what == 'ASSUMING'] cleanup = [s for s in scenario.steps if s.what == 'FINALLY'] - normal = [s for s in scenario.steps if s not in cleanup] + normal = [s for s in scenario.steps if s not in assuming + cleanup] ok = True step_number = 0 - for step in normal: - exit = self.run_step(datadir, scenario, step, shell_prelude) + for step in assuming: + exit = self.run_step(datadir, scenario, step, shell_prelude, False) step_number += 1 self.snapshot_datadir( tempdir, datadir, scenario, step_number, step) if exit != 0: - ok = False - break - - for step in cleanup: - exit = self.run_step(datadir, scenario, step, shell_prelude) - step_number += 1 - self.snapshot_datadir( - tempdir, datadir, scenario, step_number, step) - if exit != 0: - ok = False break + else: + for step in normal: + exit = self.run_step( + datadir, scenario, step, shell_prelude, True) + step_number += 1 + self.snapshot_datadir( + tempdir, datadir, scenario, step_number, step) + if exit != 0: + ok = False + break + + for step in cleanup: + exit = self.run_step( + datadir, scenario, step, shell_prelude, True) + step_number += 1 + self.snapshot_datadir( + tempdir, datadir, scenario, step_number, step) + if exit != 0: + ok = False + break if not self.settings['snapshot']: shutil.rmtree(tempdir) return ok - def run_step(self, datadir, scenario, step, shell_prelude): + def run_step(self, datadir, scenario, step, shell_prelude, report_error): self.info('Running step "%s %s"' % (step.what, step.text)) self.ts['step'] = step self.ts['step_name'] = '%s %s' % (step.what, step.text) @@ -281,7 +293,7 @@ class YarnRunner(cliapp.Application): else: logging.debug('Standard error: empty') - if exit != 0: + if exit != 0 and report_error: self.error( 'ERROR: In scenario "%s"\nstep "%s %s" failed,\n' 'with exit code %d:\n' diff --git a/yarn.tests/assuming-failure.script b/yarn.tests/assuming-failure.script new file mode 100755 index 0000000..f630294 --- /dev/null +++ b/yarn.tests/assuming-failure.script @@ -0,0 +1,23 @@ +#!/bin/sh + +set -eu + + +cat < "$DATADIR/test.yarn" + SCENARIO foo + ASSUMING something + THEN remember + FINALLY cleanup + + IMPLEMENTS ASSUMING something + false + IMPLEMENTS THEN remember + touch "$DATADIR/then-flag" + IMPLEMENTS FINALLY cleanup + touch "$DATADIR/cleanup-flag" +EOF + +./yarn -q "$DATADIR/test.yarn" +[ ! -e "$DATADIR/then-flag" ] +[ ! -e "$DATADIR/cleanup-flag" ] + diff --git a/yarn.tests/assuming.script b/yarn.tests/assuming.script new file mode 100755 index 0000000..9471280 --- /dev/null +++ b/yarn.tests/assuming.script @@ -0,0 +1,23 @@ +#!/bin/sh + +set -eu + + +cat < "$DATADIR/test.yarn" + SCENARIO foo + ASSUMING something + THEN remember + FINALLY cleanup + + IMPLEMENTS ASSUMING something + true + IMPLEMENTS THEN remember + touch "$DATADIR/then-flag" + IMPLEMENTS FINALLY cleanup + touch "$DATADIR/cleanup-flag" +EOF + +./yarn -q "$DATADIR/test.yarn" +[ -e "$DATADIR/then-flag" ] +[ -e "$DATADIR/cleanup-flag" ] + diff --git a/yarn.tests/setup b/yarn.tests/setup new file mode 100755 index 0000000..d64c24e --- /dev/null +++ b/yarn.tests/setup @@ -0,0 +1,3 @@ +#!/bin/sh + +find "$DATADIR" -mindepth 1 -delete diff --git a/yarnlib/block_parser.py b/yarnlib/block_parser.py index 84074e2..64dc990 100644 --- a/yarnlib/block_parser.py +++ b/yarnlib/block_parser.py @@ -36,6 +36,7 @@ class BlockParser(object): self.implementations = [] self.line_parsers = { 'SCENARIO': self.parse_scenario, + 'ASSUMING': self.parse_assuming, 'GIVEN': self.parse_given, 'WHEN': self.parse_when, 'THEN': self.parse_then, @@ -86,6 +87,9 @@ class BlockParser(object): self.scenarios[-1].steps.append(step) return blocks + def parse_assuming(self, line, blocks): + return self.parse_simple('ASSUMING', line, blocks) + def parse_given(self, line, blocks): return self.parse_simple('GIVEN', line, blocks) diff --git a/yarnlib/block_parser_tests.py b/yarnlib/block_parser_tests.py index c988479..78754b5 100644 --- a/yarnlib/block_parser_tests.py +++ b/yarnlib/block_parser_tests.py @@ -32,7 +32,7 @@ class BlockParserTests(unittest.TestCase): def test_parses_simple_elements(self): self.parser.parse_blocks( - ['SCENARIO foo', 'GIVEN bar', + ['SCENARIO foo', 'ASSUMING something', 'GIVEN bar', 'WHEN foobar\nTHEN yoyo\nFINALLY yay\nAND yeehaa']) self.assertEqual(len(self.parser.scenarios), 1) @@ -40,17 +40,19 @@ class BlockParserTests(unittest.TestCase): scenario = self.parser.scenarios[0] self.assertEqual(scenario.name, 'foo') - self.assertEqual(len(scenario.steps), 5) - self.assertEqual(scenario.steps[0].what, 'GIVEN') - self.assertEqual(scenario.steps[0].text, 'bar') - self.assertEqual(scenario.steps[1].what, 'WHEN') - self.assertEqual(scenario.steps[1].text, 'foobar') - self.assertEqual(scenario.steps[2].what, 'THEN') - self.assertEqual(scenario.steps[2].text, 'yoyo') - self.assertEqual(scenario.steps[3].what, 'FINALLY') - self.assertEqual(scenario.steps[3].text, 'yay') + self.assertEqual(len(scenario.steps), 6) + self.assertEqual(scenario.steps[0].what, 'ASSUMING') + self.assertEqual(scenario.steps[0].text, 'something') + self.assertEqual(scenario.steps[1].what, 'GIVEN') + self.assertEqual(scenario.steps[1].text, 'bar') + self.assertEqual(scenario.steps[2].what, 'WHEN') + self.assertEqual(scenario.steps[2].text, 'foobar') + self.assertEqual(scenario.steps[3].what, 'THEN') + self.assertEqual(scenario.steps[3].text, 'yoyo') self.assertEqual(scenario.steps[4].what, 'FINALLY') - self.assertEqual(scenario.steps[4].text, 'yeehaa') + self.assertEqual(scenario.steps[4].text, 'yay') + self.assertEqual(scenario.steps[5].what, 'FINALLY') + self.assertEqual(scenario.steps[5].text, 'yeehaa') def test_normalises_whitespace(self): self.parser.parse_blocks(['SCENARIO foo bar ']) -- cgit v1.2.1 From f35f983d515a680c2a5ebfbc7f93d3c864fb7a94 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Sun, 14 Jul 2013 19:23:59 +0100 Subject: Update README.yarn about ASSUMING --- README.yarn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.yarn b/README.yarn index 49fcd62..76d57b5 100644 --- a/README.yarn +++ b/README.yarn @@ -99,7 +99,7 @@ The following keywords are defined. * **ASSUMING** defines a condition for the scenario. The rest of the line is "matched text", which gets implemented by an IMPLEMENTS section. If the code executed by the implementation - fails, the scenario is skipped. (NOT yet implemented.) + fails, the scenario is skipped. * **GIVEN** prepares the world for the test to run. If the implementation fails, the scenario fails. -- cgit v1.2.1 From 3fe131971b7e0c232ca638e8361dcd2649883ac8 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Sun, 14 Jul 2013 19:24:34 +0100 Subject: Update NEWS about ASSUMING --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index ac47c61..cb4584d 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,7 @@ Version 0.X, released UNRELEASED includes a shell library when running any IMPLEMENTS section. * FINALLY always worked in yarn, but has now been added to the manual page as well. +* The keyword ASSUMING has been added to yarn. * New yarn option `--run` allows running selected tests only. * New yarn option `--snapshot` makes snapshots of the test working directory after each step in a scenario. Combined with the, also -- cgit v1.2.1