Esempio n. 1
0
    def test_getas__with_known_param_and_valid_text(self):
        userdata = UserData(param="42")
        assert "param" in userdata, "ENSURE: known param"

        value = userdata.getas(int, "param")
        assert isinstance(value, int)
        assert value == 42
Esempio n. 2
0
    def test_getas__with_unknown_param_returns_default_value(self):
        userdata = UserData()
        assert "param" not in userdata, "ENSURE: unknown param"

        value = userdata.getas(int, "param", 123)
        assert isinstance(value, int)
        self.assertEqual(value, 123)
Esempio n. 3
0
    def test_getas__with_unknown_param_returns_default_value(self):
        userdata = UserData()
        assert "param" not in userdata, "ENSURE: unknown param"

        value = userdata.getas(int, "param", 123)
        assert isinstance(value, int)
        self.assertEqual(value, 123)
Esempio n. 4
0
    def test_getas__with_known_param_and_preconverted_value(self):
        userdata = UserData(param=42)
        assert "param" in userdata, "ENSURE: known param"

        value = userdata.getas(int, "param")
        assert isinstance(value, int)
        self.assertEqual(value, 42)
Esempio n. 5
0
    def test_getas__with_known_param_and_valid_text(self):
        userdata = UserData(param="42")
        assert "param" in userdata, "ENSURE: known param"

        value = userdata.getas(int, "param")
        assert isinstance(value, int)
        assert value == 42
Esempio n. 6
0
    def test_getas__with_known_param_and_preconverted_value(self):
        userdata = UserData(param=42)
        assert "param" in userdata, "ENSURE: known param"

        value = userdata.getas(int, "param")
        assert isinstance(value, int)
        self.assertEqual(value, 42)
Esempio n. 7
0
 def test_userdata_is_dictlike(self):
     userdata = UserData(name="Foo", number=42)
     value1 = userdata["name"]
     value2 = userdata.get("number")
     value3 = userdata.get("unknown", Unknown)
     assert isinstance(userdata, dict)
     self.assertEqual(value1, "Foo")
     self.assertEqual(value2, 42)
     assert value3 is Unknown
Esempio n. 8
0
 def test_userdata_is_dictlike(self):
     userdata = UserData(name="Foo", number=42)
     value1 = userdata["name"]
     value2 = userdata.get("number")
     value3 = userdata.get("unknown", Unknown)
     assert isinstance(userdata, dict)
     self.assertEqual(value1, "Foo")
     self.assertEqual(value2, 42)
     assert value3 is Unknown
Esempio n. 9
0
    def test_getas__with_known_param_and_preconverted_value_and_valuetype(self):
        userdata = UserData(param=42)
        assert "param" in userdata, "ENSURE: known param"

        def parse_int(text):
            return int(text)

        value = userdata.getas(parse_int, "param", valuetype=int)
        assert isinstance(value, int)
        self.assertEqual(value, 42)
Esempio n. 10
0
    def test_getas__with_known_param_and_preconverted_value_and_valuetype(
            self):
        userdata = UserData(param=42)
        assert "param" in userdata, "ENSURE: known param"

        def parse_int(text):
            return int(text)

        value = userdata.getas(parse_int, "param", valuetype=int)
        assert isinstance(value, int)
        self.assertEqual(value, 42)
Esempio n. 11
0
    def test_getbool__with_known_param_and_valid_text(self):
        for true_text in ["true", "TRUE", "True", "yes", "on", "1"]:
            userdata = UserData(param=true_text)
            value = userdata.getbool("param")
            assert isinstance(value, bool), "text=%s" % true_text
            self.assertEqual(value, True)

        for false_text in ["false", "FALSE", "False", "no", "off", "0"]:
            userdata = UserData(param=false_text)
            value = userdata.getbool("param")
            assert isinstance(value, bool), "text=%s" % false_text
            self.assertEqual(value, False)
def test_read_from_file(mock_cp):
    mock_context = mock.Mock()
    mock_context._config.userdata = UserData.make({"config_file": "some_path"})
    mock_cp().__getitem__.return_value = {
        "endpoint": "endpoint",
        "project": "project",
        "token": "token",
        "launch_name": "launch_name",
        "launch_description": "launch_description",
        "launch_attributes": "X Y Z",
        "step_based": "False",
        "is_skipped_an_issue": "True",
        "retries": "2",
        "rerun": "True",
        "rerun_of": "launch_id",
    }
    cfg = read_config(mock_context)
    expect(cfg.endpoint == "endpoint")
    expect(cfg.token == "token")
    expect(cfg.project == "project")
    expect(cfg.launch_name == "launch_name")
    expect(cfg.step_based is False)
    expect(cfg.is_skipped_an_issue is True)
    expect(cfg.launch_attributes == ["X", "Y", "Z"])
    expect(cfg.launch_description == "launch_description")
    expect(cfg.retries == 2)
    expect(cfg.rerun is True)
    expect(cfg.rerun_of == "launch_id")
    expect(cfg.enabled is True)
    assert_expectations()
