def test_feature_max_length_on_scenario_outline_keys():
    """
    The max length of a feature considering when the table keys of the
    scenario oulines are longer than the remaining things
    """

    feature1 = Feature.from_string(FEATURE8)
    feature2 = Feature.from_string(FEATURE9)
    assert_equals(feature1.max_length, 68)
    assert_equals(feature2.max_length, 68)
def test_scenario_outlines_within_feature():
    """
    Solving scenario outlines within a feature
    """

    feature = Feature.from_string(OUTLINED_FEATURE)
    scenario = feature.scenarios[0]

    assert_equals(len(scenario.solved_steps), 12)
    expected_sentences = [
        'Given I have entered 20 into the calculator',
        'And I have entered 30 into the calculator',
        'When I press add',
        'Then the result should be 50 on the screen',
        'Given I have entered 2 into the calculator',
        'And I have entered 5 into the calculator',
        'When I press add',
        'Then the result should be 7 on the screen',
        'Given I have entered 0 into the calculator',
        'And I have entered 40 into the calculator',
        'When I press add',
        'Then the result should be 40 on the screen',
    ]

    for step, expected_sentence in zip(scenario.solved_steps, expected_sentences):
        assert_equals(type(step), Step)
        assert_equals(step.sentence, expected_sentence)
def test_feature_first_scenario_tags_extraction():
    ("A feature object should be able to find the tags "
     "belonging to the first scenario")
    feature = Feature.from_string(FEATURE23)

    assert that(feature.scenarios[0].tags).deep_equals([
        'onetag', 'another', '$%^&even-weird_chars'])
def test_scenarios_parsed_by_feature_has_feature():
    "Scenarios parsed by features has feature"

    feature = Feature.from_string(FEATURE2)

    for scenario in feature.scenarios:
        assert_equals(scenario.feature, feature)
def test_single_scenario_many_scenarios():
    "Untagged scenario following a tagged one should have no tags"

    @step('this scenario has tags')
    def scenario_has_tags(step):
        assert step.scenario.tags

    @step('this scenario has no tags')
    def scenario_has_no_tags(step):
        assert not step.scenario.tags

    @step('it can be inspected from within the object')
    def inspected_within_object(step):
        assert step.scenario.tags

    @step(r'fill my email with [\'"]?([^\'"]+)[\'"]?')
    def fill_email(step, email):
        assert that(email).equals('*****@*****.**')

    feature = Feature.from_string(FEATURE13)

    first_scenario = feature.scenarios[0]
    assert that(first_scenario.tags).equals(['runme'])

    second_scenario = feature.scenarios[1]
    assert that(second_scenario.tags).equals([])

    third_scenario = feature.scenarios[2]
    assert that(third_scenario.tags).equals(['slow'])

    last_scenario = feature.scenarios[3]
    assert that(last_scenario.tags).equals([])
def test_background_parsing_without_mmf():
    feature = Feature.from_string(FEATURE17)
    expect(feature.description).to.be.empty

    expect(feature).to.have.property('background').being.a(Background)
    expect(feature.background).to.have.property('steps')
    expect(feature.background.steps).to.have.length_of(2)

    step1, step2 = feature.background.steps
    step1.sentence.should.equal(
        'Given I have the following movies in my database:')
    step1.hashes.should.equal([
        {
            u'Available': u'6',
            u'Rating': u'4 stars',
            u'Name': u'Matrix Revolutions',
            u'New': u'no',
        },
        {
            u'Available': u'11',
            u'Rating': u'5 stars',
            u'Name': u'Iron Man 2',
            u'New': u'yes',
        },
    ])

    step2.sentence.should.equal(
        'And the following clients:')
    step2.hashes.should.equal([
        {u'Name': u'John Doe'},
        {u'Name': u'Foo Bar'},
    ])
def test_feature_first_scenario_tag_extraction():
    ("A feature object should be able to find the single tag "
     "belonging to the first scenario")
    feature = Feature.from_string(FEATURE22)

    assert that(feature.scenarios[0].tags).deep_equals([
        'onetag'])
