diff --git a/dosage b/dosage index 25d7b88b0..a15a980a9 100755 --- a/dosage +++ b/dosage @@ -66,19 +66,19 @@ def setupOptions(): parser = ArgumentParser(**kwargs) parser.add_argument('-v', '--verbose', action='count', default=0, help='provides verbose output, use multiple times for more verbosity') parser.add_argument('-n', '--numstrips', action='store', type=int, default=0, help='traverse and retrieve the given number of comic strips; use --all to retrieve all comic strips') - parser.add_argument('-a', '--all', action='store_true', default=None, help='traverse and retrieve all comic strips') - parser.add_argument('-c', '--continue', action='store_true', dest='cont', default=None, help='traverse and retrieve comic strips until an existing one is found') + parser.add_argument('-a', '--all', action='store_true', help='traverse and retrieve all comic strips') + parser.add_argument('-c', '--continue', action='store_true', dest='cont', help='traverse and retrieve comic strips until an existing one is found') parser.add_argument('-b', '--basepath', action='store', default='Comics', help='set the path to create invidivual comic directories in, default is Comics', metavar='PATH') - parser.add_argument('--baseurl', action='store', default=None, help='the base URL of your comics directory (for RSS, HTML, etc.); this should correspond to --base-path', metavar='PATH') - parser.add_argument('-l', '--list', action='store_const', const=1, help='list available comic modules') - parser.add_argument('--singlelist', action='store_const', const=2, dest='list', help='list available comic modules in a single list') + parser.add_argument('--baseurl', action='store', help='the base URL of your comics directory (for RSS, HTML, etc.); this should correspond to --base-path', metavar='PATH') + parser.add_argument('-l', '--list', action='store_true', help='list available comic modules') + parser.add_argument('--singlelist', action='store_true', help='list available comic modules in a single list') parser.add_argument('--version', action='store_true', help='display the version number') parser.add_argument('-m', '--modulehelp', action='store_true', help='display help for comic modules') - parser.add_argument('-t', '--timestamps', action='store_true', default=False, help='print timestamps for all output at any info level') + parser.add_argument('-t', '--timestamps', action='store_true', help='print timestamps for all output at any info level') parser.add_argument('-o', '--output', action='store', choices=events.getHandlers(), help='output formatting for downloaded comics') - parser.add_argument('--adult', action='store_true', default=False, help='confirms that you are old enough to view adult content') - parser.add_argument('--multimatch', action='store_true', default=False, help='') - parser.add_argument('comic', nargs='+', help='comic module name (including case insensitive substrings)') + parser.add_argument('--adult', action='store_true', help='confirms that you are old enough to view adult content') + parser.add_argument('--multimatch', action='store_true', help='') + parser.add_argument('comic', nargs='*', help='comic module name (including case insensitive substrings)') try: import argcomplete argcomplete.autocomplete(parser) @@ -190,13 +190,19 @@ def run(options): if options.version: return displayVersion() if options.list: - return doList(options.list == 1) + return doList() + if options.singlelist: + return doList(columnList=False) + # after this a list of comic strips is needed + if not options.comic: + out.warn('No comics specified, bailing out!') + return 1 if options.modulehelp: return displayHelp(options.comic) return getComics(options) -def doList(columnList): +def doList(columnList=True): """List available comics.""" out.info('Available comic scrapers:') out.info('Comics marked with [A] require age confirmation with the --adult option.') diff --git a/tests/__init__.py b/tests/__init__.py index 5d3edfa55..3254d4a0b 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1 +1,37 @@ # -*- coding: iso-8859-1 -*- +# Copyright (C) 2013 Bastian Kleineidam +# +# 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 +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +import os +import subprocess + +basedir = os.path.dirname(__file__) +dosage_cmd = os.path.join(os.path.dirname(basedir), "dosage") + +def run (cmd, verbosity=0, **kwargs): + """Run command without error checking. + @return: command return code""" + if kwargs.get("shell"): + # for shell calls the command must be a string + cmd = " ".join(cmd) + return subprocess.call(cmd, **kwargs) + + +def run_checked (cmd, ret_ok=(0,), **kwargs): + """Run command and raise OSError on error.""" + retcode = run(cmd, **kwargs) + if retcode not in ret_ok: + msg = "Command `%s' returned non-zero exit status %d" % (cmd, retcode) + raise OSError(msg) + return retcode diff --git a/tests/test_dosage.py b/tests/test_dosage.py new file mode 100644 index 000000000..9ea6bde8b --- /dev/null +++ b/tests/test_dosage.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2013 Bastian Kleineidam +# +# 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 +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +import unittest +import sys +import shutil +import tempfile +from . import dosage_cmd, run_checked + + +def run_with_options(options): + """Run dosage with given options.""" + run_checked([sys.executable, dosage_cmd] + options) + + +class TestDosage (unittest.TestCase): + """Test the dosage commandline client.""" + + def setUp(self): + # create a temporary directory for images + self.tmpdir = tempfile.mkdtemp() + + def tearDown(self): + shutil.rmtree(self.tmpdir) + + def test_list_comics(self): + for option in ("-l", "--list", "--singlelist"): + run_with_options([option]) + + def test_version(self): + run_with_options(["--version"]) + + def test_help(self): + for option in ("-h", "--help"): + run_with_options([option]) + # module help + run_with_options(["-m", "calvinandhobbes"]) + + def test_error(self): + self.assertRaises(OSError, run_with_options, []) + self.assertRaises(OSError, run_with_options, ['--imadoofus']) + + def test_fetch(self): + run_with_options(["-n", "2", "-b", self.tmpdir, "-o", "html", "calvinandhobbes"]) + run_with_options(["--numstrips", "2", "--baseurl", "bla", "--basepath", self.tmpdir, "--output", "rss", "--adult", "sexyloser"]) +