예제 #1
0
def test_ci_map_key_allowed_at_top_level(caplog):
    cfg = {
        'ci': {'skip': ['foo']},
        'repos': [{'repo': 'meta', 'hooks': [{'id': 'identity'}]}],
    }
    cfgv.validate(cfg, CONFIG_SCHEMA)
    assert not caplog.record_tuples
예제 #2
0
def test_validate_optional_sensible_regex_at_hook(caplog, regex, warning):
    config_obj = {
        'id': 'flake8',
        'files': regex,
    }
    cfgv.validate(config_obj, CONFIG_HOOK_DICT)

    assert caplog.record_tuples == [('pre_commit', logging.WARNING, warning)]
예제 #3
0
def test_validate_optional_sensible_regex_at_top_level(caplog, regex, warning):
    config_obj = {
        'files': regex,
        'repos': [],
    }
    cfgv.validate(config_obj, CONFIG_SCHEMA)

    assert caplog.record_tuples == [('pre_commit', logging.WARNING, warning)]
예제 #4
0
def test_warn_mutable_rev_conditional():
    config_obj = {
        'repo': 'meta',
        'rev': '3.7.7',
        'hooks': [{'id': 'flake8'}],
    }

    with pytest.raises(cfgv.ValidationError):
        cfgv.validate(config_obj, CONFIG_REPO_DICT)
예제 #5
0
def test_warn_mutable_rev_ok(caplog, rev):
    config_obj = {
        'repo': 'https://gitlab.com/pycqa/flake8',
        'rev': rev,
        'hooks': [{'id': 'flake8'}],
    }
    cfgv.validate(config_obj, CONFIG_REPO_DICT)

    assert caplog.record_tuples == []
예제 #6
0
def test_ensure_absent_conditional_in():
    with pytest.raises(ValidationError) as excinfo:
        validate({'key': 3, 'key2': True}, map_conditional_absent_in)
    expected = (
        'At foo(key=3)',
        'Expected key2 to be absent when key is not any of (1, 2), '
        'found key2: True',
    )
    _assert_exception_trace(excinfo.value, expected)
예제 #7
0
def test_no_additional_keys():
    with pytest.raises(ValidationError) as excinfo:
        validate({True: True, False: False}, no_additional_keys)
    expected = (
        'At Map()',
        'Additional keys found: False.  Only these keys are allowed: True',
    )
    _assert_exception_trace(excinfo.value, expected)

    validate({True: True}, no_additional_keys)
예제 #8
0
def test_validate_failure_nested():
    with pytest.raises(ValidationError) as excinfo:
        validate({'repo': 1, 'hooks': [{}]}, nested_schema_required)
    expected = (
        'At Repository(repo=1)',
        'At key: hooks',
        'At foo(key=MISSING)',
        'Missing required key: key',
    )
    _assert_exception_trace(excinfo.value, expected)
예제 #9
0
def test_minimum_pre_commit_version_failing():
    with pytest.raises(cfgv.ValidationError) as excinfo:
        cfg = {'repos': [], 'minimum_pre_commit_version': '999'}
        cfgv.validate(cfg, CONFIG_SCHEMA)
    assert str(excinfo.value) == (
        f'\n'
        f'==> At Config()\n'
        f'==> At key: minimum_pre_commit_version\n'
        f'=====> pre-commit version 999 is required but version {C.VERSION} '
        f'is installed.  Perhaps run `pip install --upgrade pre-commit`.')
def test_skip_referencing_missing_hook():
    cfg = {'ci': {'skip': ['identity']}, 'repos': []}
    with pytest.raises(cfgv.ValidationError) as excinfo:
        cfgv.validate(cfg, SCHEMA)
    assert _error_to_trace(excinfo.value) == (
        'At Config()',
        'At key: ci',
        'At key: skip',
        'unexpected hook ids: identity',
    )
예제 #11
0
def test_validate_failure_optional_recurse():
    with pytest.raises(ValidationError) as excinfo:
        validate({'links': [{}]}, optional_nested_schema)
    expected = (
        'At Config()',
        'At key: links',
        'At Link(key=MISSING)',
        'Missing required key: key',
    )
    _assert_exception_trace(excinfo.value, expected)
예제 #12
0
def test_conditional_optional_check(tvalue):
    with pytest.raises(ValidationError) as excinfo:
        validate({'t': tvalue, 'v': 2}, conditional_optional)
    expected = (
        'At Map()',
        'At key: v',
        'Expected bool got int',
    )
    _assert_exception_trace(excinfo.value, expected)

    validate({'t': tvalue, 'v': tvalue}, conditional_optional)
