1# Copyright (C) 2017, Red Hat, Inc. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); you may 4# not use this file except in compliance with the License. You may obtain 5# a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12# License for the specific language governing permissions and limitations 13# under the License. 14 15import argparse 16import textwrap 17 18from cliff import sphinxext 19from cliff.tests import base 20 21 22class TestSphinxExtension(base.TestBase): 23 24 def test_empty_help(self): 25 """Handle positional and optional actions without help messages.""" 26 parser = argparse.ArgumentParser(prog='hello-world', add_help=False) 27 parser.add_argument('name', action='store') 28 parser.add_argument('--language', dest='lang') 29 30 output = '\n'.join(sphinxext._format_parser(parser)) 31 self.assertEqual(textwrap.dedent(""" 32 .. program:: hello-world 33 .. code-block:: shell 34 35 hello-world [--language LANG] name 36 37 .. option:: --language <LANG> 38 39 .. option:: name 40 """).lstrip(), output) 41 42 def test_nonempty_help(self): 43 """Handle positional and optional actions with help messages.""" 44 parser = argparse.ArgumentParser(prog='hello-world', add_help=False) 45 parser.add_argument('name', help='user name') 46 parser.add_argument('--language', dest='lang', 47 help='greeting language') 48 49 output = '\n'.join(sphinxext._format_parser(parser)) 50 self.assertEqual(textwrap.dedent(""" 51 .. program:: hello-world 52 .. code-block:: shell 53 54 hello-world [--language LANG] name 55 56 .. option:: --language <LANG> 57 58 greeting language 59 60 .. option:: name 61 62 user name 63 """).lstrip(), output) 64 65 def test_description_epilog(self): 66 """Handle a parser description, epilog.""" 67 parser = argparse.ArgumentParser(prog='hello-world', add_help=False, 68 description='A "Hello, World" app.', 69 epilog='What am I doing down here?') 70 parser.add_argument('name', action='store') 71 parser.add_argument('--language', dest='lang') 72 73 output = '\n'.join(sphinxext._format_parser(parser)) 74 self.assertEqual(textwrap.dedent(""" 75 A "Hello, World" app. 76 77 .. program:: hello-world 78 .. code-block:: shell 79 80 hello-world [--language LANG] name 81 82 .. option:: --language <LANG> 83 84 .. option:: name 85 86 What am I doing down here? 87 """).lstrip(), output) 88 89 def test_flag(self): 90 """Handle a boolean argparse action.""" 91 parser = argparse.ArgumentParser(prog='hello-world', add_help=False) 92 parser.add_argument('name', help='user name') 93 parser.add_argument('--translate', action='store_true', 94 help='translate to local language') 95 96 output = '\n'.join(sphinxext._format_parser(parser)) 97 self.assertEqual(textwrap.dedent(""" 98 .. program:: hello-world 99 .. code-block:: shell 100 101 hello-world [--translate] name 102 103 .. option:: --translate 104 105 translate to local language 106 107 .. option:: name 108 109 user name 110 """).lstrip(), output) 111 112 def test_supressed(self): 113 """Handle a supressed action.""" 114 parser = argparse.ArgumentParser(prog='hello-world', add_help=False) 115 parser.add_argument('name', help='user name') 116 parser.add_argument('--variable', help=argparse.SUPPRESS) 117 118 output = '\n'.join(sphinxext._format_parser(parser)) 119 self.assertEqual(textwrap.dedent(""" 120 .. program:: hello-world 121 .. code-block:: shell 122 123 hello-world name 124 125 126 .. option:: name 127 128 user name 129 """).lstrip(), output) 130 131 def test_metavar(self): 132 """Handle an option with a metavar.""" 133 parser = argparse.ArgumentParser(prog='hello-world', add_help=False) 134 parser.add_argument('names', metavar='<NAME>', nargs='+', 135 help='a user name') 136 137 output = '\n'.join(sphinxext._format_parser(parser)) 138 self.assertEqual(textwrap.dedent(""" 139 .. program:: hello-world 140 .. code-block:: shell 141 142 hello-world <NAME> [<NAME> ...] 143 144 .. option:: NAME 145 146 a user name 147 """).lstrip(), output) 148 149 def test_multiple_opts(self): 150 """Correctly output multiple opts on separate lines.""" 151 parser = argparse.ArgumentParser(prog='hello-world', add_help=False) 152 parser.add_argument('name', help='user name') 153 parser.add_argument('--language', dest='lang', 154 help='greeting language') 155 parser.add_argument('--translate', action='store_true', 156 help='translate to local language') 157 parser.add_argument('--write-to-var-log-something-or-other', 158 action='store_true', 159 help='a long opt to force wrapping') 160 parser.add_argument('--required-arg', dest='stuff', required=True, 161 help='a required argument') 162 style_group = parser.add_mutually_exclusive_group(required=True) 163 style_group.add_argument('--polite', action='store_true', 164 help='use a polite greeting') 165 style_group.add_argument('--profane', action='store_true', 166 help='use a less polite greeting') 167 168 output = '\n'.join(sphinxext._format_parser(parser)) 169 self.assertEqual(textwrap.dedent(""" 170 .. program:: hello-world 171 .. code-block:: shell 172 173 hello-world 174 [--language LANG] 175 [--translate] 176 [--write-to-var-log-something-or-other] 177 --required-arg STUFF 178 (--polite | --profane) 179 name 180 181 .. option:: --language <LANG> 182 183 greeting language 184 185 .. option:: --translate 186 187 translate to local language 188 189 .. option:: --write-to-var-log-something-or-other 190 191 a long opt to force wrapping 192 193 .. option:: --required-arg <STUFF> 194 195 a required argument 196 197 .. option:: --polite 198 199 use a polite greeting 200 201 .. option:: --profane 202 203 use a less polite greeting 204 205 .. option:: name 206 207 user name 208 """).lstrip(), output) 209 210 def test_various_option_names_with_hyphen(self): 211 """Handle options whose name and/or metavar contain hyphen(s)""" 212 parser = argparse.ArgumentParser(prog='hello-world', add_help=False) 213 parser.add_argument('--foo-bar', metavar='<foo-bar>', 214 help='foo bar', required=True) 215 parser.add_argument('--foo-bar-baz', metavar='<foo-bar-baz>', 216 help='foo bar baz', required=True) 217 parser.add_argument('--foo', metavar='<foo>', 218 help='foo', required=True) 219 parser.add_argument('--alpha', metavar='<A>', 220 help='alpha') 221 parser.add_argument('--alpha-beta', metavar='<A-B>', 222 help='alpha beta') 223 parser.add_argument('--alpha-beta-gamma', metavar='<A-B-C>', 224 help='alpha beta gamma') 225 226 output = '\n'.join(sphinxext._format_parser(parser)) 227 self.assertEqual(textwrap.dedent(""" 228 .. program:: hello-world 229 .. code-block:: shell 230 231 hello-world 232 --foo-bar <foo-bar> 233 --foo-bar-baz <foo-bar-baz> 234 --foo <foo> 235 [--alpha <A>] 236 [--alpha-beta <A-B>] 237 [--alpha-beta-gamma <A-B-C>] 238 239 .. option:: --foo-bar <foo-bar> 240 241 foo bar 242 243 .. option:: --foo-bar-baz <foo-bar-baz> 244 245 foo bar baz 246 247 .. option:: --foo <foo> 248 249 foo 250 251 .. option:: --alpha <A> 252 253 alpha 254 255 .. option:: --alpha-beta <A-B> 256 257 alpha beta 258 259 .. option:: --alpha-beta-gamma <A-B-C> 260 261 alpha beta gamma 262 """).lstrip(), output) 263