def test_parse_tags_with_tags_and_comment(self): tags = parse_tags( '@one @two.three-four @xxx # @fake-tag-in-comment xxx') eq_(len(tags), 3) eq_(tags, [ model.Tag(name, 1) for name in (u'one', u'two.three-four', u'xxx') ])
def action_steps(self, line): stripped = line.lstrip() if stripped.startswith('"""') or stripped.startswith("'''"): self.state = 'multiline' self.multiline_start = self.line self.multiline_terminator = stripped[:3] self.multiline_leading = line.index(stripped[0]) return True line = line.strip() step = self.parse_step(line) if step: self.statement.steps.append(step) return True if line.startswith('@'): self.tags.extend([model.Tag(tag.strip(), self.line) for tag in line[1:].split('@')]) return True scenario_kwd = self.match_keyword('scenario', line) if scenario_kwd: name = line[len(scenario_kwd) + 1:].strip() self.statement = model.Scenario(self.filename, self.line, scenario_kwd, name, tags=self.tags) self.tags = [] self.feature.add_scenario(self.statement) return True scenario_outline_kwd = self.match_keyword('scenario_outline', line) if scenario_outline_kwd: name = line[len(scenario_outline_kwd) + 1:].strip() self.statement = model.ScenarioOutline(self.filename, self.line, scenario_outline_kwd, name, tags=self.tags) self.tags = [] self.feature.add_scenario(self.statement) self.state = 'steps' return True examples_kwd = self.match_keyword('examples', line) if examples_kwd: if not isinstance(self.statement, model.ScenarioOutline): message = 'Examples must only appear inside scenario outline' raise ParserError(message, self.line) name = line[len(examples_kwd) + 1:].strip() self.examples = model.Examples(self.filename, self.line, examples_kwd, name) self.statement.examples.append(self.examples) self.state = 'table' return True if line.startswith('|'): self.state = 'table' return self.action_table(line) return False
def test_parses_feature_with_multiple_scenarios_with_tags(self): doc = u""" Feature: Stuff Scenario: Doing stuff Given there is stuff When I do stuff Then stuff happens @one_tag Scenario: Doing other stuff When stuff happens Then I am stuffed @lots @of @tags Scenario: Doing different stuff Given stuff Then who gives a stuff """.lstrip() feature = parser.parse_feature(doc) eq_(feature.name, "Stuff") assert (len(feature.scenarios) == 3) eq_(feature.scenarios[0].name, 'Doing stuff') self.compare_steps(feature.scenarios[0].steps, [ ('given', 'Given', 'there is stuff', None, None), ('when', 'When', 'I do stuff', None, None), ('then', 'Then', 'stuff happens', None, None), ]) eq_(feature.scenarios[1].name, 'Doing other stuff') eq_(feature.scenarios[1].tags, [model.Tag(u'one_tag', 1)]) self.compare_steps(feature.scenarios[1].steps, [ ('when', 'When', 'stuff happens', None, None), ('then', 'Then', 'I am stuffed', None, None), ]) eq_(feature.scenarios[2].name, 'Doing different stuff') eq_(feature.scenarios[2].tags, [model.Tag(n, 1) for n in (u'lots', u'of', u'tags')]) self.compare_steps(feature.scenarios[2].steps, [ ('given', 'Given', 'stuff', None, None), ('then', 'Then', 'who gives a stuff', None, None), ])
def test_parses_scenario_outline_with_tagged_examples1(self): # -- CASE: Examples with 1 tag-line (= 1 tag) doc = u''' Feature: Alice @foo Scenario Outline: Bob Given we have <Stuff> @bar Examples: Charly | Stuff | Things | | wool | felt | | cotton | thread | '''.lstrip() feature = parser.parse_feature(doc) eq_(feature.name, "Alice") assert(len(feature.scenarios) == 1) scenario_outline = feature.scenarios[0] eq_(scenario_outline.name, "Bob") eq_(scenario_outline.tags, [model.Tag(u"foo", 1)]) self.compare_steps(scenario_outline.steps, [ ("given", "Given", "we have <Stuff>", None, None), ]) table = model.Table( [u"Stuff", u"Things"], 0, [ [u"wool", u"felt"], [u"cotton", u"thread"], ] ) eq_(scenario_outline.examples[0].name, "Charly") eq_(scenario_outline.examples[0].table, table) eq_(scenario_outline.examples[0].tags, [model.Tag(u"bar", 1)]) # -- ScenarioOutline.scenarios: # Inherit tags from ScenarioOutline and Examples element. eq_(len(scenario_outline.scenarios), 2) expected_tags = [model.Tag(u"foo", 1), model.Tag(u"bar", 1)] eq_(set(scenario_outline.scenarios[0].tags), set(expected_tags)) eq_(set(scenario_outline.scenarios[1].tags), set(expected_tags))
def test_parses_feature_with_a_scenario_outline_with_tags(self): doc = u''' Feature: Stuff @stuff @derp Scenario Outline: Doing all sorts of stuff Given we have <Stuff> When we do stuff Then we have <Things> Examples: Some stuff | Stuff | Things | | wool | felt | | cotton | thread | | wood | paper | | explosives | hilarity | '''.lstrip() feature = parser.parse_feature(doc) eq_(feature.name, "Stuff") assert(len(feature.scenarios) == 1) eq_(feature.scenarios[0].name, 'Doing all sorts of stuff') eq_(feature.scenarios[0].tags, [model.Tag(u'stuff', 1), model.Tag(u'derp', 1)]) self.compare_steps(feature.scenarios[0].steps, [ ('given', 'Given', 'we have <Stuff>', None, None), ('when', 'When', 'we do stuff', None, None), ('then', 'Then', 'we have <Things>', None, None), ]) table = model.Table( [u'Stuff', u'Things'], 0, [ [u'wool', u'felt'], [u'cotton', u'thread'], [u'wood', u'paper'], [u'explosives', u'hilarity'], ] ) eq_(feature.scenarios[0].examples[0].name, 'Some stuff') eq_(feature.scenarios[0].examples[0].table, table)
def test_parses_feature_with_a_tag_and_comment(self): doc = u""" @foo # Comment: ... Feature: Stuff In order to thing As an entity I want to do stuff """.strip() feature = parser.parse_feature(doc) eq_(feature.name, "Stuff") eq_(feature.description, ["In order to thing", "As an entity", "I want to do stuff"]) eq_(feature.tags, [model.Tag(u'foo', 1)])
def test_parses_feature_with_more_tags_and_comment(self): doc = u""" @foo @bar @baz @qux @winkle_pickers # Comment: @number8 Feature: Stuff In order to thing As an entity I want to do stuff """.strip() feature = parser.parse_feature(doc) eq_(feature.name, "Stuff") eq_(feature.description, ["In order to thing", "As an entity", "I want to do stuff"]) eq_(feature.tags, [model.Tag(name, 1) for name in (u'foo', u'bar', u'baz', u'qux', u'winkle_pickers')])
def action_init(self, line): line = line.strip() if line.startswith('@'): self.tags.extend([model.Tag(tag.strip(), self.line) for tag in line[1:].split('@')]) return True feature_kwd = self.match_keyword('feature', line) if feature_kwd: name = line[len(feature_kwd) + 1:].strip() self.feature = model.Feature(self.filename, self.line, feature_kwd, name, tags=self.tags) self.tags = [] self.state = 'feature' return True return False
def action_feature(self, line): line = line.strip() if line.startswith('@'): self.tags.extend([model.Tag(tag.strip(), self.line) for tag in line[1:].split('@')]) return True background_kwd = self.match_keyword('background', line) if background_kwd: name = line[len(background_kwd) + 1:].strip() self.statement = model.Background(self.filename, self.line, background_kwd, name) self.feature.background = self.statement self.state = 'steps' return True scenario_kwd = self.match_keyword('scenario', line) if scenario_kwd: name = line[len(scenario_kwd) + 1:].strip() self.statement = model.Scenario(self.filename, self.line, scenario_kwd, name, tags=self.tags) self.tags = [] self.feature.add_scenario(self.statement) self.state = 'steps' return True scenario_outline_kwd = self.match_keyword('scenario_outline', line) if scenario_outline_kwd: name = line[len(scenario_outline_kwd) + 1:].strip() self.statement = model.ScenarioOutline(self.filename, self.line, scenario_outline_kwd, name, tags=self.tags) self.tags = [] self.feature.add_scenario(self.statement) self.state = 'steps' return True self.feature.description.append(line) return True
def parse_tags(self, line): """Parse a line with one or more tags: * A tag starts with the AT sign. * A tag consists of one word without whitespace chars. * Multiple tags are separated with whitespace chars * End-of-line comment is stripped. :param line: Line with one/more tags to process. :raise ParserError: If syntax error is detected. """ assert line.startswith("@") tags = [] for word in line.split(): if word.startswith("@"): tags.append(model.Tag(word[1:], self.line)) elif word.startswith("#"): break # -- COMMENT: Skip rest of line. else: # -- BAD-TAG: Abort here. raise ParserError(u"tag: %s (line: %s)" % (word, line), self.line, self.filename) return tags
def test_parses_feature_with_the_lot(self): doc = u''' # This one's got comments too. @derp Feature: Stuff In order to test my parser As a test runner I want to run tests # A møøse once bit my sister Background: Given this is a test @fred Scenario: Testing stuff Given we are testing And this is only a test But this is an important test When we test with a multiline string: """ Yarr, my hovercraft be full of stuff. Also, I be feelin' this pirate schtick be a mite overdone, me hearties. Also: rum. """ Then we want it to work #These comments are everywhere man Scenario Outline: Gosh this is long Given this is <length> Then we want it to be <width> But not <height> Examples: Initial | length | width | height | # I don't know why this one is here | 1 | 2 | 3 | | 4 | 5 | 6 | Examples: Subsequent | length | width | height | | 7 | 8 | 9 | Scenario: This one doesn't have a tag Given we don't have a tag Then we don't really mind @stuff @derp Scenario Outline: Doing all sorts of stuff Given we have <Stuff> When we do stuff with a table: | a | b | c | d | e | | 1 | 2 | 3 | 4 | 5 | # I can see a comment line from here | 6 | 7 | 8 | 9 | 10 | Then we have <Things> Examples: Some stuff | Stuff | Things | | wool | felt | | cotton | thread | | wood | paper | | explosives | hilarity | '''.lstrip() feature = parser.parse_feature(doc) eq_(feature.name, "Stuff") eq_(feature.tags, [model.Tag(u'derp', 1)]) eq_(feature.description, [ 'In order to test my parser', 'As a test runner', 'I want to run tests' ]) assert (feature.background) self.compare_steps(feature.background.steps, [('given', 'Given', 'this is a test', None, None)]) assert (len(feature.scenarios) == 4) eq_(feature.scenarios[0].name, 'Testing stuff') eq_(feature.scenarios[0].tags, [model.Tag(u'fred', 1)]) string = '\n'.join([ 'Yarr, my hovercraft be full of stuff.', "Also, I be feelin' this pirate schtick be a mite overdone, " + \ "me hearties.", ' Also: rum.' ]) self.compare_steps(feature.scenarios[0].steps, [ ('given', 'Given', 'we are testing', None, None), ('given', 'And', 'this is only a test', None, None), ('given', 'But', 'this is an important test', None, None), ('when', 'When', 'we test with a multiline string', string, None), ('then', 'Then', 'we want it to work', None, None), ]) eq_(feature.scenarios[1].name, 'Gosh this is long') eq_(feature.scenarios[1].tags, []) table = model.Table([u'length', u'width', u'height'], 0, [ [u'1', u'2', u'3'], [u'4', u'5', u'6'], ]) eq_(feature.scenarios[1].examples[0].name, 'Initial') eq_(feature.scenarios[1].examples[0].table, table) table = model.Table([u'length', u'width', u'height'], 0, [ [u'7', u'8', u'9'], ]) eq_(feature.scenarios[1].examples[1].name, 'Subsequent') eq_(feature.scenarios[1].examples[1].table, table) self.compare_steps(feature.scenarios[1].steps, [ ('given', 'Given', 'this is <length>', None, None), ('then', 'Then', 'we want it to be <width>', None, None), ('then', 'But', 'not <height>', None, None), ]) eq_(feature.scenarios[2].name, "This one doesn't have a tag") eq_(feature.scenarios[2].tags, []) self.compare_steps(feature.scenarios[2].steps, [ ('given', 'Given', "we don't have a tag", None, None), ('then', 'Then', "we don't really mind", None, None), ]) table = model.Table([u'Stuff', u'Things'], 0, [ [u'wool', u'felt'], [u'cotton', u'thread'], [u'wood', u'paper'], [u'explosives', u'hilarity'], ]) eq_(feature.scenarios[3].name, 'Doing all sorts of stuff') eq_(feature.scenarios[3].tags, [model.Tag(u'stuff', 1), model.Tag(u'derp', 1)]) eq_(feature.scenarios[3].examples[0].name, 'Some stuff') eq_(feature.scenarios[3].examples[0].table, table) table = model.Table([u'a', u'b', u'c', u'd', u'e'], 0, [ [u'1', u'2', u'3', u'4', u'5'], [u'6', u'7', u'8', u'9', u'10'], ]) self.compare_steps(feature.scenarios[3].steps, [ ('given', 'Given', 'we have <Stuff>', None, None), ('when', 'When', 'we do stuff with a table', None, table), ('then', 'Then', 'we have <Things>', None, None), ])
def test_parse_tags_with_more_tags(self): tags = parse_tags('@one @two.three-four @xxx') eq_(len(tags), 3) eq_(tags, [ model.Tag(name, 1) for name in (u'one', u'two.three-four', u'xxx') ])