def test_autoupdate_commit_msg_cannot_be_empty():
    cfg = {'ci': {'autoupdate_commit_msg': ''}, 'repos': []}
    with pytest.raises(cfgv.ValidationError) as excinfo:
        cfgv.validate(cfg, SCHEMA)
    assert _error_to_trace(excinfo.value) == (
        'At Config()',
        'At key: ci',
        'At CI()',
        'At key: autoupdate_commit_msg',
        'string cannot be empty',
    )
예제 #14
0
def test_conditional_recurse_error():
    with pytest.raises(ValidationError) as excinfo:
        val = {'type': 'type1', 'params': {'p2': True}}
        validate(val, conditional_nested_schema)
    expected = (
        'At Config()',
        'At key: params',
        'At Params1()',
        'Missing required key: p1',
    )
    _assert_exception_trace(excinfo.value, expected)
예제 #15
0
def test_minimum_pre_commit_version_failing():
    with pytest.raises(cfgv.ValidationError) as excinfo:
        cfg = {'repos': [], 'minimum_pre_commit_version': '999'}
        cfgv.validate(cfg, CONFIG_SCHEMA)
    assert str(excinfo.value) == (
        '\n'
        '==> At Config()\n'
        '==> At key: minimum_pre_commit_version\n'
        '=====> pre-commit version 999 is required but version {} is '
        'installed.  Perhaps run `pip install --upgrade pre-commit`.'.format(
            C.VERSION,
        )
    )
예제 #16
0
def test_validate_optional_sensible_regex_at_hook_level(caplog):
    config_obj = {
        'id': 'flake8',
        'files': 'dir/*.py',
    }
    cfgv.validate(config_obj, CONFIG_HOOK_DICT)

    assert caplog.record_tuples == [
        (
            'pre_commit',
            logging.WARNING,
            "The 'files' field in hook 'flake8' is a regex, not a glob -- "
            "matching '/*' probably isn't what you want here",
        ),
    ]
예제 #17
0
def test_validate_optional_sensible_regex_at_top_level(caplog):
    config_obj = {
        'files': 'dir/*.py',
        'repos': [],
    }
    cfgv.validate(config_obj, CONFIG_SCHEMA)

    assert caplog.record_tuples == [
        (
            'pre_commit',
            logging.WARNING,
            "The top-level 'files' field is a regex, not a glob -- matching "
            "'/*' probably isn't what you want here",
        ),
    ]
예제 #18
0
def _get_hook_no_install(repo_config, store, hook_id):
    config = {'repos': [repo_config]}
    config = cfgv.validate(config, CONFIG_SCHEMA)
    config = cfgv.apply_defaults(config, CONFIG_SCHEMA)
    hooks = all_hooks(config, store)
    hook, = [hook for hook in hooks if hook.id == hook_id]
    return hook
예제 #19
0
 def from_yaml(cls, dct: Dict[str, Any]) -> 'GenerateOptions':
     dct = cfgv.apply_defaults(cfgv.validate(dct, SCHEMA), SCHEMA)
     return cls(
         skip_default_metrics=dct['skip_default_metrics'],
         metric_package_names=dct['metric_package_names'],
         repo=dct['repo'],
         database=dct['database'],
         exclude=re.compile(dct['exclude'].encode()),
     )
예제 #20
0
def test_config_with_local_hooks_definition_fails():
    config_obj = {
        'repos': [{
            'repo':
            'local',
            'rev':
            'foo',
            'hooks': [{
                'id': 'do_not_commit',
                'name': 'Block if "DO NOT COMMIT" is found',
                'entry': 'DO NOT COMMIT',
                'language': 'pcre',
                'files': '^(.*)$',
            }],
        }]
    }
    with pytest.raises(cfgv.ValidationError):
        cfgv.validate(config_obj, CONFIG_SCHEMA)
예제 #21
0
def test_warn_mutable_rev_invalid(caplog, rev):
    config_obj = {
        'repo': 'https://gitlab.com/pycqa/flake8',
        'rev': rev,
        'hooks': [{'id': 'flake8'}],
    }
    cfgv.validate(config_obj, CONFIG_REPO_DICT)

    assert caplog.record_tuples == [
        (
            'pre_commit',
            logging.WARNING,
            "The 'rev' field of repo 'https://gitlab.com/pycqa/flake8' "
            'appears to be a mutable reference (moving tag / branch).  '
            'Mutable references are never updated after first install and are '
            'not supported.  '
            'See https://pre-commit.com/#using-the-latest-version-for-a-repository '  # noqa: E501
            'for more details.  '
            'Hint: `pre-commit autoupdate` often fixes this.',
        ),
    ]