def test_read_config_from_cmd(mock_cp):
    mock_cp().has_section.return_value = False
    mock_context = mock.Mock()
    mock_context._config.userdata = UserData.make({
        "config_file": "some_path",
        "endpoint": "endpoint",
        "project": "project",
        "token": "token",
        "launch_name": "launch_name",
        "launch_attributes": "A B C",
        "launch_description": "launch_description",
        "step_based": "True",
        "is_skipped_an_issue": "False",
        "retries": 3,
        "rerun": "True",
        "rerun_of": "launch_id",
    })
    cfg = read_config(mock_context)
    expect(cfg.endpoint == "endpoint")
    expect(cfg.token == "token")
    expect(cfg.project == "project")
    expect(cfg.launch_name == "launch_name")
    expect(cfg.step_based is True)
    expect(cfg.launch_attributes == ["A", "B", "C"])
    expect(cfg.launch_description == "launch_description")
    expect(cfg.is_skipped_an_issue is False)
    expect(cfg.retries == 3)
    expect(cfg.rerun is True)
    expect(cfg.rerun_of == "launch_id")
    expect(cfg.enabled is True)
    assert_expectations()
def test_read_config_file_path(mock_cp, cmd_args, path):
    mock_context = mock.Mock()
    mock_context._config.userdata = UserData.make(cmd_args)
    read_config(mock_context)
    expect(mock_cp().read.call_count == 1)
    expect(mock_cp().read.call_args[0][0] == path)
    expect(mock_cp().has_section.call_count == 1)
    expect(mock_cp().has_section.call_args[0][0] == RP_CFG_SECTION)
    assert_expectations()
Esempio n. 15
0
 def test_items__with_scoped_params(self):
     userdata = UserData({
         "my.other_scope.param1": "__OTHER1__",
         "my.scope.param1": "123",
         "my.scope.param2": "456",
         "my.other_scope.param2": "__OTHER2__",
     })
     config = UserDataNamespace("my.scope", userdata)
     assert sorted(config.items()) == [("param1", "123"), ("param2", "456")]
Esempio n. 16
0
 def test_setitem__stores_value(self):
     userdata = UserData({"my.scope.param1": "123"})
     config = UserDataNamespace("my.scope", userdata)
     scoped_name = "my.scope.new_param"
     config["new_param"] = 1234
     assert "new_param" in config
     assert config["new_param"] == 1234
     assert scoped_name in config.data
     assert config.data[scoped_name] == 1234
Esempio n. 17
0
 def test_scoped_keys__with_scoped_params(self):
     userdata = UserData({
         "my.other_scope.param1": "123",
         "my.scope.param1": "123",
         "my.scope.param2": "456",
         "my.other_scope.param2": "123",
     })
     config = UserDataNamespace("my.scope", userdata)
     assert sorted(
         config.scoped_keys()) == ["my.scope.param1", "my.scope.param2"]
Esempio n. 18
0
 def test_length__with_scoped_params(self):
     userdata1 = UserData({"my.scope.param1": "123"})
     userdata2 = UserData({
         "my.other_scope.param1": "123",
         "my.scope.param1": "123",
         "my.scope.param2": "456",
     })
     userdata3 = UserData({
         "my.other_scope.param1": "123",
         "my.scope.param1": "123",
         "my.scope.param2": "456",
         "my.scope.param3": "789",
         "my.other_scope.param2": "123",
     })
     config = UserDataNamespace("my.scope")
     config.data = userdata1
     assert len(config) == 1
     config.data = userdata2
     assert len(config) == 2
     config.data = userdata3
     assert len(config) == 3
Esempio n. 19
0
    def test_getbool__with_known_param_and_valid_text(self):
        for true_text in ["true", "TRUE", "True", "yes", "on", "1"]:
            userdata = UserData(param=true_text)
            value = userdata.getbool("param")
            assert isinstance(value, bool), "text=%s" % true_text
            self.assertEqual(value, True)

        for false_text in ["false", "FALSE", "False", "no", "off", "0"]:
            userdata = UserData(param=false_text)
            value = userdata.getbool("param")
            assert isinstance(value, bool), "text=%s" % false_text
            self.assertEqual(value, False)