def test_full_featured_feature():
    """
    Solving scenarios within a full-featured feature
    """

    feature = Feature.from_string(OUTLINED_FEATURE_WITH_MANY)
    scenario1, scenario2, scenario3, scenario4 = feature.scenarios

    assert_equals(scenario1.name, 'Do something')
    assert_equals(scenario2.name, 'Do something else')
    assert_equals(scenario3.name, 'Worked!')
    assert_equals(scenario4.name, 'Add two numbers wisely')

    assert_equals(len(scenario1.solved_steps), 2)
    expected_sentences = [
        'Given I have entered ok into the fail',
        'Given I have entered fail into the ok',
    ]
    for step, expected_sentence in zip(scenario1.solved_steps, expected_sentences):
        assert_equals(step.sentence, expected_sentence)

    expected_evaluated = (
        (
            {'button': 'add', 'input_1': '20', 'input_2': '30', 'output': '50'}, [
                'Given I have entered 20 into the calculator',
                'And I have entered 30 into the calculator',
                'When I press add',
                'Then the result should be 50 on the screen',
            ]
        ),
        (
            {'button': 'add', 'input_1': '2', 'input_2': '5', 'output': '7'}, [
                'Given I have entered 2 into the calculator',
                'And I have entered 5 into the calculator',
                'When I press add',
                'Then the result should be 7 on the screen',
                ]
        ),
        (
            {'button': 'add', 'input_1': '0', 'input_2': '40', 'output': '40'}, [
                'Given I have entered 0 into the calculator',
                'And I have entered 40 into the calculator',
                'When I press add',
                'Then the result should be 40 on the screen',
            ],
        ),
        (
            {'button': 'add', 'input_1': '5', 'input_2': '7', 'output': '12'}, [
                'Given I have entered 5 into the calculator',
                'And I have entered 7 into the calculator',
                'When I press add',
                'Then the result should be 12 on the screen',
            ],
        )
    )
    for ((got_examples, got_steps), (expected_examples, expected_steps)) in zip(scenario4.evaluated, expected_evaluated):
        sentences_of = lambda x: x.sentence
        assert_equals(got_examples, expected_examples)
        assert_equals(map(sentences_of, got_steps), expected_steps)
def test_feature_max_length_on_step_with_table_keys():
    """
    The max length of a feature considering when the table keys of some of the
    steps are longer than the remaining things
    """

    feature = Feature.from_string(FEATURE7)
    assert_equals(feature.max_length, 74)
def test_feature_max_length_on_step_sentence():
    """
    The max length of a feature considering when the some of the step sentences
    is longer than the remaining things
    """

    feature = Feature.from_string(FEATURE4)
    assert_equals(feature.max_length, 55)
def test_feature_max_length_on_feature_name():
    """
    The max length of a feature considering when the name of the feature
    is longer than the remaining things
    """

    feature = Feature.from_string(FEATURE3)
    assert_equals(feature.max_length, 78)
def test_feature_max_length_on_feature_description():
    """
    The max length of a feature considering when one of the description lines
    of the feature is longer than the remaining things
    """

    feature = Feature.from_string(FEATURE2)
    assert_equals(feature.max_length, 47)
def test_feature_max_length_on_scenario():
    """
    The max length of a feature considering when the scenario is longer than
    the remaining things
    """

    feature = Feature.from_string(FEATURE1)
    assert_equals(feature.max_length, 76)
def test_feature_max_length_on_scenario_outline():
    """
    The max length of a feature considering when the table of some of the
    scenario oulines is longer than the remaining things
    """

    feature = Feature.from_string(FEATURE6)
    assert_equals(feature.max_length, 79)
def test_description_on_long_named_feature():
    "Can parse the description on long named features"
    feature = Feature.from_string(FEATURE3)
    assert_equals(
        feature.description,
        "In order to describe my features\n"
        "I want to add description on them",
    )
def test_single_scenario_single_scenario():
    "Features should have at least the first scenario parsed with tags"
    feature = Feature.from_string(FEATURE11)

    first_scenario = feature.scenarios[0]

    assert that(first_scenario.tags).deep_equals([
        'many', 'other', 'basic', 'tags', 'here', ':)'])
def test_comments():
    """
    It should ignore lines that start with #, despite white spaces
    """

    feature = Feature.from_string(FEATURE10)

    assert_equals(feature.max_length, 55)
def parse_steps(step):
    feature = """
    Feature: parse a step
    Scenario: parse a single step
    """

    feature += step

    return Feature.from_string(feature).scenarios[0].steps
def test_scenarios_with_special_characters():
    "Make sure that regex special characters in the scenario names are ignored"
    feature = Feature.from_string(FEATURE19)

    assert that(feature.scenarios[0].tags).deep_equals([
        'runme1'])

    assert that(feature.scenarios[1].tags).deep_equals([
        'runme2'])
def test_description_on_big_sentenced_steps():
    "Can parse the description on long sentenced steps"
    feature = Feature.from_string(FEATURE4)
    assert_equals(
        feature.description,
        "As a clever guy\n"
        "I want to describe this Feature\n"
        "So that I can take care of my Scenario",
    )
def test_scenario_has_name():
    """
    It should extract the name string from the scenario
    """

    feature = Feature.from_string(FEATURE1)

    assert isinstance(feature, Feature)

    expect(feature.name).to.equal("Rent movies")
def test_scenario_post_email():
    ("Having a scenario which the body has an email address; "
     "Then the following scenario should have no "
     "tags related to the email")

    feature = Feature.from_string(FEATURE21)
    scenario1, scenario2 = feature.scenarios

    scenario1.tags.should.be.empty
    scenario2.tags.should.equal(['tag'])
def test_scenarios_with_extra_whitespace():
    "Make sure that extra leading whitespace is ignored"
    feature = Feature.from_string(FEATURE14)

    assert_equals(type(feature.scenarios), list)
    assert_equals(len(feature.scenarios), 1, "It should have 1 scenario")
    assert_equals(feature.name, "Extra whitespace feature")

    scenario = feature.scenarios[0]
    assert_equals(type(scenario), Scenario)
    assert_equals(scenario.name, "Extra whitespace scenario")
