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"])
+