def test_read_config_default_values(mock_cp):
    mock_cp().has_section.return_value = False
    mock_context = mock.Mock()
    mock_context._config.userdata = UserData.make({"config_file": "some_path"})
    cfg = read_config(mock_context)
    expect(cfg.endpoint is None)
    expect(cfg.token is None)
    expect(cfg.project is None)
    expect(cfg.launch_name == DEFAULT_LAUNCH_NAME)
    expect(cfg.step_based is False)
    expect(cfg.launch_attributes is None)
    expect(cfg.launch_description is None)
    expect(cfg.is_skipped_an_issue is False)
    expect(cfg.retries is None)
    expect(cfg.rerun is False)
    expect(cfg.rerun_of is None)
    expect(cfg.enabled is False)
    assert_expectations()
Esempio n. 21
0
 def test_getint__with_known_param_and_valid_text(self):
     userdata = UserData(param="42")
     value = userdata.getint("param")
     assert isinstance(value, int)
     self.assertEqual(value, 42)
Esempio n. 22
0
 def test_getbool__with_known_param_and_valid_false_text(self, text):
     false_text = text
     userdata = UserData(param=false_text)
     value = userdata.getbool("param")
     assert isinstance(value, bool), "text=%s" % false_text
     assert value is False
Esempio n. 23
0
 def test_length__returns_zero_without_params(self):
     userdata = UserData({"my.other_scope.param1": "123"})
     config = UserDataNamespace("my.scope", userdata)
     assert len(config) == 0
Esempio n. 24
0
 def test_getas__with_known_param_and_invalid_text_raises_ValueError(self):
     userdata = UserData(param="__BAD_NUMBER__")
     assert "param" in userdata, "ENSURE: known param"
     with pytest.raises(ValueError):
         userdata.getas(int, "param")
Esempio n. 25
0
 def test_getbool__with_known_param_and_invalid_text_raises_ValueError(self):
     userdata = UserData(param="__BAD_VALUE__")
     with pytest.raises(ValueError):
         userdata.getbool("param")
Esempio n. 26
0
 def test_getfloat__with_unknown_param_without_default_returns_zero(self):
     userdata = UserData()
     value = userdata.getfloat("param")
     self.assertEqual(value, 0.0)
Esempio n. 27
0
 def test_getfloat__with_unknown_param_without_default_returns_zero(self):
     userdata = UserData()
     value = userdata.getfloat("param")
     self.assertEqual(value, 0.0)
