diff --git a/.github/workflows/code-counter-CI.yml b/.github/workflows/code-counter-CI.yml index c886360..588243a 100644 --- a/.github/workflows/code-counter-CI.yml +++ b/.github/workflows/code-counter-CI.yml @@ -17,4 +17,4 @@ jobs: with: python-version: ${{ matrix.python-version }} - name: Test with pytest - run: python -m unittest discover -s test -p "test.py" + run: python -m unittest discover -s tests -p "test_*.py" diff --git a/Makefile b/Makefile index 31e565d..d3157b1 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,10 @@ +.PHONY: +test: + python -m unittest discover -s tests -p "test_*.py" + setup: python setup.py install - -.PHONY: check: python setup.py check @@ -19,4 +21,4 @@ uninstall: echo y | pip uninstall code-counter clean: - rm -rf build code_counter.* dist \ No newline at end of file + rm -rf build code_counter.* dist diff --git a/code_counter/__init__.py b/code_counter/__init__.py index 5f1e750..5becc17 100644 --- a/code_counter/__init__.py +++ b/code_counter/__init__.py @@ -1 +1 @@ -__version__ = "1.0.0-alpha" +__version__ = "1.0.0" diff --git a/code_counter/conf/config.json b/code_counter/conf/config.json index ae13b3c..9c18bb0 100644 --- a/code_counter/conf/config.json +++ b/code_counter/conf/config.json @@ -1,55 +1,55 @@ { "suffix": [ - "c", + "java", + "swift", + "dart", + "rb", "cc", - "clj", - "cpp", - "cs", + "go", + "php", + "sh", + "lua", + "m", "cu", + "c", + "vb", + "clj", + "js", "cuh", - "dart", - "go", - "h", "hpp", - "java", - "jl", - "js", + "R", + "cs", "kt", - "lisp", - "lua", - "pde", - "m", - "php", + "ts", + "scala", + "rust", "py", - "R", - "rb", + "cpp", "rs", - "rust", - "sh", - "scala", - "swift", - "ts", - "vb" + "h", + "jl", + "pde", + "lisp" ], "comment": [ - "#", "//", - "/*", + ":", "*", "*/", - ":", ";", - "\"\"\"\"" + "#", + "\"\"\"\"", + "/*" ], "ignore": [ - "out", "venv", - ".git", - ".idea", - "build", + "dist", "target", + "build", + ".idea", "node_modules", ".vscode", - "dist" + ".git", + "out" ] } \ No newline at end of file diff --git a/code_counter/conf/config.py b/code_counter/conf/config.py index 3f5f2b1..2bf209b 100644 --- a/code_counter/conf/config.py +++ b/code_counter/conf/config.py @@ -5,56 +5,78 @@ import pkg_resources +class SetEncoder(json.JSONEncoder): + def default(self, obj): + if isinstance(obj, set): + return list(obj) + return json.JSONEncoder.default(self, obj) + + class Config: def __init__(self): conf = self.__load() - self.suffix = conf['suffix'] - self.comment = conf['comment'] - self.ignore = conf['ignore'] + self.suffix = set(conf['suffix']) + self.comment = set(conf['comment']) + self.ignore = set(conf['ignore']) def invoke(self, args): if args.restore: self.restore() else: - if any([args.suffix_add, args.comment_add, args.ignore_add]): - self.__append_config(args.suffix_add, args.comment_add, args.ignore_add) if any([args.suffix_reset, args.comment_reset, args.ignore_reset]): self.__reset_config(args.suffix_reset, args.comment_reset, args.ignore_reset) + if any([args.suffix_add, args.comment_add, args.ignore_add]): + self.__append_config(args.suffix_add, args.comment_add, args.ignore_add) + if any([args.suffix_del, args.comment_del, args.ignore_del]): + self.__remove_config(args.suffix_del, args.comment_del, args.ignore_del) if args.show_list: self.show() def show(self): - print(json.dumps(self.__dict__, indent=4)) + print(json.dumps(self.__dict__, indent=4, cls=SetEncoder)) def __confirm(self, tips): check = input(tips) return check.strip().lower() == 'y' + def __reset_config(self, suffix_reset, comment_reset, ignore_reset): + if suffix_reset: + if self.__confirm("'suffix' will be replaced with {} . (y/n) ".format(suffix_reset)): + self.suffix = set(suffix_reset) + if comment_reset: + if self.__confirm("'comment' will be replaced with {} . (y/n) ".format(comment_reset)): + self.comment = set(comment_reset) + if ignore_reset: + if self.__confirm("'ignore' will be replaced with {} . (y/n) ".format(ignore_reset)): + self.ignore = set(ignore_reset) + + self.__update() + def __append_config(self, suffix_add, comment_add, ignore_add): if suffix_add: - if self.__confirm("'suffix' will be appended with {} (y/n)".format(suffix_add)): - self.suffix.extend(suffix_add) + if self.__confirm("'suffix' will be appended with {} . (y/n) ".format(suffix_add)): + self.suffix.update(suffix_add) if comment_add: - if self.__confirm("'comment' will be appended with {} (y/n)".format(comment_add)): - self.comment.extend(comment_add) + if self.__confirm("'comment' will be appended with {} . (y/n) ".format(comment_add)): + self.comment.update(comment_add) if ignore_add: - if self.__confirm("'ignore' will be appended with {} (y/n)".format(ignore_add)): - self.ignore.extend(ignore_add) + if self.__confirm("'ignore' will be appended with {} . (y/n) ".format(ignore_add)): + self.ignore.update(ignore_add) self.__update() - def __reset_config(self, suffix_reset, comment_reset, ignore_reset): - if suffix_reset: - if self.__confirm("'suffix' will be replaced with {} (y/n)".format(suffix_reset)): - self.suffix = suffix_reset - if comment_reset: - if self.__confirm("'comment' will be replaced with {} (y/n)".format(comment_reset)): - self.comment = comment_reset - if ignore_reset: - if self.__confirm("'ignore' will be replaced with {} (y/n)".format(ignore_reset)): - self.ignore = ignore_reset + def __remove_config(self, suffix_del, comment_del, ignore_del): + if suffix_del: + if self.__confirm("'suffix' will remove {} . (y/n) ".format(suffix_del)): + self.suffix.difference_update(suffix_del) + if comment_del: + if self.__confirm("'comment' will remove {} . (y/n) ".format(comment_del)): + self.comment.difference_update(comment_del) + if ignore_del: + if self.__confirm("'ignore' will remove {} . (y/n) ".format(ignore_del)): + self.ignore.difference_update(ignore_del) self.__update() @@ -67,14 +89,14 @@ def __load(self): def __update(self): filename = pkg_resources.resource_filename(__name__, 'config.json') with open(filename, 'w') as config: - json.dump(self.__dict__, config, indent=4) + json.dump(self.__dict__, config, indent=4, cls=SetEncoder) def restore(self): - self.suffix = ["c", "cc", "clj", "cpp", "cs", "cu", "cuh", "dart", "go", "h", - "hpp", "java", "jl", "js", "kt", "lisp", "lua", "pde", "m", "php", - "py", "R", "rb", "rs", "rust", "sh", "scala", "swift", "ts", "vb"] - self.comment = ["#", "//", "/*", "*", "*/", ":", ";", '""""'] - self.ignore = ["out", "venv", ".git", ".idea", "build", "target", "node_modules", ".vscode", "dist"] + self.suffix = {"c", "cc", "clj", "cpp", "cs", "cu", "cuh", "dart", "go", "h", "hpp", "java", "jl", "js", "kt", + "lisp", "lua", "pde", "m", "php", "py", "R", "rb", "rs", "rust", "sh", "scala", "swift", "ts", + "vb"} + self.comment = {"#", "//", "/*", "*", "*/", ":", ";", '""""'} + self.ignore = {"out", "venv", ".git", ".idea", "build", "target", "node_modules", ".vscode", "dist"} - if self.__confirm('Default configuration will be restored (y/n)?'): + if self.__confirm('The default configuration will be restored. (y/n) '): self.__update() diff --git a/code_counter/core/args.py b/code_counter/core/args.py index bac6259..dd731cd 100644 --- a/code_counter/core/args.py +++ b/code_counter/core/args.py @@ -61,21 +61,19 @@ def __search(self): usage="cocnt search input_path [-h] [-v] [-g] " "[-o OUTPUT_PATH] [--suffix SUFFIX] [--comment COMMENT] [--ignore IGNORE]") parser.add_argument('input_path', type=split_args, - help="counting the code lines according the given path(s)") + help="counting the code lines according to the given path(s)") parser.add_argument('-v', '--verbose', dest="verbose", action='store_true', - help="show verbose infomation") + help="show verbose information") parser.add_argument('-g', '--graph', dest='graph', action='store_true', help="choose to whether to visualize the result") parser.add_argument('-o', '--output', dest='output_path', - help="specify a output path if you want to store the result") + help="specify an output path if you want to store the result") parser.add_argument('--suffix', dest='suffix', type=split_args, - help="what code files do you want to count, this parameter is disposable") + help="what code files do you want to count") parser.add_argument('--comment', dest='comment', type=split_args, - help="the comment symbol, which can be judged whether the current line is a comment, " - "this parameter is disposable") + help="the comment symbol, which can be judged whether the current line is a comment") parser.add_argument('--ignore', dest='ignore', type=split_args, - help="ignore some directories or files that you don't want to count, " - "this parameter is disposable") + help="ignore some directories or files that you don't want to count") return parser.parse_args(sys.argv[2:]) def __config(self): @@ -87,24 +85,31 @@ def __config(self): "[--comment-add COMMENT_ADD] [--ignore-reset IGNORE_RESET] " "[--ignore-add IGNORE_ADD] [--restore] ") parser.add_argument('--list', dest='show_list', action='store_true', - help="list all variables set in config file, along with their values") + help="list all variables set in the config file, along with their values") parser.add_argument('--suffix-reset', dest='suffix_reset', type=split_args, - help="override 'suffix' in config and count codes according to this value") + help="reset the 'suffix' in the config and count code lines according to this value") parser.add_argument('--suffix-add', dest='suffix_add', type=split_args, - help="append new value for 'suffix' in config and count codes according to this value") + help="append new value for the 'suffix' in the config " + "and count code lines according to this value") + parser.add_argument('--suffix-del', dest='suffix_del', type=split_args, + help="delete some values of the 'suffix' in the config") parser.add_argument('--comment-reset', dest='comment_reset', type=split_args, - help="override 'comment' in config and count comment lines according to this value") + help="reset the 'comment' in the config and count comment lines according to this value") parser.add_argument('--comment-add', dest='comment_add', type=split_args, - help="append new value for 'comment' in config " + help="append new value for the 'comment' in the config " "and count comment lines according to this value") + parser.add_argument('--comment-del', dest='comment_del', type=split_args, + help="delete some values of the 'comment' in the config") parser.add_argument('--ignore-reset', dest='ignore_reset', type=split_args, - help="override 'ignore' in config " - "and ignore some files or directory according to this value") + help="reset the 'ignore' in the config " + "and ignore some files or directories according to this value") parser.add_argument('--ignore-add', dest='ignore_add', type=split_args, - help="append new value for 'ignore' in config " - "and ignore some files or directory according to this value") + help="append new value for the 'ignore' in the config " + "and ignore some files or directories according to this value") + parser.add_argument('--ignore-del', dest='ignore_del', type=split_args, + help="delete some values of the 'ignore' in the config") parser.add_argument('--restore', dest='restore', action='store_true', help="restore default config") diff --git a/setup.py b/setup.py index 8920293..b6d5160 100644 --- a/setup.py +++ b/setup.py @@ -1,22 +1,24 @@ - import os from setuptools import setup, find_packages -short_desc = "A command-line interface (CLI) utility that can help you easily count code and display detailed results." +short_desc = "A command-line interface (CLI) utility " \ + "that can help you easily count code lines and display detailed results." + def read_readme(file_name): with open(os.path.join(os.path.dirname(__file__), file_name), encoding='utf-8') as f: return f.read() + setup(name='code-counter', version=__import__('code_counter').__version__, author="Inno Fang", author_email="innofang@yeah.net", url='https://github.com/innofang/code-counter', # homepage project_urls={ - 'Documentation': 'https://github.com/InnoFang/code-counter/blob/master/README.md', - 'Source': 'https://github.com/InnoFang/code-counter', - 'Bug Reports': 'https://github.com/InnoFang/code-counter/issues', + 'Documentation': 'https://github.com/InnoFang/code-counter/blob/master/README.md', + 'Source': 'https://github.com/InnoFang/code-counter', + 'Bug Reports': 'https://github.com/InnoFang/code-counter/issues', }, description=short_desc, long_description=read_readme('README.md'), @@ -24,25 +26,25 @@ def read_readme(file_name): include_package_data=True, long_description_content_type="text/markdown", license='Apache License', - install_requires = ["matplotlib", "numpy"], - python_requires='>=3.5', + install_requires=["matplotlib", "numpy"], + python_requires='>=3.6', classifiers=[ - 'Development Status :: 4 - Beta', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: Apache Software License', - 'Environment :: Console', - 'Topic :: Utilities', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - ], + 'Development Status :: 4 - Beta', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: Apache Software License', + 'Environment :: Console', + 'Topic :: Utilities', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + ], entry_points={ 'console_scripts': [ 'cocnt = code_counter.__main__:main' ] }, keywords='code count line file counter', -) \ No newline at end of file + ) diff --git a/test/.gitkeep b/test/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/tests/test_args.py b/tests/test_args.py new file mode 100644 index 0000000..68189e1 --- /dev/null +++ b/tests/test_args.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +# coding:utf8 + +import sys +import os +import unittest +from code_counter.core.args import CodeCounterArgs + +test_path = os.path.abspath('.') +bin_path = os.path.dirname(os.path.join(os.pardir, '..')) +lib_path = os.path.abspath(os.path.join(bin_path, 'code_counter')) +app_path = os.path.join(lib_path, '__main__.py') + + +class CodeCounterArgsTest(unittest.TestCase): + def test_search_args(self): + options = ['python', app_path, + 'search', + '../code_counter/', + '-v', + '-g', + '-o=output.txt', + '--suffix=py,java,cpp', + '--comment=//,#,/*', + '--ignore=.vscode,.idea'] + sys.argv[1:] = options[2:] + args = CodeCounterArgs() + self.assertFalse(args.has_config_args(), '"config" is in the "args"') + self.assertTrue(args.has_search_args(), '"search" is not in the "args"') + search_args = args.search() + self.assertEqual(search_args.input_path, ['../code_counter/'], "search path parsed error.") + self.assertTrue(search_args.verbose, '-v,--verbose flag parsed error.') + self.assertTrue(search_args.graph, '-g,--graph flag parsed error.') + self.assertEqual(search_args.output_path, 'output.txt', "output path parsed error.") + self.assertEqual(search_args.suffix, ['py', 'java', 'cpp'], "suffix flag and values parsed error.") + self.assertEqual(search_args.comment, ['//', '#', '/*'], "comment flag and values parsed error.") + self.assertEqual(search_args.ignore, ['.vscode', '.idea'], "ignore flag and values parsed error.") + + def test_config_args(self): + options = ['python', app_path, + 'config', + '--list', + '--suffix-add=lisp', + '--suffix-reset=clj', + '--comment-add=//', + '--comment-reset=;', + '--ignore-add=.idea', + '--ignore-reset=target', + '--restore'] + sys.argv[1:] = options[2:] + args = CodeCounterArgs() + self.assertTrue(args.has_config_args(), '"config" is not in the "args"') + self.assertFalse(args.has_search_args(), '"search" is in the "args"') + config_args = args.config() + self.assertTrue(config_args.show_list, '--list flag parsed error.') + self.assertEqual(config_args.suffix_add, ['lisp'], "suffix_add flag and values parsed error.") + self.assertEqual(config_args.suffix_reset, ['clj'], "suffix_reset flag and values parsed error.") + self.assertEqual(config_args.comment_add, ['//'], "comment_add flag and values parsed error.") + self.assertEqual(config_args.comment_reset, [';'], "comment_reset flag and values parsed error.") + self.assertEqual(config_args.ignore_add, ['.idea'], "ignore_add flag and values parsed error.") + self.assertEqual(config_args.ignore_reset, ['target'], "ignore_reset flag and values parsed error.") + self.assertTrue(config_args.restore, '--restore flag parsed error.') diff --git a/test/test.py b/tests/test_config.py similarity index 63% rename from test/test.py rename to tests/test_config.py index 2304c13..114c28c 100644 --- a/test/test.py +++ b/tests/test_config.py @@ -1,13 +1,13 @@ #!/usr/bin/env python3 # coding:utf8 -import sys import os +import sys import unittest from unittest.mock import patch -from code_counter.core.args import CodeCounterArgs + from code_counter.conf.config import Config -from code_counter.__main__ import main +from code_counter.core.args import CodeCounterArgs test_path = os.path.abspath('.') bin_path = os.path.dirname(os.path.join(os.pardir, '..')) @@ -15,85 +15,13 @@ app_path = os.path.join(lib_path, '__main__.py') -class CodeCounterTest(unittest.TestCase): +class CodeCounterConfigTest(unittest.TestCase): def setUp(self): - self.default_suffix = ["c", "cc", "clj", "cpp", "cs", "cu", "cuh", "dart", "go", "h", + self.default_suffix = {"c", "cc", "clj", "cpp", "cs", "cu", "cuh", "dart", "go", "h", "hpp", "java", "jl", "js", "kt", "lisp", "lua", "pde", "m", "php", - "py", "R", "rb", "rs", "rust", "sh", "scala", "swift", "ts", "vb"] - self.default_comment = ["#", "//", "/*", "*", "*/", ":", ";", '""""'] - self.default_ignore = ["out", "venv", ".git", ".idea", "build", "target", "node_modules", ".vscode", "dist"] - - def test_print_help(self): - options = ('python', app_path, '--help') - sys.argv[1:] = options[2:] - try: - CodeCounterArgs() - except SystemExit: - pass - - def test_print_search_help(self): - options = ('python', app_path, 'search', '--help') - sys.argv[1:] = options[2:] - try: - CodeCounterArgs() - except SystemExit: - pass - - def test_print_config_help(self): - options = ('python', app_path, 'config', '--help') - sys.argv[1:] = options[2:] - try: - CodeCounterArgs() - except SystemExit: - pass - - def test_search_args(self): - options = ['python', app_path, - 'search', - '../code_counter/', - '-v', - '-g', - '-o=output.txt', - '--suffix=py,java,cpp', - '--comment=//,#,/*', - '--ignore=.vscode,.idea'] - sys.argv[1:] = options[2:] - args = CodeCounterArgs() - self.assertFalse(args.has_config_args(), '"config" is in the "args"') - self.assertTrue(args.has_search_args(), '"search" is not in the "args"') - search_args = args.search() - self.assertEqual(search_args.input_path, ['../code_counter/'], "search path parsed error.") - self.assertTrue(search_args.verbose, '-v,--verbose flag parsed error.') - self.assertTrue(search_args.graph, '-g,--graph flag parsed error.') - self.assertEqual(search_args.output_path, 'output.txt', "output path parsed error.") - self.assertEqual(search_args.suffix, ['py', 'java', 'cpp'], "suffix flag and values parsed error.") - self.assertEqual(search_args.comment, ['//', '#', '/*'], "comment flag and values parsed error.") - self.assertEqual(search_args.ignore, ['.vscode', '.idea'], "ignore flag and values parsed error.") - - def test_config_args(self): - options = ['python', app_path, - 'config', - '--list', - '--suffix-add=lisp', - '--suffix-reset=clj', - '--comment-add=//', - '--comment-reset=;', - '--ignore-add=.idea', - '--ignore-reset=target', - '--restore'] - sys.argv[1:] = options[2:] - args = CodeCounterArgs() - self.assertTrue(args.has_config_args(), '"config" is not in the "args"') - self.assertFalse(args.has_search_args(), '"search" is in the "args"') - config_args = args.config() - self.assertTrue(config_args.show_list, '--list flag parsed error.') - self.assertEqual(config_args.suffix_add, ['lisp'], "suffix_add flag and values parsed error.") - self.assertEqual(config_args.suffix_reset, ['clj'], "suffix_reset flag and values parsed error.") - self.assertEqual(config_args.comment_add, ['//'], "comment_add flag and values parsed error.") - self.assertEqual(config_args.comment_reset, [';'], "comment_reset flag and values parsed error.") - self.assertEqual(config_args.ignore_add, ['.idea'], "ignore_add flag and values parsed error.") - self.assertEqual(config_args.ignore_reset, ['target'], "ignore_reset flag and values parsed error.") - self.assertTrue(config_args.restore, '--restore flag parsed error.') + "py", "R", "rb", "rs", "rust", "sh", "scala", "swift", "ts", "vb"} + self.default_comment = {"#", "//", "/*", "*", "*/", ":", ";", '""""'} + self.default_ignore = {"out", "venv", ".git", ".idea", "build", "target", "node_modules", ".vscode", "dist"} @patch('builtins.input') def test_Config_restore(self, mock_input): @@ -132,9 +60,9 @@ def test_Config_reset1(self, mock_input): self.assertTrue(args.has_config_args()) config.invoke(args.config()) - suffix = ['java', 'cpp', 'go', 'js', 'py'] - comment = ['//', '#', '/**'] - ignore = ['target', 'build', 'node_modules', '__pycache__'] + suffix = {'java', 'cpp', 'go', 'js', 'py'} + comment = {'//', '#', '/**'} + ignore = {'target', 'build', 'node_modules', '__pycache__'} self.assertEqual(config.suffix, suffix) self.assertEqual(config.comment, comment) @@ -160,9 +88,9 @@ def test_Config_reset2(self, mock_input): self.assertTrue(args.has_config_args()) config.invoke(args.config()) - suffix = ['java', 'cpp', 'go', 'js', 'py'] - comment = ['//', '#', '/**'] - ignore = ['target', 'build', 'node_modules', '__pycache__'] + suffix = {'java', 'cpp', 'go', 'js', 'py'} + comment = {'//', '#', '/**'} + ignore = {'target', 'build', 'node_modules', '__pycache__'} self.assertEqual(config.suffix, self.default_suffix) self.assertEqual(config.comment, comment) @@ -188,9 +116,9 @@ def test_Config_reset3(self, mock_input): self.assertTrue(args.has_config_args()) config.invoke(args.config()) - suffix = ['java', 'cpp', 'go', 'js', 'py'] - comment = ['//', '#', '/**'] - ignore = ['target', 'build', 'node_modules', '__pycache__'] + suffix = {'java', 'cpp', 'go', 'js', 'py'} + comment = {'//', '#', '/**'} + ignore = {'target', 'build', 'node_modules', '__pycache__'} self.assertEqual(config.suffix, suffix) self.assertEqual(config.comment, self.default_comment) @@ -216,9 +144,9 @@ def test_Config_reset4(self, mock_input): self.assertTrue(args.has_config_args()) config.invoke(args.config()) - suffix = ['java', 'cpp', 'go', 'js', 'py'] - comment = ['//', '#', '/**'] - ignore = ['target', 'build', 'node_modules', '__pycache__'] + suffix = {'java', 'cpp', 'go', 'js', 'py'} + comment = {'//', '#', '/**'} + ignore = {'target', 'build', 'node_modules', '__pycache__'} self.assertEqual(config.suffix, suffix) self.assertEqual(config.comment, comment) @@ -226,6 +154,38 @@ def test_Config_reset4(self, mock_input): config.restore() + @patch('builtins.input') + def test_Config_reset_duplicate(self, mock_input): + mock_input.side_effect = ['y', 'y', 'y', 'y', 'y'] + + config = Config() + config.restore() + + options = ['python', app_path, + 'config', + '--suffix-reset=py,py,py,py', + '--comment-reset=#,#,#', + '--ignore-reset=__pycache__,__pycache__'] + sys.argv[1:] = options[2:] + + args = CodeCounterArgs() + self.assertTrue(args.has_config_args()) + config.invoke(args.config()) + + suffix = {'py'} + comment = {'#'} + ignore = {'__pycache__'} + + self.assertEqual(len(config.suffix), 1) + self.assertEqual(len(config.comment), 1) + self.assertEqual(len(config.ignore), 1) + + self.assertEqual(config.suffix, suffix) + self.assertEqual(config.comment, comment) + self.assertEqual(config.ignore, ignore) + + config.restore() + @patch('builtins.input') def test_Config_add1(self, mock_input): mock_input.side_effect = ['y', 'y', 'y', 'y', 'y'] @@ -338,15 +298,30 @@ def test_Config_add4(self, mock_input): config.restore() - def test_search_case1(self): + @patch('builtins.input') + def test_Config_del(self, mock_input): + mock_input.side_effect = ['y', 'y', 'y', 'y', 'y'] + + config = Config() + config.restore() + options = ['python', app_path, - 'search', - '..', - '-v', - '-o=output.txt'] + 'config', + '--suffix-del=py', + '--comment-del=#', + '--ignore-del=venv'] sys.argv[1:] = options[2:] - main() - output_path = os.path.join(test_path, 'output.txt') - self.assertTrue(os.path.exists(output_path)) - os.remove(output_path) + args = CodeCounterArgs() + self.assertTrue(args.has_config_args()) + config.invoke(args.config()) + + suffix = 'py' + comment = '#' + ignore = 'venv' + + self.assertFalse(suffix in config.suffix) + self.assertFalse(comment in config.comment) + self.assertFalse(ignore in config.ignore) + + config.restore() diff --git a/tests/test_search.py b/tests/test_search.py new file mode 100644 index 0000000..d655d1c --- /dev/null +++ b/tests/test_search.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python3 +# coding:utf8 + +import sys +import os +import unittest +from code_counter.__main__ import main + +test_path = os.path.abspath('.') +bin_path = os.path.dirname(os.path.join(os.pardir, '..')) +lib_path = os.path.abspath(os.path.join(bin_path, 'code_counter')) +app_path = os.path.join(lib_path, '__main__.py') + + +class CodeCounterSearchTest(unittest.TestCase): + def test_search_case1(self): + options = ['python', app_path, + 'search', + '..', + '-v', + '-o=output.txt'] + sys.argv[1:] = options[2:] + main() + + output_path = os.path.join(test_path, 'output.txt') + self.assertTrue(os.path.exists(output_path)) + os.remove(output_path)