def test_single_feature_single_tag():
    "All scenarios within a feature inherit the feature's tags"
    feature = Feature.from_string(FEATURE18)

    assert that(feature.scenarios[0].tags).deep_equals([
        'runme1', 'feature_runme'])

    assert that(feature.scenarios[1].tags).deep_equals([
        'runme2', 'feature_runme'])

    assert that(feature.scenarios[2].tags).deep_equals([
        'runme3', 'feature_runme'])
def parse_scenario(scenario,
                   tags=None):
    feature_str = """
    Feature: test scenario
    """

    if tags:
        feature_str += ' '.join('@%s' % tag for tag in tags)

    feature_str += scenario

    feature = Feature.from_string(feature_str)

    return feature.scenarios[0]
def test_feature_has_scenarios():
    """
    A feature object should have a list of scenarios
    """

    feature = Feature.from_string(FEATURE1)

    expect(feature.scenarios).to.be.a(list)
    expect(feature.scenarios).to.have.length_of(3)

    expected_scenario_names = [
        "Renting a featured movie",
        "Renting a non-featured movie",
        "Renting two movies allows client to take one more without charge",
    ]

    for scenario, expected_name in zip(feature.scenarios, expected_scenario_names):
        expect(scenario).to.be.a(Scenario)
        expect(scenario.name).to.equal(expected_name)

    expect(feature.scenarios[1].steps[0].keys).to.equal(
        ('Name', 'Rating', 'New', 'Available'))

    expect(list(feature.scenarios[1].steps[0].hashes)).to.equal([
        {
            'Name': 'A night at the museum 2',
            'Rating': '3 stars',
            'New': 'yes',
            'Available': '9',
        },
        {
            'Name': 'Matrix Revolutions',
            'Rating': '4 stars',
            'New': 'no',
            'Available': '6',
        },
    ])
def test_background_parsing_with_mmf():
    feature = Feature.from_string(FEATURE16)
    expect(feature.description).to.equal(
        "As a rental store owner\n"
        "I want to keep track of my clients\n"
        "So that I can manage my business better"
    )

    expect(feature).to.have.property('background').being.a(Background)
    expect(feature.background).to.have.property('steps')
    expect(feature.background.steps).to.have.length_of(2)

    step1, step2 = feature.background.steps
    step1.sentence.should.equal(
        'Given I have the following movies in my database:')
    step1.hashes.should.equal([
        {
            u'Available': u'6',
            u'Rating': u'4 stars',
            u'Name': u'Matrix Revolutions',
            u'New': u'no',
        },
        {
            u'Available': u'11',
            u'Rating': u'5 stars',
            u'Name': u'Iron Man 2',
            u'New': u'yes',
        },
    ])

    step2.sentence.should.equal(
        'And the following clients:')
    step2.hashes.should.equal([
        {u'Name': u'John Doe'},
        {u'Name': u'Foo Bar'},
    ])
def test_scenarios_parsing():
    "Tags are parsed correctly"
    feature = Feature.from_string(FEATURE15)
    scenarios_and_tags = [(s.name, s.tags) for s in feature.scenarios]

    scenarios_and_tags.should.equal([
        ('Bootstraping Redis role', []),
        ('Restart scalarizr', []),
        ('Rebundle server', [u'rebundle']),
        ('Use new role', [u'rebundle']),
        ('Restart scalarizr after bundling', [u'rebundle']),
        ('Bundling data', []),
        ('Modifying data', []),
        ('Reboot server', []),
        ('Backuping data on Master', []),
        ('Setup replication', []),
        ('Restart scalarizr in slave', []),
        ('Slave force termination', []),
        ('Slave delete EBS', [u'ec2']),
        ('Setup replication for EBS test', [u'ec2']),
        ('Writing on Master, reading on Slave', []),
        ('Slave -> Master promotion', []),
        ('Restart farm', [u'restart_farm']),
    ])
def test_can_parse_feature_description():
    """
    A feature object should have a description
    """

    feature = Feature.from_string(FEATURE2)

    assert_equals(
        feature.description,
        "In order to avoid silly mistakes\n"
        "Cashiers must be able to calculate a fraction"
    )
    expected_scenario_names = ["Regular numbers"]
    got_scenario_names = [s.name for s in feature.scenarios]

    assert_equals(expected_scenario_names, got_scenario_names)
    assert_equals(len(feature.scenarios[0].steps), 4)

    step1, step2, step3, step4 = feature.scenarios[0].steps

    assert_equals(step1.sentence, 'Given I have entered 3 into the calculator')
    assert_equals(step2.sentence, 'And I have entered 2 into the calculator')
    assert_equals(step3.sentence, 'When I press divide')
    assert_equals(step4.sentence, 'Then the result should be 1.5 on the screen')
def test_feature_has_repr():
    """
    Feature implements __repr__ nicely
    """
    feature = Feature.from_string(FEATURE1)
    expect(repr(feature)).to.equal('<Feature: "Rent movies">')