Esempio n. 28
0
class Configuration(object):
    """Configuration object for behave and behave runners."""
    # pylint: disable=too-many-instance-attributes
    defaults = dict(
        color=sys.platform != "win32",
        show_snippets=True,
        show_skipped=True,
        dry_run=False,
        show_source=True,
        show_timings=True,
        stdout_capture=True,
        stderr_capture=True,
        log_capture=True,
        logging_format="%(levelname)s:%(name)s:%(message)s",
        logging_level=logging.INFO,
        steps_catalog=False,
        summary=True,
        junit=False,
        stage=None,
        userdata={},
        # -- SPECIAL:
        default_format="pretty",  # -- Used when no formatters are configured.
        default_tags="",  # -- Used when no tags are defined.
        scenario_outline_annotation_schema=
        u"{name} -- @{row.id} {examples.name}")
    cmdline_only_options = set("userdata_defines")

    def __init__(self,
                 command_args=None,
                 load_config=True,
                 verbose=None,
                 **kwargs):
        """
        Constructs a behave configuration object.
          * loads the configuration defaults (if needed).
          * process the command-line args
          * store the configuration results

        :param command_args: Provide command args (as sys.argv).
            If command_args is None, sys.argv[1:] is used.
        :type command_args: list<str>, str
        :param load_config: Indicate if configfile should be loaded (=true)
        :param verbose: Indicate if diagnostic output is enabled
        :param kwargs:  Used to hand-over/overwrite default values.
        """
        # pylint: disable=too-many-branches, too-many-statements
        if command_args is None:
            command_args = sys.argv[1:]
        elif isinstance(command_args, six.string_types):
            encoding = select_best_encoding() or "utf-8"
            if six.PY2 and isinstance(command_args, six.text_type):
                command_args = command_args.encode(encoding)
            elif six.PY3 and isinstance(command_args, six.binary_type):
                command_args = command_args.decode(encoding)
            command_args = shlex.split(command_args)
        elif isinstance(command_args, (list, tuple)):
            command_args = to_texts(command_args)

        if verbose is None:
            # -- AUTO-DISCOVER: Verbose mode from command-line args.
            verbose = ("-v" in command_args) or ("--verbose" in command_args)

        self.version = None
        self.tags_help = None
        self.lang_list = None
        self.lang_help = None
        self.default_tags = None
        self.junit = None
        self.logging_format = None
        self.logging_datefmt = None
        self.name = None
        self.scope = None
        self.steps_catalog = None
        self.userdata = None
        self.wip = None

        defaults = self.defaults.copy()
        for name, value in six.iteritems(kwargs):
            defaults[name] = value
        self.defaults = defaults
        self.formatters = []
        self.reporters = []
        self.name_re = None
        self.outputs = []
        self.include_re = None
        self.exclude_re = None
        self.scenario_outline_annotation_schema = None  # pylint: disable=invalid-name
        self.steps_dir = "steps"
        self.environment_file = "environment.py"
        self.userdata_defines = None
        self.more_formatters = None
        if load_config:
            load_configuration(self.defaults, verbose=verbose)
        parser = setup_parser()
        parser.set_defaults(**self.defaults)
        args = parser.parse_args(command_args)
        for key, value in six.iteritems(args.__dict__):
            if key.startswith("_") and key not in self.cmdline_only_options:
                continue
            setattr(self, key, value)

        self.paths = [os.path.normpath(path) for path in self.paths]
        self.setup_outputs(args.outfiles)

        if self.steps_catalog:
            # -- SHOW STEP-CATALOG: As step summary.
            self.default_format = "steps.catalog"
            self.format = ["steps.catalog"]
            self.dry_run = True
            self.summary = False
            self.show_skipped = False
            self.quiet = True

        if self.wip:
            # Only run scenarios tagged with "wip".
            # Additionally:
            #  * use the "plain" formatter (per default)
            #  * do not capture stdout or logging output and
            #  * stop at the first failure.
            self.default_format = "plain"
            self.tags = ["wip"] + self.default_tags.split()
            self.color = False
            self.stop = True
            self.log_capture = False
            self.stdout_capture = False

        self.tags = TagExpression(self.tags or self.default_tags.split())

        if self.quiet:
            self.show_source = False
            self.show_snippets = False

        if self.exclude_re:
            self.exclude_re = re.compile(self.exclude_re)

        if self.include_re:
            self.include_re = re.compile(self.include_re)
        if self.name:
            # -- SELECT: Scenario-by-name, build regular expression.
            self.name_re = self.build_name_re(self.name)

        if self.stage is None:  # pylint: disable=access-member-before-definition
            # -- USE ENVIRONMENT-VARIABLE, if stage is undefined.
            self.stage = os.environ.get("BEHAVE_STAGE", None)
        self.setup_stage(self.stage)
        self.setup_model()
        self.setup_userdata()

        # -- FINALLY: Setup Reporters and Formatters
        # NOTE: Reporters and Formatters can now use userdata information.
        if self.junit:
            # Buffer the output (it will be put into Junit report)
            self.stdout_capture = True
            self.stderr_capture = True
            self.log_capture = True
            self.reporters.append(JUnitReporter(self))
        if self.summary:
            self.reporters.append(SummaryReporter(self))

        self.setup_formats()
        unknown_formats = self.collect_unknown_formats()
        if unknown_formats:
            parser.error("format=%s is unknown" % ", ".join(unknown_formats))

    def setup_outputs(self, args_outfiles=None):
        if self.outputs:
            assert not args_outfiles, "ONLY-ONCE"
            return

        # -- NORMAL CASE: Setup only initially (once).
        if not args_outfiles:
            self.outputs.append(StreamOpener(stream=sys.stdout))
        else:
            for outfile in args_outfiles:
                if outfile and outfile != "-":
                    self.outputs.append(StreamOpener(outfile))
                else:
                    self.outputs.append(StreamOpener(stream=sys.stdout))

    def setup_formats(self):
        """Register more, user-defined formatters by name."""
        if self.more_formatters:
            for name, scoped_class_name in self.more_formatters.items():
                _format_registry.register_as(name, scoped_class_name)

    def collect_unknown_formats(self):
        unknown_formats = []
        if self.format:
            for format_name in self.format:
                if (format_name == "help"
                        or _format_registry.is_formatter_valid(format_name)):
                    continue
                unknown_formats.append(format_name)
        return unknown_formats

    @staticmethod
    def build_name_re(names):
        """
        Build regular expression for scenario selection by name
        by using a list of name parts or name regular expressions.

        :param names: List of name parts or regular expressions (as text).
        :return: Compiled regular expression to use.
        """
        # -- NOTE: re.LOCALE is removed in Python 3.6 (deprecated in Python 3.5)
        # flags = (re.UNICODE | re.LOCALE)
        # -- ENSURE: Names are all unicode/text values (for issue #606).
        names = to_texts(names)
        pattern = u"|".join(names)
        return re.compile(pattern, flags=re.UNICODE)

    def exclude(self, filename):
        if isinstance(filename, FileLocation):
            filename = six.text_type(filename)

        if self.include_re and self.include_re.search(filename) is None:
            return True
        if self.exclude_re and self.exclude_re.search(filename) is not None:
            return True
        return False

    def setup_logging(self, level=None, configfile=None, **kwargs):
        """
        Support simple setup of logging subsystem.
        Ensures that the logging level is set.
        But note that the logging setup can only occur once.

        SETUP MODES:
          * :func:`logging.config.fileConfig()`, if ``configfile`` is provided.
          * :func:`logging.basicConfig()`, otherwise.

        .. code-block: python
            # -- FILE: features/environment.py
            def before_all(context):
                context.config.setup_logging()

        :param level:       Logging level of root logger.
                            If None, use :attr:`logging_level` value.
        :param configfile:  Configuration filename for fileConfig() setup.
        :param kwargs:      Passed to :func:`logging.basicConfig()`
        """
        if level is None:
            level = self.logging_level  # pylint: disable=no-member

        if configfile:
            from logging.config import fileConfig
            fileConfig(configfile)
        else:
            # pylint: disable=no-member
            format_ = kwargs.pop("format", self.logging_format)
            datefmt = kwargs.pop("datefmt", self.logging_datefmt)
            logging.basicConfig(format=format_, datefmt=datefmt, **kwargs)
        # -- ENSURE: Default log level is set
        #    (even if logging subsystem is already configured).
        logging.getLogger().setLevel(level)

    def setup_model(self):
        if self.scenario_outline_annotation_schema:
            name_schema = six.text_type(
                self.scenario_outline_annotation_schema)
            ScenarioOutline.annotation_schema = name_schema.strip()

    def setup_stage(self, stage=None):
        """Setup the test stage that selects a different set of
        steps and environment implementations.

        :param stage:   Name of current test stage (as string or None).

        EXAMPLE::

            # -- SETUP DEFAULT TEST STAGE (unnamed):
            config = Configuration()
            config.setup_stage()
            assert config.steps_dir == "steps"
            assert config.environment_file == "environment.py"

            # -- SETUP PRODUCT TEST STAGE:
            config.setup_stage("product")
            assert config.steps_dir == "product_steps"
            assert config.environment_file == "product_environment.py"
        """
        steps_dir = "steps"
        environment_file = "environment.py"
        if stage:
            # -- USE A TEST STAGE: Select different set of implementations.
            prefix = stage + "_"
            steps_dir = prefix + steps_dir
            environment_file = prefix + environment_file
        self.steps_dir = steps_dir
        self.environment_file = environment_file

    def setup_userdata(self):
        if not isinstance(self.userdata, UserData):
            self.userdata = UserData(self.userdata)
        if self.userdata_defines:
            # -- ENSURE: Cmd-line overrides configuration file parameters.
            self.userdata.update(self.userdata_defines)

    def update_userdata(self, data):
        """Update userdata with data and reapply userdata defines (cmdline).
        :param data:  Provides (partial) userdata (as dict)
        """
        self.userdata.update(data)
        if self.userdata_defines:
            # -- REAPPLY: Cmd-line defines (override configuration file data).
            self.userdata.update(self.userdata_defines)
