mirror of
https://github.com/wting/autojump
synced 2024-10-27 20:34:07 +00:00
Merge branch 'add_match_tests'
This commit is contained in:
commit
b9e70a0eea
@ -1,11 +1,12 @@
|
|||||||
- repo: git@github.com:pre-commit/pre-commit-hooks.git
|
- repo: git@github.com:pre-commit/pre-commit-hooks.git
|
||||||
sha: 6f2b0a27e5b9047c6c067fb3d575ba323d572793
|
sha: 35548254adb636ce52b5574eb1904b8c795b673e
|
||||||
hooks:
|
hooks:
|
||||||
- id: autopep8-wrapper
|
- id: autopep8-wrapper
|
||||||
args:
|
args:
|
||||||
- --in-place
|
- --in-place
|
||||||
- --aggressive
|
- --aggressive
|
||||||
- --aggressive
|
- --aggressive
|
||||||
|
- --max-line-length=131
|
||||||
- id: check-added-large-files
|
- id: check-added-large-files
|
||||||
- id: check-ast
|
- id: check-ast
|
||||||
- id: check-case-conflict
|
- id: check-case-conflict
|
||||||
@ -16,10 +17,10 @@
|
|||||||
- id: fix-encoding-pragma
|
- id: fix-encoding-pragma
|
||||||
- id: flake8
|
- id: flake8
|
||||||
args:
|
args:
|
||||||
- --max-complexity=10
|
- --max-complexity=10
|
||||||
- --max-line-length=130
|
- --max-line-length=131
|
||||||
- --ignore=E126,E128,E731
|
- --ignore=E126,E128,E731
|
||||||
- --exclude=bin/autojump_argparse.py
|
- --exclude=bin/autojump_argparse.py
|
||||||
- id: requirements-txt-fixer
|
- id: requirements-txt-fixer
|
||||||
- id: trailing-whitespace
|
- id: trailing-whitespace
|
||||||
- repo: git@github.com:asottile/reorder_python_imports.git
|
- repo: git@github.com:asottile/reorder_python_imports.git
|
||||||
|
14
Makefile
14
Makefile
@ -1,7 +1,7 @@
|
|||||||
VERSION = $(shell grep -oE "[0-9]+\.[0-9]+\.[0-9]+" bin/autojump)
|
VERSION = $(shell grep -oE "[0-9]+\.[0-9]+\.[0-9]+" bin/autojump)
|
||||||
TAGNAME = release-v$(VERSION)
|
TAGNAME = release-v$(VERSION)
|
||||||
|
|
||||||
.PHONY: docs install uninstall lint tar test
|
.PHONY: clean docs install uninstall pre-commit lint tar test
|
||||||
|
|
||||||
install:
|
install:
|
||||||
./install.py
|
./install.py
|
||||||
@ -39,9 +39,15 @@ tar:
|
|||||||
sha1sum autojump_v$(VERSION).tar.gz
|
sha1sum autojump_v$(VERSION).tar.gz
|
||||||
|
|
||||||
test: pre-commit
|
test: pre-commit
|
||||||
@find . -type f -iname '*.py[co]' -delete
|
@tox
|
||||||
tox
|
|
||||||
|
test-xfail: pre-commit
|
||||||
|
@tox -- --runxfail
|
||||||
|
|
||||||
test-fast: pre-commit
|
test-fast: pre-commit
|
||||||
|
@tox -e py27
|
||||||
|
|
||||||
|
clean:
|
||||||
@find . -type f -iname '*.py[co]' -delete
|
@find . -type f -iname '*.py[co]' -delete
|
||||||
tox -e py27
|
@find . -type d -iname '__pycache__' -delete
|
||||||
|
@rm -fr .tox
|
||||||
|
@ -63,7 +63,7 @@ INSTALLATION
|
|||||||
|
|
||||||
### REQUIREMENTS
|
### REQUIREMENTS
|
||||||
|
|
||||||
- Python v2.6+
|
- Python v2.6+ except v3.2
|
||||||
- Supported shells:
|
- Supported shells:
|
||||||
- bash v4.0+
|
- bash v4.0+
|
||||||
- zsh
|
- zsh
|
||||||
@ -148,7 +148,7 @@ maintained by William Ting. More contributors can be found in `AUTHORS`.
|
|||||||
COPYRIGHT
|
COPYRIGHT
|
||||||
---------
|
---------
|
||||||
|
|
||||||
Copyright © 2012 Free Software Foundation, Inc. License GPLv3+: GNU GPL
|
Copyright © 2016 Free Software Foundation, Inc. License GPLv3+: GNU GPL
|
||||||
version 3 or later <http://gnu.org/licenses/gpl.html>. This is free
|
version 3 or later <http://gnu.org/licenses/gpl.html>. This is free
|
||||||
software: you are free to change and redistribute it. There is NO
|
software: you are free to change and redistribute it. There is NO
|
||||||
WARRANTY, to the extent permitted by law.
|
WARRANTY, to the extent permitted by law.
|
||||||
|
120
bin/autojump
120
bin/autojump
@ -2,7 +2,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
Copyright © 2008-2012 Joel Schaerer
|
Copyright © 2008-2012 Joel Schaerer
|
||||||
Copyright © 2012-2014 William Ting
|
Copyright © 2012-2016 William Ting
|
||||||
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -18,16 +18,13 @@
|
|||||||
along with this program; if not, write to the Free Software Foundation, Inc.,
|
along with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
from difflib import SequenceMatcher
|
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from math import sqrt
|
from math import sqrt
|
||||||
from operator import attrgetter
|
from operator import attrgetter
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
import os
|
import os
|
||||||
import re
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
if sys.version_info[0] == 3:
|
if sys.version_info[0] == 3:
|
||||||
@ -38,13 +35,21 @@ else:
|
|||||||
from itertools import ifilter
|
from itertools import ifilter
|
||||||
from itertools import imap
|
from itertools import imap
|
||||||
|
|
||||||
|
# Vendorized argparse for Python 2.6 support
|
||||||
from autojump_argparse import ArgumentParser
|
from autojump_argparse import ArgumentParser
|
||||||
|
|
||||||
|
# autojump is not a standard python package but rather installed as a mixed
|
||||||
|
# shell + Python app with no outside dependencies (except Python). As a
|
||||||
|
# consequence we use relative imports and depend on file prefixes to prevent
|
||||||
|
# module conflicts.
|
||||||
from autojump_data import dictify
|
from autojump_data import dictify
|
||||||
from autojump_data import entriefy
|
from autojump_data import entriefy
|
||||||
from autojump_data import Entry
|
from autojump_data import Entry
|
||||||
from autojump_data import load
|
from autojump_data import load
|
||||||
from autojump_data import save
|
from autojump_data import save
|
||||||
|
from autojump_match import match_anywhere
|
||||||
|
from autojump_match import match_consecutive
|
||||||
|
from autojump_match import match_fuzzy
|
||||||
from autojump_utils import first
|
from autojump_utils import first
|
||||||
from autojump_utils import get_pwd
|
from autojump_utils import get_pwd
|
||||||
from autojump_utils import get_tab_entry_info
|
from autojump_utils import get_tab_entry_info
|
||||||
@ -60,7 +65,7 @@ from autojump_utils import sanitize
|
|||||||
from autojump_utils import take
|
from autojump_utils import take
|
||||||
from autojump_utils import unico
|
from autojump_utils import unico
|
||||||
|
|
||||||
VERSION = '22.3.2'
|
VERSION = '22.3.3'
|
||||||
FUZZY_MATCH_THRESHOLD = 0.6
|
FUZZY_MATCH_THRESHOLD = 0.6
|
||||||
TAB_ENTRIES_COUNT = 9
|
TAB_ENTRIES_COUNT = 9
|
||||||
TAB_SEPARATOR = '__'
|
TAB_SEPARATOR = '__'
|
||||||
@ -221,111 +226,6 @@ def handle_tab_completion(needle, entries):
|
|||||||
TAB_SEPARATOR)
|
TAB_SEPARATOR)
|
||||||
|
|
||||||
|
|
||||||
def match_anywhere(needles, haystack, ignore_case=False):
|
|
||||||
"""
|
|
||||||
Matches needles anywhere in the path as long as they're in the same (but
|
|
||||||
not necessary consecutive) order.
|
|
||||||
|
|
||||||
For example:
|
|
||||||
needles = ['foo', 'baz']
|
|
||||||
regex needle = r'.*foo.*baz.*'
|
|
||||||
haystack = [
|
|
||||||
(path="/foo/bar/baz", weight=10),
|
|
||||||
(path="/baz/foo/bar", weight=10),
|
|
||||||
(path="/foo/baz", weight=10)]
|
|
||||||
|
|
||||||
result = [
|
|
||||||
(path="/moo/foo/baz", weight=10),
|
|
||||||
(path="/foo/baz", weight=10)]
|
|
||||||
"""
|
|
||||||
regex_needle = '.*' + '.*'.join(needles).replace('\\', '\\\\') + '.*'
|
|
||||||
regex_flags = re.IGNORECASE | re.UNICODE if ignore_case else re.UNICODE
|
|
||||||
found = lambda haystack: re.search(
|
|
||||||
regex_needle,
|
|
||||||
haystack.path,
|
|
||||||
flags=regex_flags)
|
|
||||||
return ifilter(found, haystack)
|
|
||||||
|
|
||||||
|
|
||||||
def match_consecutive(needles, haystack, ignore_case=False):
|
|
||||||
"""
|
|
||||||
Matches consecutive needles at the end of a path.
|
|
||||||
|
|
||||||
For example:
|
|
||||||
needles = ['foo', 'baz']
|
|
||||||
haystack = [
|
|
||||||
(path="/foo/bar/baz", weight=10),
|
|
||||||
(path="/foo/baz/moo", weight=10),
|
|
||||||
(path="/moo/foo/baz", weight=10),
|
|
||||||
(path="/foo/baz", weight=10)]
|
|
||||||
|
|
||||||
regex_needle = re.compile(r'''
|
|
||||||
foo # needle #1
|
|
||||||
[^/]* # all characters except os.sep zero or more times
|
|
||||||
/ # os.sep
|
|
||||||
[^/]* # all characters except os.sep zero or more times
|
|
||||||
baz # needle #2
|
|
||||||
[^/]* # all characters except os.sep zero or more times
|
|
||||||
$ # end of string
|
|
||||||
''')
|
|
||||||
|
|
||||||
result = [
|
|
||||||
(path="/moo/foo/baz", weight=10),
|
|
||||||
(path="/foo/baz", weight=10)]
|
|
||||||
"""
|
|
||||||
# The normal \\ separator needs to be escaped again for use in regex.
|
|
||||||
sep = '\\\\' if is_windows() else os.sep
|
|
||||||
regex_no_sep = '[^' + sep + ']*'
|
|
||||||
regex_no_sep_end = regex_no_sep + '$'
|
|
||||||
regex_one_sep = regex_no_sep + sep + regex_no_sep
|
|
||||||
# can't use compiled regex because of flags
|
|
||||||
regex_needle = regex_one_sep.join(needles).replace('\\', '\\\\') + regex_no_sep_end # noqa
|
|
||||||
regex_flags = re.IGNORECASE | re.UNICODE if ignore_case else re.UNICODE
|
|
||||||
found = lambda entry: re.search(
|
|
||||||
regex_needle,
|
|
||||||
entry.path,
|
|
||||||
flags=regex_flags)
|
|
||||||
return ifilter(found, haystack)
|
|
||||||
|
|
||||||
|
|
||||||
def match_fuzzy(needles, haystack, ignore_case=False):
|
|
||||||
"""
|
|
||||||
Performs an approximate match with the last needle against the end of
|
|
||||||
every path past an acceptable threshold (FUZZY_MATCH_THRESHOLD).
|
|
||||||
|
|
||||||
For example:
|
|
||||||
needles = ['foo', 'bar']
|
|
||||||
haystack = [
|
|
||||||
(path="/foo/bar/baz", weight=11),
|
|
||||||
(path="/foo/baz/moo", weight=10),
|
|
||||||
(path="/moo/foo/baz", weight=10),
|
|
||||||
(path="/foo/baz", weight=10),
|
|
||||||
(path="/foo/bar", weight=10)]
|
|
||||||
|
|
||||||
result = [
|
|
||||||
(path="/foo/bar/baz", weight=11),
|
|
||||||
(path="/moo/foo/baz", weight=10),
|
|
||||||
(path="/foo/baz", weight=10),
|
|
||||||
(path="/foo/bar", weight=10)]
|
|
||||||
|
|
||||||
This is a weak heuristic and used as a last resort to find matches.
|
|
||||||
"""
|
|
||||||
end_dir = lambda path: last(os.path.split(path))
|
|
||||||
if ignore_case:
|
|
||||||
needle = last(needles).lower()
|
|
||||||
match_percent = lambda entry: SequenceMatcher(
|
|
||||||
a=needle,
|
|
||||||
b=end_dir(entry.path.lower())).ratio()
|
|
||||||
else:
|
|
||||||
needle = last(needles)
|
|
||||||
match_percent = lambda entry: SequenceMatcher(
|
|
||||||
a=needle,
|
|
||||||
b=end_dir(entry.path)).ratio()
|
|
||||||
meets_threshold = lambda entry: match_percent(entry) >= \
|
|
||||||
FUZZY_MATCH_THRESHOLD
|
|
||||||
return ifilter(meets_threshold, haystack)
|
|
||||||
|
|
||||||
|
|
||||||
def purge_missing_paths(entries):
|
def purge_missing_paths(entries):
|
||||||
"""Remove non-existent paths from a list of entries."""
|
"""Remove non-existent paths from a list of entries."""
|
||||||
exists = lambda entry: os.path.exists(entry.path)
|
exists = lambda entry: os.path.exists(entry.path)
|
||||||
|
127
bin/autojump_match.py
Normal file
127
bin/autojump_match.py
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
from difflib import SequenceMatcher
|
||||||
|
|
||||||
|
from autojump_utils import is_python3
|
||||||
|
from autojump_utils import last
|
||||||
|
|
||||||
|
|
||||||
|
if is_python3(): # pragma: no cover
|
||||||
|
ifilter = filter
|
||||||
|
imap = map
|
||||||
|
os.getcwdu = os.getcwd
|
||||||
|
else:
|
||||||
|
from itertools import ifilter
|
||||||
|
from itertools import imap
|
||||||
|
|
||||||
|
|
||||||
|
def match_anywhere(needles, haystack, ignore_case=False):
|
||||||
|
"""
|
||||||
|
Matches needles anywhere in the path as long as they're in the same (but
|
||||||
|
not necessary consecutive) order.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
needles = ['foo', 'baz']
|
||||||
|
regex needle = r'.*foo.*baz.*'
|
||||||
|
haystack = [
|
||||||
|
(path='/foo/bar/baz', weight=10),
|
||||||
|
(path='/baz/foo/bar', weight=10),
|
||||||
|
(path='/foo/baz', weight=10),
|
||||||
|
]
|
||||||
|
|
||||||
|
result = [
|
||||||
|
(path='/moo/foo/baz', weight=10),
|
||||||
|
(path='/foo/baz', weight=10),
|
||||||
|
]
|
||||||
|
"""
|
||||||
|
regex_needle = '.*' + '.*'.join(imap(re.escape, needles)) + '.*'
|
||||||
|
regex_flags = re.IGNORECASE | re.UNICODE if ignore_case else re.UNICODE
|
||||||
|
found = lambda haystack: re.search(
|
||||||
|
regex_needle,
|
||||||
|
haystack.path,
|
||||||
|
flags=regex_flags,
|
||||||
|
)
|
||||||
|
return ifilter(found, haystack)
|
||||||
|
|
||||||
|
|
||||||
|
def match_consecutive(needles, haystack, ignore_case=False):
|
||||||
|
"""
|
||||||
|
Matches consecutive needles at the end of a path.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
needles = ['foo', 'baz']
|
||||||
|
haystack = [
|
||||||
|
(path='/foo/bar/baz', weight=10),
|
||||||
|
(path='/foo/baz/moo', weight=10),
|
||||||
|
(path='/moo/foo/baz', weight=10),
|
||||||
|
(path='/foo/baz', weight=10),
|
||||||
|
]
|
||||||
|
|
||||||
|
# We can't actually use re.compile because of re.UNICODE
|
||||||
|
regex_needle = re.compile(r'''
|
||||||
|
foo # needle #1
|
||||||
|
[^/]* # all characters except os.sep zero or more times
|
||||||
|
/ # os.sep
|
||||||
|
[^/]* # all characters except os.sep zero or more times
|
||||||
|
baz # needle #2
|
||||||
|
[^/]* # all characters except os.sep zero or more times
|
||||||
|
$ # end of string
|
||||||
|
''')
|
||||||
|
|
||||||
|
result = [
|
||||||
|
(path='/moo/foo/baz', weight=10),
|
||||||
|
(path='/foo/baz', weight=10),
|
||||||
|
]
|
||||||
|
"""
|
||||||
|
regex_no_sep = '[^' + os.sep + ']*'
|
||||||
|
regex_no_sep_end = regex_no_sep + '$'
|
||||||
|
regex_one_sep = regex_no_sep + os.sep + regex_no_sep
|
||||||
|
regex_needle = regex_one_sep.join(imap(re.escape, needles)) + regex_no_sep_end
|
||||||
|
regex_flags = re.IGNORECASE | re.UNICODE if ignore_case else re.UNICODE
|
||||||
|
found = lambda entry: re.search(
|
||||||
|
regex_needle,
|
||||||
|
entry.path,
|
||||||
|
flags=regex_flags,
|
||||||
|
)
|
||||||
|
return ifilter(found, haystack)
|
||||||
|
|
||||||
|
|
||||||
|
def match_fuzzy(needles, haystack, ignore_case=False, threshold=0.6):
|
||||||
|
"""
|
||||||
|
Performs an approximate match with the last needle against the end of
|
||||||
|
every path past an acceptable threshold.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
needles = ['foo', 'bar']
|
||||||
|
haystack = [
|
||||||
|
(path='/foo/bar/baz', weight=11),
|
||||||
|
(path='/foo/baz/moo', weight=10),
|
||||||
|
(path='/moo/foo/baz', weight=10),
|
||||||
|
(path='/foo/baz', weight=10),
|
||||||
|
(path='/foo/bar', weight=10),
|
||||||
|
]
|
||||||
|
|
||||||
|
result = [
|
||||||
|
(path='/foo/bar/baz', weight=11),
|
||||||
|
(path='/moo/foo/baz', weight=10),
|
||||||
|
(path='/foo/baz', weight=10),
|
||||||
|
(path='/foo/bar', weight=10),
|
||||||
|
]
|
||||||
|
|
||||||
|
This is a weak heuristic and used as a last resort to find matches.
|
||||||
|
"""
|
||||||
|
end_dir = lambda path: last(os.path.split(path))
|
||||||
|
if ignore_case:
|
||||||
|
needle = last(needles).lower()
|
||||||
|
match_percent = lambda entry: SequenceMatcher(
|
||||||
|
a=needle,
|
||||||
|
b=end_dir(entry.path.lower())).ratio()
|
||||||
|
else:
|
||||||
|
needle = last(needles)
|
||||||
|
match_percent = lambda entry: SequenceMatcher(
|
||||||
|
a=needle,
|
||||||
|
b=end_dir(entry.path)).ratio()
|
||||||
|
meets_threshold = lambda entry: match_percent(entry) >= threshold
|
||||||
|
return ifilter(meets_threshold, haystack)
|
@ -127,7 +127,7 @@ maintained by William Ting.
|
|||||||
More contributors can be found in \f[C]AUTHORS\f[].
|
More contributors can be found in \f[C]AUTHORS\f[].
|
||||||
.SS COPYRIGHT
|
.SS COPYRIGHT
|
||||||
.PP
|
.PP
|
||||||
Copyright © 2012 Free Software Foundation, Inc.
|
Copyright © 2016 Free Software Foundation, Inc.
|
||||||
License GPLv3+: GNU GPL version 3 or later
|
License GPLv3+: GNU GPL version 3 or later
|
||||||
<http://gnu.org/licenses/gpl.html>.
|
<http://gnu.org/licenses/gpl.html>.
|
||||||
This is free software: you are free to change and redistribute it.
|
This is free software: you are free to change and redistribute it.
|
||||||
|
@ -28,7 +28,7 @@ William Ting. More contributors can be found in `AUTHORS`.
|
|||||||
COPYRIGHT
|
COPYRIGHT
|
||||||
---------
|
---------
|
||||||
|
|
||||||
Copyright © 2012 Free Software Foundation, Inc. License GPLv3+: GNU GPL version
|
Copyright © 2016 Free Software Foundation, Inc. License GPLv3+: GNU GPL version
|
||||||
3 or later <http://gnu.org/licenses/gpl.html>. This is free software: you are
|
3 or later <http://gnu.org/licenses/gpl.html>. This is free software: you are
|
||||||
free to change and redistribute it. There is NO WARRANTY, to the extent
|
free to change and redistribute it. There is NO WARRANTY, to the extent
|
||||||
permitted by law.
|
permitted by law.
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
### REQUIREMENTS
|
### REQUIREMENTS
|
||||||
|
|
||||||
- Python v2.6+
|
- Python v2.6+ except v3.2
|
||||||
- Supported shells:
|
- Supported shells:
|
||||||
- bash v4.0+
|
- bash v4.0+
|
||||||
- zsh
|
- zsh
|
||||||
@ -41,7 +41,7 @@ MacPorts also available:
|
|||||||
|
|
||||||
## Windows
|
## Windows
|
||||||
|
|
||||||
Windows support is enabled by [clink](https://code.google.com/p/clink/) which
|
Windows support is enabled by [clink](https://mridgers.github.io/clink/) which
|
||||||
should be installed prior to installing autojump.
|
should be installed prior to installing autojump.
|
||||||
|
|
||||||
### MANUAL
|
### MANUAL
|
||||||
|
@ -1 +0,0 @@
|
|||||||
tox
|
|
131
tests/unit/autojump_match_test.py
Normal file
131
tests/unit/autojump_match_test.py
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
sys.path.append(os.path.join(os.getcwd(), 'bin')) # noqa
|
||||||
|
from autojump_data import Entry
|
||||||
|
from autojump_match import match_anywhere
|
||||||
|
from autojump_match import match_consecutive
|
||||||
|
|
||||||
|
|
||||||
|
class TestMatchAnywhere(object):
|
||||||
|
|
||||||
|
entry1 = Entry('/foo/bar/baz', 10)
|
||||||
|
entry2 = Entry('/baz/foo/bar', 10)
|
||||||
|
entry3 = Entry('/foo/baz', 10)
|
||||||
|
entry4 = Entry('/中/zhong/国/guo', 10)
|
||||||
|
entry5 = Entry('/is\'t/this/a/b*tchin/edge/case?', 10)
|
||||||
|
win_entry1 = Entry('C:\\foo\\bar\\baz', 10)
|
||||||
|
win_entry2 = Entry('D:\Program Files (x86)\GIMP', 10)
|
||||||
|
win_entry3 = Entry('C:\Windows\System32', 10)
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def haystack(self):
|
||||||
|
return [
|
||||||
|
self.entry1,
|
||||||
|
self.entry2,
|
||||||
|
self.entry3,
|
||||||
|
self.entry4,
|
||||||
|
self.entry5,
|
||||||
|
]
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def windows_haystack(self):
|
||||||
|
return [self.win_entry1, self.win_entry2, self.win_entry3]
|
||||||
|
|
||||||
|
def test_single_needle(self, haystack):
|
||||||
|
assert list(match_anywhere(['bar'], haystack)) == [self.entry1, self.entry2]
|
||||||
|
|
||||||
|
def test_consecutive(self, haystack):
|
||||||
|
assert list(match_anywhere(['foo', 'bar'], haystack)) \
|
||||||
|
== [self.entry1, self.entry2]
|
||||||
|
assert list(match_anywhere(['bar', 'foo'], haystack)) == []
|
||||||
|
|
||||||
|
def test_skip(self, haystack):
|
||||||
|
assert list(match_anywhere(['baz', 'bar'], haystack)) == [self.entry2]
|
||||||
|
assert list(match_anywhere(['中', '国'], haystack)) == [self.entry4]
|
||||||
|
|
||||||
|
def test_ignore_case(self, haystack):
|
||||||
|
assert list(match_anywhere(['bAz', 'bAR'], haystack, ignore_case=True)) \
|
||||||
|
== [self.entry2]
|
||||||
|
|
||||||
|
def test_backslashes_for_windows_paths(self, windows_haystack):
|
||||||
|
# https://github.com/wting/autojump/issues/281
|
||||||
|
assert list(match_anywhere(['foo', 'baz'], windows_haystack)) \
|
||||||
|
== [self.win_entry1]
|
||||||
|
assert list(match_anywhere(['program', 'gimp'], windows_haystack, True)) \
|
||||||
|
== [self.win_entry2]
|
||||||
|
assert list(match_anywhere(['win', '32'], windows_haystack, True)) \
|
||||||
|
== [self.win_entry3]
|
||||||
|
|
||||||
|
def test_wildcard_in_needle(self, haystack):
|
||||||
|
# https://github.com/wting/autojump/issues/402
|
||||||
|
assert list(match_anywhere(['*', 'this'], haystack)) == []
|
||||||
|
assert list(match_anywhere(['this', '*'], haystack)) == [self.entry5]
|
||||||
|
|
||||||
|
|
||||||
|
class TestMatchConsecutive(object):
|
||||||
|
|
||||||
|
entry1 = Entry('/foo/bar/baz', 10)
|
||||||
|
entry2 = Entry('/baz/foo/bar', 10)
|
||||||
|
entry3 = Entry('/foo/baz', 10)
|
||||||
|
entry4 = Entry('/中/zhong/国/guo', 10)
|
||||||
|
entry5 = Entry('/日/本', 10)
|
||||||
|
entry6 = Entry('/is\'t/this/a/b*tchin/edge/case?', 10)
|
||||||
|
win_entry1 = Entry('C:\Foo\Bar\Baz', 10)
|
||||||
|
win_entry2 = Entry('D:\Program Files (x86)\GIMP', 10)
|
||||||
|
win_entry3 = Entry('C:\Windows\System32', 10)
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def haystack(self):
|
||||||
|
return [
|
||||||
|
self.entry1,
|
||||||
|
self.entry2,
|
||||||
|
self.entry3,
|
||||||
|
self.entry4,
|
||||||
|
self.entry5,
|
||||||
|
]
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def windows_haystack(self):
|
||||||
|
return [self.win_entry1, self.win_entry2, self.win_entry3]
|
||||||
|
|
||||||
|
def test_single_needle(self, haystack):
|
||||||
|
assert list(match_consecutive(['baz'], haystack)) == [self.entry1, self.entry3]
|
||||||
|
assert list(match_consecutive(['本'], haystack)) == [self.entry5]
|
||||||
|
|
||||||
|
def test_consecutive(self, haystack):
|
||||||
|
assert list(match_consecutive(['bar', 'baz'], haystack)) == [self.entry1]
|
||||||
|
assert list(match_consecutive(['foo', 'bar'], haystack)) == [self.entry2]
|
||||||
|
assert list(match_consecutive(['国', 'guo'], haystack)) == [self.entry4]
|
||||||
|
assert list(match_consecutive(['bar', 'foo'], haystack)) == []
|
||||||
|
|
||||||
|
def test_ignore_case(self, haystack):
|
||||||
|
assert list(match_consecutive(['FoO', 'bAR'], haystack, ignore_case=True)) \
|
||||||
|
== [self.entry2]
|
||||||
|
|
||||||
|
def test_windows_ignore_case(self, windows_haystack):
|
||||||
|
assert list(match_consecutive(['gimp'], windows_haystack, True)) == [self.win_entry2]
|
||||||
|
|
||||||
|
@pytest.mark.xfail(reason='https://github.com/wting/autojump/issues/418')
|
||||||
|
def test_backslashes_for_windows_paths(self, windows_haystack):
|
||||||
|
assert list(match_consecutive(['program', 'gimp'], windows_haystack, True)) \
|
||||||
|
== [self.win_entry2]
|
||||||
|
|
||||||
|
@pytest.mark.xfail(reason='https://github.com/wting/autojump/issues/418')
|
||||||
|
def test_foo_bar_baz(self, windows_haystack):
|
||||||
|
assert list(match_consecutive(['bar', 'baz'], windows_haystack, ignore_case=True)) \
|
||||||
|
== [self.win_entry1]
|
||||||
|
|
||||||
|
@pytest.mark.xfail(reason='https://github.com/wting/autojump/issues/402')
|
||||||
|
def test_thing(self, windows_haystack):
|
||||||
|
assert list(match_consecutive(['win', '32'], windows_haystack, True)) \
|
||||||
|
== [self.win_entry3]
|
||||||
|
|
||||||
|
@pytest.mark.xfail(reason='https://github.com/wting/autojump/issues/402')
|
||||||
|
def test_wildcard_in_needle(self, haystack):
|
||||||
|
assert list(match_consecutive(['*', 'this'], haystack)) == []
|
||||||
|
assert list(match_consecutive(['*', 'edge', 'case'], haystack)) == [self.entry6]
|
@ -6,20 +6,20 @@ import sys
|
|||||||
import mock
|
import mock
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
sys.path.append(os.path.join(os.getcwd(), 'bin'))
|
sys.path.append(os.path.join(os.getcwd(), 'bin')) # noqa
|
||||||
import autojump_utils # noqa
|
import autojump_utils
|
||||||
from autojump_utils import encode_local # noqa
|
from autojump_utils import encode_local
|
||||||
from autojump_utils import first # noqa
|
from autojump_utils import first
|
||||||
from autojump_utils import get_tab_entry_info # noqa
|
from autojump_utils import get_tab_entry_info
|
||||||
from autojump_utils import has_uppercase # noqa
|
from autojump_utils import has_uppercase
|
||||||
from autojump_utils import in_bash # noqa
|
from autojump_utils import in_bash
|
||||||
from autojump_utils import is_python3 # noqa
|
from autojump_utils import is_python3
|
||||||
from autojump_utils import last # noqa
|
from autojump_utils import last
|
||||||
from autojump_utils import sanitize # noqa
|
from autojump_utils import sanitize
|
||||||
from autojump_utils import second # noqa
|
from autojump_utils import second
|
||||||
from autojump_utils import surround_quotes # noqa
|
from autojump_utils import surround_quotes
|
||||||
from autojump_utils import take # noqa
|
from autojump_utils import take
|
||||||
from autojump_utils import unico # noqa
|
from autojump_utils import unico
|
||||||
|
|
||||||
|
|
||||||
if is_python3():
|
if is_python3():
|
23
tox.ini
23
tox.ini
@ -2,13 +2,13 @@
|
|||||||
envlist =
|
envlist =
|
||||||
py26,
|
py26,
|
||||||
py27,
|
py27,
|
||||||
py32,
|
|
||||||
py33,
|
py33,
|
||||||
py34
|
py34,
|
||||||
|
py35
|
||||||
# ignore missing setup.py
|
# ignore missing setup.py
|
||||||
skipsdist = True
|
skipsdist = True
|
||||||
|
|
||||||
[testenv:py]
|
[testenv]
|
||||||
setenv =
|
setenv =
|
||||||
PYTHONDONTWRITEBYTECODE = 1
|
PYTHONDONTWRITEBYTECODE = 1
|
||||||
deps =
|
deps =
|
||||||
@ -16,24 +16,17 @@ deps =
|
|||||||
coverage
|
coverage
|
||||||
ipdb
|
ipdb
|
||||||
ipython
|
ipython
|
||||||
pytest
|
pytest >= 2.9
|
||||||
commands =
|
commands =
|
||||||
coverage run --source=bin/ -m pytest -vv -rxs --tb native -s --durations 10 --strict {posargs:tests}
|
coverage run --source=bin/ --omit=bin/autojump_argparse.py -m \
|
||||||
|
py.test -vv -rxs --tb native -s --strict {posargs:tests}
|
||||||
coverage report -m
|
coverage report -m
|
||||||
|
|
||||||
[testenv:flake8]
|
|
||||||
deps =
|
|
||||||
flake8
|
|
||||||
pyflakes
|
|
||||||
pep8
|
|
||||||
mccabe
|
|
||||||
commands =
|
|
||||||
flake8 .
|
|
||||||
|
|
||||||
[testenv:pre-commit]
|
[testenv:pre-commit]
|
||||||
deps =
|
deps =
|
||||||
pre-commit
|
pre-commit>=0.7.0
|
||||||
command =
|
commands =
|
||||||
pre-commit {posargs}
|
pre-commit {posargs}
|
||||||
|
|
||||||
[pytest]
|
[pytest]
|
||||||
|
Loading…
Reference in New Issue
Block a user