|
1 | 1 | # -*- coding: utf-8 -*- |
2 | | - |
| 2 | +import io |
| 3 | +import os |
| 4 | +import sys |
3 | 5 | import unittest |
| 6 | +from contextlib import contextmanager |
| 7 | + |
4 | 8 | from slugify import slugify |
5 | 9 | from slugify import smart_truncate |
| 10 | +from slugify.__main__ import slugify_params, parse_args |
6 | 11 |
|
7 | 12 |
|
8 | 13 | class TestSlugification(unittest.TestCase): |
@@ -242,5 +247,110 @@ def test_smart_truncate_no_seperator(self): |
242 | 247 | self.assertEqual(r, txt) |
243 | 248 |
|
244 | 249 |
|
| 250 | +PY3 = sys.version_info.major == 3 |
| 251 | + |
| 252 | + |
| 253 | +@contextmanager |
| 254 | +def captured_stderr(): |
| 255 | + backup = sys.stderr |
| 256 | + sys.stderr = io.StringIO() if PY3 else io.BytesIO() |
| 257 | + try: |
| 258 | + yield sys.stderr |
| 259 | + finally: |
| 260 | + sys.stderr = backup |
| 261 | + |
| 262 | + |
| 263 | +@contextmanager |
| 264 | +def loaded_stdin(contents): |
| 265 | + backup = sys.stdin |
| 266 | + sys.stdin = io.StringIO(contents) if PY3 else io.BytesIO(contents) |
| 267 | + try: |
| 268 | + yield sys.stdin |
| 269 | + finally: |
| 270 | + sys.stdin = backup |
| 271 | + |
| 272 | + |
| 273 | +class TestCommandParams(unittest.TestCase): |
| 274 | + DEFAULTS = { |
| 275 | + 'entities': True, |
| 276 | + 'decimal': True, |
| 277 | + 'hexadecimal': True, |
| 278 | + 'max_length': 0, |
| 279 | + 'word_boundary': False, |
| 280 | + 'save_order': False, |
| 281 | + 'separator': '-', |
| 282 | + 'stopwords': None, |
| 283 | + 'lowercase': True, |
| 284 | + 'replacements': None |
| 285 | + } |
| 286 | + |
| 287 | + def get_params_from_cli(self, *argv): |
| 288 | + args = parse_args([None] + list(argv)) |
| 289 | + return slugify_params(args) |
| 290 | + |
| 291 | + def make_params(self, **values): |
| 292 | + return dict(self.DEFAULTS, **values) |
| 293 | + |
| 294 | + def assertParamsMatch(self, expected, checked): |
| 295 | + reduced_checked = {} |
| 296 | + for key in expected.keys(): |
| 297 | + reduced_checked[key] = checked[key] |
| 298 | + self.assertEqual(expected, reduced_checked) |
| 299 | + |
| 300 | + def test_defaults(self): |
| 301 | + params = self.get_params_from_cli() |
| 302 | + self.assertParamsMatch(self.DEFAULTS, params) |
| 303 | + |
| 304 | + def test_negative_flags(self): |
| 305 | + params = self.get_params_from_cli('--no-entities', '--no-decimal', '--no-hexadecimal', '--no-lowercase') |
| 306 | + expected = self.make_params(entities=False, decimal=False, hexadecimal=False, lowercase=False) |
| 307 | + self.assertFalse(expected['lowercase']) |
| 308 | + self.assertFalse(expected['word_boundary']) |
| 309 | + self.assertParamsMatch(expected, params) |
| 310 | + |
| 311 | + def test_affirmative_flags(self): |
| 312 | + params = self.get_params_from_cli('--word-boundary', '--save-order') |
| 313 | + expected = self.make_params(word_boundary=True, save_order=True) |
| 314 | + self.assertParamsMatch(expected, params) |
| 315 | + |
| 316 | + def test_valued_arguments(self): |
| 317 | + params = self.get_params_from_cli('--stopwords', 'abba', 'beatles', '--max-length', '98', '--separator', '+') |
| 318 | + expected = self.make_params(stopwords=['abba', 'beatles'], max_length=98, separator='+') |
| 319 | + self.assertParamsMatch(expected, params) |
| 320 | + |
| 321 | + def test_replacements_right(self): |
| 322 | + params = self.get_params_from_cli('--replacements', 'A->B', 'C->D') |
| 323 | + expected = self.make_params(replacements=[['A', 'B'], ['C', 'D']]) |
| 324 | + self.assertParamsMatch(expected, params) |
| 325 | + |
| 326 | + def test_replacements_wrong(self): |
| 327 | + with self.assertRaises(SystemExit) as err, captured_stderr() as cse: |
| 328 | + self.get_params_from_cli('--replacements', 'A--B') |
| 329 | + self.assertEqual(err.exception.code, 2) |
| 330 | + self.assertIn("Replacements must be of the form: ORIGINAL->REPLACED", cse.getvalue()) |
| 331 | + |
| 332 | + def test_text_in_cli(self): |
| 333 | + params = self.get_params_from_cli('Cool Text') |
| 334 | + expected = self.make_params(text='Cool Text') |
| 335 | + self.assertParamsMatch(expected, params) |
| 336 | + |
| 337 | + def test_text_in_cli_multi(self): |
| 338 | + params = self.get_params_from_cli('Cool', 'Text') |
| 339 | + expected = self.make_params(text='Cool Text') |
| 340 | + self.assertParamsMatch(expected, params) |
| 341 | + |
| 342 | + def test_text_in_stdin(self): |
| 343 | + with loaded_stdin("Cool Stdin"): |
| 344 | + params = self.get_params_from_cli('--stdin') |
| 345 | + expected = self.make_params(text='Cool Stdin') |
| 346 | + self.assertParamsMatch(expected, params) |
| 347 | + |
| 348 | + def test_two_text_sources_fails(self): |
| 349 | + with self.assertRaises(SystemExit) as err, captured_stderr() as cse: |
| 350 | + self.get_params_from_cli('--stdin', 'Text') |
| 351 | + self.assertEqual(err.exception.code, 2) |
| 352 | + self.assertIn("Input strings and --stdin cannot work together", cse.getvalue()) |
| 353 | + |
| 354 | + |
245 | 355 | if __name__ == '__main__': |
246 | 356 | unittest.main() |
0 commit comments