Esempio n. 29
0
 def test_getitem__raises_error_when_param_not_exists(self):
     userdata = UserData({"my.scope.param": "123"})
     config = UserDataNamespace("my.scope", userdata)
     with pytest.raises(KeyError):
         _ = config["UNKNOWN_PARAM"]
Esempio n. 30
0
 def test_getbool__with_unknown_param_returns_default_value(self):
     userdata = UserData()
     value = userdata.getint("param", 1.2)
     assert isinstance(value, float)
     self.assertEqual(value, 1.2)
Esempio n. 31
0
 def test_getbool__with_known_param_and_invalid_text_raises_ValueError(
         self):
     userdata = UserData(param="__BAD_VALUE__")
     self.assertRaises(ValueError, userdata.getbool, "param")
Esempio n. 32
0
 def test_getbool__with_unknown_param_without_default_returns_false(self):
     userdata = UserData()
     value = userdata.getfloat("param")
     self.assertEqual(value, False)
Esempio n. 33
0
 def test_getint__with_known_param_and_valid_text(self):
     userdata = UserData(param="42")
     value = userdata.getint("param")
     assert isinstance(value, int)
     self.assertEqual(value, 42)
Esempio n. 34
0
 def test_getfloat__with_known_param_and_valid_text(self):
     for valid_text in ["1.2", "2", "-1E+3", "+2.34E-5"]:
         userdata = UserData(param=valid_text)
         value = userdata.getfloat("param")
         assert isinstance(value, float)
         self.assertEqual(value, float(valid_text))