예제 #22
0
def make_config_from_repo(repo_path, rev=None, hooks=None, check=True):
    manifest = load_manifest(os.path.join(repo_path, C.MANIFEST_FILE))
    config = {
        'repo': 'file://{}'.format(repo_path),
        'rev': rev or git.head_rev(repo_path),
        'hooks': hooks or [{'id': hook['id']} for hook in manifest],
    }

    if check:
        wrapped = validate({'repos': [config]}, CONFIG_SCHEMA)
        wrapped = apply_defaults(wrapped, CONFIG_SCHEMA)
        config, = wrapped['repos']
        return config
    else:
        return config
예제 #23
0
def make_config_from_repo(repo_path, rev=None, hooks=None, check=True):
    manifest = load_manifest(os.path.join(repo_path, C.MANIFEST_FILE))
    config = OrderedDict((
        ('repo', 'file://{}'.format(repo_path)),
        ('rev', rev or git.head_rev(repo_path)),
        (
            'hooks',
            hooks or [OrderedDict((('id', hook['id']),)) for hook in manifest],
        ),
    ))

    if check:
        wrapped = validate({'repos': [config]}, CONFIG_SCHEMA)
        wrapped = apply_defaults(wrapped, CONFIG_SCHEMA)
        config, = wrapped['repos']
        return config
    else:
        return config
예제 #24
0
def test_warn_additional_keys_when_no_extra_keys(warn_additional_keys):
    validate({True: True}, warn_additional_keys.schema)
    assert not warn_additional_keys.record.called
예제 #25
0
def test_warn_additional_keys_when_has_extra_keys(warn_additional_keys):
    validate({True: True, False: False}, warn_additional_keys.schema)
    assert warn_additional_keys.record.called
예제 #26
0
def test_default_language_version_invalid(mapping):
    with pytest.raises(cfgv.ValidationError):
        cfgv.validate(mapping, DEFAULT_LANGUAGE_VERSION)
예제 #27
0
def test_minimum_pre_commit_version_passing():
    cfg = {'repos': [], 'minimum_pre_commit_version': '0'}
    cfgv.validate(cfg, CONFIG_SCHEMA)
예제 #28
0
def test_local_hooks_with_rev_fails():
    config_obj = {'repos': [dict(sample_local_config(), rev='foo')]}
    with pytest.raises(cfgv.ValidationError):
        cfgv.validate(config_obj, CONFIG_SCHEMA)
예제 #29
0
def test_conditional_recurse_ok(val):
    validate(val, conditional_nested_schema)
예제 #30
0
def test_optional_recurse_ok_missing():
    validate({}, optional_nested_schema)
예제 #31
0
def test_config_with_local_hooks_definition_passes():
    config_obj = {'repos': [sample_local_config()]}
    cfgv.validate(config_obj, CONFIG_SCHEMA)
예제 #32
0
def test_no_error_conditional_absent():
    validate({}, map_conditional_absent)
    validate({}, map_conditional_absent_not)
    validate({'key2': True}, map_conditional_absent)
    validate({'key2': True}, map_conditional_absent_not)
예제 #33
0
def test_not_ok_conditional_schemas(schema):
    with pytest.raises(ValidationError) as excinfo:
        validate({'key': True, 'key2': 5}, schema)
    expected = ('At foo(key=True)', 'At key: key2', 'Expected bool got int')
    _assert_exception_trace(excinfo.value, expected)
예제 #34
0
def test_ok_conditional_schemas(v, schema):
    validate(v, schema)
예제 #35
0
def test_meta_hook_invalid(config_repo):
    with pytest.raises(cfgv.ValidationError):
        cfgv.validate(config_repo, CONFIG_REPO_DICT)
예제 #36
0
def _hook_from_manifest_dct(dct):
    dct = validate(apply_defaults(dct, MANIFEST_HOOK_DICT), MANIFEST_HOOK_DICT)
    dct = _hook(dct)
    return dct
예제 #37
0
def is_valid_according_to_schema(obj, obj_schema):
    try:
        cfgv.validate(obj, obj_schema)
        return True
    except cfgv.ValidationError:
        return False