11import unittest
22
33from io import BytesIO
4+ from typing import List
45
56from curlylint .tests .utils import BlackRunner
67
78from curlylint .cli import main
89
910
10- class TestParser (unittest .TestCase ):
11- def test_no_flag (self ):
11+ class TestCLI (unittest .TestCase ):
12+ """
13+ Heavily inspired by Black’s CLI tests.
14+ See https://github.com/psf/black/blob/master/tests/test_black.py.
15+ """
16+
17+ def invoke_curlylint (
18+ self , exit_code : int , args : List [str ], input : str = None
19+ ):
1220 runner = BlackRunner ()
13- result = runner .invoke (main , [])
21+ result = runner .invoke (
22+ main , args , input = BytesIO (input .encode ("utf8" )) if input else None
23+ )
24+ self .assertEqual (
25+ result .exit_code ,
26+ exit_code ,
27+ msg = (
28+ f"Failed with args: { args } \n "
29+ f"stdout: { runner .stdout_bytes .decode ()!r} \n "
30+ f"stderr: { runner .stderr_bytes .decode ()!r} \n "
31+ f"exception: { result .exception } "
32+ ),
33+ )
34+ return runner
35+
36+ def test_no_flag (self ):
37+ runner = self .invoke_curlylint (0 , [])
1438 self .assertEqual (runner .stdout_bytes .decode (), "" )
1539 self .assertEqual (
1640 runner .stderr_bytes .decode (), "No Path provided. Nothing to do 😴\n "
1741 )
18- self .assertEqual (result .exit_code , 0 )
1942
2043 def test_stdin (self ):
21- runner = BlackRunner ()
22- result = runner .invoke (
23- main , ["-" ], input = BytesIO ("<p>Hello, World!</p>" .encode ("utf8" )),
24- )
44+ runner = self .invoke_curlylint (0 , ["-" ], input = "<p>Hello, World!</p>" )
2545 self .assertEqual (runner .stdout_bytes .decode (), "" )
2646 self .assertEqual (runner .stderr_bytes .decode (), "All done! ✨ 🍰 ✨\n \n " )
27- self .assertEqual (result .exit_code , 0 )
2847
2948 def test_stdin_verbose (self ):
30- runner = BlackRunner ()
31- result = runner .invoke (
32- main ,
33- ["--verbose" , "-" ],
34- input = BytesIO ("<p>Hello, World!</p>" .encode ("utf8" )),
49+ runner = self .invoke_curlylint (
50+ 0 , ["--verbose" , "-" ], input = "<p>Hello, World!</p>"
3551 )
3652 self .assertEqual (runner .stdout_bytes .decode (), "" )
3753 self .assertIn (
@@ -45,14 +61,40 @@ def test_stdin_verbose(self):
4561""" ,
4662 runner .stderr_bytes .decode (),
4763 )
48- self .assertEqual (result .exit_code , 0 )
4964
5065 def test_flag_help (self ):
51- runner = BlackRunner ()
52- result = runner .invoke (main , ["--help" ])
66+ runner = self .invoke_curlylint (0 , ["--help" ])
5367 self .assertIn (
5468 "Prototype linter for Jinja and Django templates" ,
5569 runner .stdout_bytes .decode (),
5670 )
5771 self .assertEqual (runner .stderr_bytes .decode (), "" )
58- self .assertEqual (result .exit_code , 0 )
72+
73+ def test_template_tags_validation_fail_no_nesting (self ):
74+ runner = self .invoke_curlylint (
75+ 2 ,
76+ ["--template-tags" , '["cache", "endcache"]' , "-" ],
77+ input = "<p>Hello, World!</p>" ,
78+ )
79+ self .assertIn (
80+ "Error: Invalid value for '--template-tags': expected a list of lists of tags as JSON, got '[\" cache\" , \" endcache\" ]'" ,
81+ runner .stderr_bytes .decode (),
82+ )
83+
84+ def test_template_tags_cli_configured (self ):
85+ self .invoke_curlylint (
86+ 0 ,
87+ ["--template-tags" , '[["of", "elseof", "endof"]]' , "-" ],
88+ input = "<p>{% of a %}c{% elseof %}test{% endof %}</p>" ,
89+ )
90+
91+ def test_template_tags_cli_unconfigured_fails (self ):
92+ runner = self .invoke_curlylint (
93+ 1 ,
94+ ["--template-tags" , "[]" , "-" ],
95+ input = "<p>{% of a %}c{% elseof %}test{% endof %}</p>" ,
96+ )
97+ self .assertIn (
98+ "Parse error: expected one of 'autoescape', 'block', 'blocktrans', 'comment', 'filter', 'for', 'if', 'ifchanged', 'ifequal', 'ifnotequal', 'not an intermediate Jinja tag name', 'spaceless', 'verbatim', 'with' at 0:17\t parse_error" ,
99+ runner .stdout_bytes .decode (),
100+ )
0 commit comments