Esempio n. 35
0
 def test_getfloat__with_known_param_and_invalid_text_raises_ValueError(
         self):
     userdata = UserData(param="__BAD_NUMBER__")
     self.assertRaises(ValueError, userdata.getfloat, "param")
Esempio n. 36
0
 def test_contains__when_scoped_param_not_exists(self):
     userdata = UserData({"my.scope.param": 12})
     config = UserDataNamespace("my.scope", userdata)
     assert "UNKNOWN_PARAM" not in config
     assert not ("UNKNOWN_PARAM" in config)
Esempio n. 37
0
 def test_getbool__with_unknown_param_returns_default_value(self):
     userdata = UserData()
     value = userdata.getint("param", 1.2)
     assert isinstance(value, float)
     self.assertEqual(value, 1.2)
Esempio n. 38
0
 def test_getfloat__with_known_param_and_valid_text(self):
     for valid_text in ["1.2", "2", "-1E+3", "+2.34E-5"]:
         userdata = UserData(param=valid_text)
         value = userdata.getfloat("param")
         assert isinstance(value, float)
         self.assertEqual(value, float(valid_text))
Esempio n. 39
0
 def test_getbool__with_unknown_param_without_default_returns_false(self):
     userdata = UserData()
     value = userdata.getfloat("param")
     self.assertEqual(value, False)
Esempio n. 40
0
 def test_getas__with_known_param_and_invalid_text_raises_ValueError(self):
     userdata = UserData(param="__BAD_NUMBER__")
     assert "param" in userdata, "ENSURE: known param"
     self.assertRaises(ValueError, userdata.getas, int, "param")
Esempio n. 41
0
class Configuration(object):
    """Configuration object for behave and behave runners."""
    # pylint: disable=too-many-instance-attributes
    defaults = dict(
        color=sys.platform != "win32",
        show_snippets=True,
        show_skipped=True,
        dry_run=False,
        show_source=True,
        show_timings=True,
        stdout_capture=True,
        stderr_capture=True,
        log_capture=True,
        logging_format="%(levelname)s:%(name)s:%(message)s",
        logging_level=logging.INFO,
        steps_catalog=False,
        summary=True,
        junit=False,
        stage=None,
        userdata={},
        # -- SPECIAL:
        default_format="pretty",    # -- Used when no formatters are configured.
        default_tags="",            # -- Used when no tags are defined.
        scenario_outline_annotation_schema=u"{name} -- @{row.id} {examples.name}"
    )
    cmdline_only_options = set("userdata_defines")

    def __init__(self, command_args=None, load_config=True, verbose=None,
                 **kwargs):
        """
        Constructs a behave configuration object.
          * loads the configuration defaults (if needed).
          * process the command-line args
          * store the configuration results

        :param command_args: Provide command args (as sys.argv).
            If command_args is None, sys.argv[1:] is used.
        :type command_args: list<str>, str
        :param load_config: Indicate if configfile should be loaded (=true)
        :param verbose: Indicate if diagnostic output is enabled
        :param kwargs:  Used to hand-over/overwrite default values.
        """
        # pylint: disable=too-many-branches, too-many-statements
        if command_args is None:
            command_args = sys.argv[1:]
        elif isinstance(command_args, six.string_types):
            if six.PY2 and isinstance(command_args, six.text_type):
                command_args = command_args.encode("utf-8")
            elif six.PY3 and isinstance(command_args, six.binary_type):
                command_args = command_args.decode("utf-8")
            command_args = shlex.split(command_args)
        if verbose is None:
            # -- AUTO-DISCOVER: Verbose mode from command-line args.
            verbose = ("-v" in command_args) or ("--verbose" in command_args)

        self.version = None
        self.tags_help = None
        self.lang_list = None
        self.lang_help = None
        self.default_tags = None
        self.junit = None
        self.logging_format = None
        self.logging_datefmt = None
        self.name = None
        self.scope = None
        self.steps_catalog = None
        self.userdata = None
        self.wip = None

        defaults = self.defaults.copy()
        for name, value in six.iteritems(kwargs):
            defaults[name] = value
        self.defaults = defaults
        self.formatters = []
        self.reporters = []
        self.name_re = None
        self.outputs = []
        self.include_re = None
        self.exclude_re = None
        self.scenario_outline_annotation_schema = None  # pylint: disable=invalid-name
        self.steps_dir = "steps"
        self.environment_file = "environment.py"
        self.userdata_defines = None
        self.more_formatters = None
        if load_config:
            load_configuration(self.defaults, verbose=verbose)
        parser = setup_parser()
        parser.set_defaults(**self.defaults)
        args = parser.parse_args(command_args)
        for key, value in six.iteritems(args.__dict__):
            if key.startswith("_") and key not in self.cmdline_only_options:
                continue
            setattr(self, key, value)

        self.paths = [os.path.normpath(path) for path in self.paths]
        self.setup_outputs(args.outfiles)

        if self.steps_catalog:
            # -- SHOW STEP-CATALOG: As step summary.
            self.default_format = "steps.catalog"
            self.format = ["steps.catalog"]
            self.dry_run = True
            self.summary = False
            self.show_skipped = False
            self.quiet = True

        if self.wip:
            # Only run scenarios tagged with "wip".
            # Additionally:
            #  * use the "plain" formatter (per default)
            #  * do not capture stdout or logging output and
            #  * stop at the first failure.
            self.default_format = "plain"
            self.tags = ["wip"] + self.default_tags.split()
            self.color = False
            self.stop = True
            self.log_capture = False
            self.stdout_capture = False

        self.tags = TagExpression(self.tags or self.default_tags.split())

        if self.quiet:
            self.show_source = False
            self.show_snippets = False

        if self.exclude_re:
            self.exclude_re = re.compile(self.exclude_re)

        if self.include_re:
            self.include_re = re.compile(self.include_re)
        if self.name:
            # -- SELECT: Scenario-by-name, build regular expression.
            self.name_re = self.build_name_re(self.name)

        if self.stage is None:  # pylint: disable=access-member-before-definition
            # -- USE ENVIRONMENT-VARIABLE, if stage is undefined.
            self.stage = os.environ.get("BEHAVE_STAGE", None)
        self.setup_stage(self.stage)
        self.setup_model()
        self.setup_userdata()

        # -- FINALLY: Setup Reporters and Formatters
        # NOTE: Reporters and Formatters can now use userdata information.
        if self.junit:
            # Buffer the output (it will be put into Junit report)
            self.stdout_capture = True
            self.stderr_capture = True
            self.log_capture = True
            self.reporters.append(JUnitReporter(self))
        if self.summary:
            self.reporters.append(SummaryReporter(self))

        self.setup_formats()
        unknown_formats = self.collect_unknown_formats()
        if unknown_formats:
            parser.error("format=%s is unknown" % ", ".join(unknown_formats))


    def setup_outputs(self, args_outfiles=None):
        if self.outputs:
            assert not args_outfiles, "ONLY-ONCE"
            return

        # -- NORMAL CASE: Setup only initially (once).
        if not args_outfiles:
            self.outputs.append(StreamOpener(stream=sys.stdout))
        else:
            for outfile in args_outfiles:
                if outfile and outfile != "-":
                    self.outputs.append(StreamOpener(outfile))
                else:
                    self.outputs.append(StreamOpener(stream=sys.stdout))

    def setup_formats(self):
        """Register more, user-defined formatters by name."""
        if self.more_formatters:
            for name, scoped_class_name in self.more_formatters.items():
                _format_registry.register_as(name, scoped_class_name)

    def collect_unknown_formats(self):
        unknown_formats = []
        if self.format:
            for format_name in self.format:
                if (format_name == "help" or
                        _format_registry.is_formatter_valid(format_name)):
                    continue
                unknown_formats.append(format_name)
        return unknown_formats

    @staticmethod
    def build_name_re(names):
        """
        Build regular expression for scenario selection by name
        by using a list of name parts or name regular expressions.

        :param names: List of name parts or regular expressions (as text).
        :return: Compiled regular expression to use.
        """
        # -- NOTE: re.LOCALE is removed in Python 3.6 (deprecated in Python 3.5)
        # flags = (re.UNICODE | re.LOCALE)
        pattern = u"|".join(names)
        return re.compile(pattern, flags=re.UNICODE)

    def exclude(self, filename):
        if isinstance(filename, FileLocation):
            filename = six.text_type(filename)

        if self.include_re and self.include_re.search(filename) is None:
            return True
        if self.exclude_re and self.exclude_re.search(filename) is not None:
            return True
        return False

    def setup_logging(self, level=None, configfile=None, **kwargs):
        """
        Support simple setup of logging subsystem.
        Ensures that the logging level is set.
        But note that the logging setup can only occur once.

        SETUP MODES:
          * :func:`logging.config.fileConfig()`, if ``configfile`` is provided.
          * :func:`logging.basicConfig()`, otherwise.

        .. code-block: python
            # -- FILE: features/environment.py
            def before_all(context):
                context.config.setup_logging()

        :param level:       Logging level of root logger.
                            If None, use :attr:`logging_level` value.
        :param configfile:  Configuration filename for fileConfig() setup.
        :param kwargs:      Passed to :func:`logging.basicConfig()`
        """
        if level is None:
            level = self.logging_level      # pylint: disable=no-member

        if configfile:
            from logging.config import fileConfig
            fileConfig(configfile)
        else:
            # pylint: disable=no-member
            format_ = kwargs.pop("format", self.logging_format)
            datefmt = kwargs.pop("datefmt", self.logging_datefmt)
            logging.basicConfig(format=format_, datefmt=datefmt, **kwargs)
        # -- ENSURE: Default log level is set
        #    (even if logging subsystem is already configured).
        logging.getLogger().setLevel(level)

    def setup_model(self):
        if self.scenario_outline_annotation_schema:
            name_schema = six.text_type(self.scenario_outline_annotation_schema)
            ScenarioOutline.annotation_schema = name_schema.strip()

    def setup_stage(self, stage=None):
        """Setup the test stage that selects a different set of
        steps and environment implementations.

        :param stage:   Name of current test stage (as string or None).

        EXAMPLE::

            # -- SETUP DEFAULT TEST STAGE (unnamed):
            config = Configuration()
            config.setup_stage()
            assert config.steps_dir == "steps"
            assert config.environment_file == "environment.py"

            # -- SETUP PRODUCT TEST STAGE:
            config.setup_stage("product")
            assert config.steps_dir == "product_steps"
            assert config.environment_file == "product_environment.py"
        """
        steps_dir = "steps"
        environment_file = "environment.py"
        if stage:
            # -- USE A TEST STAGE: Select different set of implementations.
            prefix = stage + "_"
            steps_dir = prefix + steps_dir
            environment_file = prefix + environment_file
        self.steps_dir = steps_dir
        self.environment_file = environment_file

    def setup_userdata(self):
        if not isinstance(self.userdata, UserData):
            self.userdata = UserData(self.userdata)
        if self.userdata_defines:
            # -- ENSURE: Cmd-line overrides configuration file parameters.
            self.userdata.update(self.userdata_defines)

    def update_userdata(self, data):
        """Update userdata with data and reapply userdata defines (cmdline).
        :param data:  Provides (partial) userdata (as dict)
        """
        self.userdata.update(data)
        if self.userdata_defines:
            # -- REAPPLY: Cmd-line defines (override configuration file data).
            self.userdata.update(self.userdata_defines)
Esempio n. 42
0
 def test_getitem__returns_value_when_param_exists(self):
     userdata = UserData({"my.scope.param": "123"})
     config = UserDataNamespace("my.scope", userdata)
     assert config["param"] == "123"
Esempio n. 43
0
 def test_getfloat__with_known_param_and_invalid_text_raises_ValueError(self):
     userdata = UserData(param="__BAD_NUMBER__")
     with pytest.raises(ValueError):
         userdata.getfloat("param")
Esempio n. 44
0
 def test_getint__with_unknown_param_returns_default_value(self):
     userdata = UserData()
     value = userdata.getint("param", 123)
     assert isinstance(value, int)
     assert value == 123
Esempio n. 45
0
    def test_getas__with_unknown_param_without_default_returns_none(self):
        userdata = UserData()
        assert "param" not in userdata, "ENSURE: unknown param"

        value = userdata.getas(int, "param")
        assert value is None
Esempio n. 46
0
    def test_getas__with_unknown_param_without_default_returns_none(self):
        userdata = UserData()
        assert "param" not in userdata, "ENSURE: unknown param"

        value = userdata.getas(int, "param")
        assert value is None
Esempio n. 47
0
 def setup_userdata(self):
     if not isinstance(self.userdata, UserData):
         self.userdata = UserData(self.userdata)
     if self.userdata_defines:
         # -- ENSURE: Cmd-line overrides configuration file parameters.
         self.userdata.update(self.userdata_defines)
Esempio n. 48
0
 def test_getbool__returns_default_when_scoped_param_not_exists(self):
     userdata = UserData({})
     config = UserDataNamespace("my.scope", userdata)
     assert config.getint("UNKNOWN_PARAM", True) == True
     assert config.getint("UNKNOWN_PARAM", False) == False
Esempio n. 49
0
 def setup_userdata(self):
     if not isinstance(self.userdata, UserData):
         self.userdata = UserData(self.userdata)
     if self.userdata_defines:
         # -- ENSURE: Cmd-line overrides configuration file parameters.
         self.userdata.update(self.userdata_defines)
Esempio n. 50
0
 def test_getint__with_unknown_param_without_default_returns_zero(self):
     userdata = UserData()
     value = userdata.getint("param")
     assert value == 0