4747from .utils import get_dir , get_manifest_path
4848
4949
50+ def create_fake_quarto_rendered_output (target_dir , name ):
51+ with open (join (target_dir , f"{ name } .html" ), "w" ) as fp :
52+ fp .write (f"<html><body>fake rendering: { name } </body></html>\n " )
53+ files_dir = join (target_dir , f"{ name } _files" )
54+ os .mkdir (files_dir )
55+ with open (join (files_dir , "resource.js" ), "w" ) as fp :
56+ fp .write ("// fake resource.js\n " )
57+
58+
5059class TestBundle (TestCase ):
5160 @staticmethod
5261 def python_version ():
5362 return "." .join (map (str , sys .version_info [:3 ]))
5463
64+ def setUp (self ):
65+ self .maxDiff = None
66+
5567 def test_to_bytes (self ):
5668 self .assertEqual (to_bytes (b"abc123" ), b"abc123" )
5769 self .assertEqual (to_bytes (b"\xc3 \xa5 bc123" ), b"\xc3 \xa5 bc123" )
@@ -64,7 +76,6 @@ def test_to_bytes(self):
6476 self .assertEqual (to_bytes ("åbc123" ), b"\xc3 \xa5 bc123" )
6577
6678 def test_make_notebook_source_bundle1 (self ):
67- self .maxDiff = 5000
6879 directory = get_dir ("pip1" )
6980 nb_path = join (directory , "dummy.ipynb" )
7081
@@ -135,7 +146,6 @@ def test_make_notebook_source_bundle1(self):
135146 )
136147
137148 def test_make_notebook_source_bundle2 (self ):
138- self .maxDiff = 5000
139149 directory = get_dir ("pip2" )
140150 nb_path = join (directory , "dummy.ipynb" )
141151
@@ -221,24 +231,27 @@ def test_make_notebook_source_bundle2(self):
221231 },
222232 )
223233
224- def test_make_quarto_source_bundle_from_project (self ):
234+ def test_make_quarto_source_bundle_from_simple_project (self ):
225235 temp_proj = tempfile .mkdtemp ()
226236
227- # add project files
228- fp = open (join (temp_proj , "myquarto.qmd" ), "w" )
229- fp .write ("---\n " )
230- fp .write ("title: myquarto\n " )
231- fp .write ("jupyter: python3\n " )
232- fp .write ("---\n \n " )
233- fp .write ("```{python}\n " )
234- fp .write ("1 + 1\n " )
235- fp .write ("```\n " )
236- fp .close ()
237-
238- fp = open (join (temp_proj , "_quarto.yml" ), "w" )
239- fp .write ("project:\n " )
240- fp .write (' title: "myquarto"\n ' )
241- fp .write ("editor: visual\n " )
237+ # This is a simple project; it has a _quarto.yml and one Markdown file.
238+ with open (join (temp_proj , "_quarto.yml" ), "w" ) as fp :
239+ fp .write ("project:\n " )
240+ fp .write (' title: "project with one rendered file"\n ' )
241+
242+ with open (join (temp_proj , "myquarto.qmd" ), "w" ) as fp :
243+ fp .write ("---\n " )
244+ fp .write ("title: myquarto\n " )
245+ fp .write ("jupyter: python3\n " )
246+ fp .write ("---\n \n " )
247+ fp .write ("```{python}\n " )
248+ fp .write ("1 + 1\n " )
249+ fp .write ("```\n " )
250+
251+ # Create some files that should not make it into the manifest; they
252+ # should be automatically ignored because myquarto.qmd is a project
253+ # input file.
254+ create_fake_quarto_rendered_output (temp_proj , "myquarto" )
242255
243256 environment = detect_environment (temp_proj )
244257
@@ -299,6 +312,122 @@ def test_make_quarto_source_bundle_from_project(self):
299312 },
300313 )
301314
315+ def test_make_quarto_source_bundle_from_complex_project (self ):
316+ temp_proj = tempfile .mkdtemp ()
317+
318+ # This is a complex project; it has a _quarto.yml and multiple
319+ # Markdown files.
320+ with open (join (temp_proj , "_quarto.yml" ), "w" ) as fp :
321+ fp .write ("project:\n " )
322+ fp .write (" type: website\n " )
323+ fp .write (' title: "myquarto"\n ' )
324+
325+ with open (join (temp_proj , "index.qmd" ), "w" ) as fp :
326+ fp .write ("---\n " )
327+ fp .write ("title: home\n " )
328+ fp .write ("jupyter: python3\n " )
329+ fp .write ("---\n \n " )
330+ fp .write ("```{python}\n " )
331+ fp .write ("1 + 1\n " )
332+ fp .write ("```\n " )
333+
334+ with open (join (temp_proj , "about.qmd" ), "w" ) as fp :
335+ fp .write ("---\n " )
336+ fp .write ("title: about\n " )
337+ fp .write ("---\n \n " )
338+ fp .write ("math, math, math.\n " )
339+
340+ # Create some files that should not make it into the manifest; they
341+ # should be automatically ignored because myquarto.qmd is a project
342+ # input file.
343+ #
344+ # Create files both in the current directory and beneath _site (the
345+ # implicit output-dir for websites).
346+ create_fake_quarto_rendered_output (temp_proj , "index" )
347+ create_fake_quarto_rendered_output (temp_proj , "about" )
348+ site_dir = join (temp_proj , "_site" )
349+ os .mkdir (site_dir )
350+ create_fake_quarto_rendered_output (site_dir , "index" )
351+ create_fake_quarto_rendered_output (site_dir , "about" )
352+
353+ environment = detect_environment (temp_proj )
354+
355+ # mock the result of running of `quarto inspect <project_dir>`
356+ inspect = {
357+ "quarto" : {"version" : "1.3.433" },
358+ "dir" : temp_proj ,
359+ "engines" : [
360+ "markdown" ,
361+ "jupyter" ,
362+ ],
363+ "config" : {
364+ "project" : {
365+ "type" : "website" ,
366+ "output-dir" : "_site" ,
367+ },
368+ },
369+ "files" : {
370+ "input" : [
371+ temp_proj + "/index.qmd" ,
372+ temp_proj + "/about.qmd" ,
373+ ],
374+ "resources" : [],
375+ "config" : [temp_proj + "/_quarto.yml" ],
376+ "configResources" : [],
377+ },
378+ }
379+
380+ with make_quarto_source_bundle (
381+ temp_proj , inspect , AppModes .STATIC_QUARTO , environment , [], [], None
382+ ) as bundle , tarfile .open (mode = "r:gz" , fileobj = bundle ) as tar :
383+ names = sorted (tar .getnames ())
384+ self .assertEqual (
385+ names ,
386+ [
387+ "_quarto.yml" ,
388+ "about.qmd" ,
389+ "index.qmd" ,
390+ "manifest.json" ,
391+ "requirements.txt" ,
392+ ],
393+ )
394+
395+ reqs = tar .extractfile ("requirements.txt" ).read ()
396+ self .assertIsNotNone (reqs )
397+
398+ manifest = json .loads (tar .extractfile ("manifest.json" ).read ().decode ("utf-8" ))
399+
400+ # noinspection SpellCheckingInspection
401+ self .assertEqual (
402+ manifest ,
403+ {
404+ "version" : 1 ,
405+ "locale" : mock .ANY ,
406+ "metadata" : {
407+ "appmode" : "quarto-static" ,
408+ "content_category" : "site" ,
409+ },
410+ "python" : {
411+ "version" : self .python_version (),
412+ "package_manager" : {
413+ "name" : "pip" ,
414+ "package_file" : "requirements.txt" ,
415+ "version" : mock .ANY ,
416+ },
417+ },
418+ "quarto" : {
419+ "engines" : ["markdown" , "jupyter" ],
420+ "version" : mock .ANY ,
421+ },
422+ "files" : {
423+ "_quarto.yml" : {"checksum" : mock .ANY },
424+ "index.qmd" : {"checksum" : mock .ANY },
425+ "about.qmd" : {"checksum" : mock .ANY },
426+ "requirements.txt" : {"checksum" : mock .ANY },
427+ },
428+ },
429+ )
430+
302431 def test_make_quarto_source_bundle_from_project_with_requirements (self ):
303432 temp_proj = tempfile .mkdtemp ()
304433
@@ -385,14 +514,19 @@ def test_make_quarto_source_bundle_from_project_with_requirements(self):
385514 def test_make_quarto_source_bundle_from_file (self ):
386515 temp_proj = tempfile .mkdtemp ()
387516
517+ filename = join (temp_proj , "myquarto.qmd" )
388518 # add single qmd file with markdown engine
389- fp = open (join (temp_proj , "myquarto.qmd" ), "w" )
390- fp .write ("---\n " )
391- fp .write ("title: myquarto\n " )
392- fp .write ("engine: markdown\n " )
393- fp .write ("---\n \n " )
394- fp .write ("### This is a test\n " )
395- fp .close ()
519+ with open (filename , "w" ) as fp :
520+ fp .write ("---\n " )
521+ fp .write ("title: myquarto\n " )
522+ fp .write ("engine: markdown\n " )
523+ fp .write ("---\n \n " )
524+ fp .write ("### This is a test\n " )
525+
526+ # Create some files that should not make it into the manifest; they
527+ # should be automatically ignored because myquarto.qmd is the input
528+ # file.
529+ create_fake_quarto_rendered_output (temp_proj , "myquarto" )
396530
397531 # mock the result of running of `quarto inspect <qmd_file>`
398532 inspect = {
@@ -401,7 +535,7 @@ def test_make_quarto_source_bundle_from_file(self):
401535 }
402536
403537 with make_quarto_source_bundle (
404- temp_proj , inspect , AppModes .STATIC_QUARTO , None , [], [], None
538+ filename , inspect , AppModes .STATIC_QUARTO , None , [], [], None
405539 ) as bundle , tarfile .open (mode = "r:gz" , fileobj = bundle ) as tar :
406540 names = sorted (tar .getnames ())
407541 self .assertEqual (
@@ -469,7 +603,6 @@ def test_html_bundle2(self):
469603 self .do_test_html_bundle (get_dir ("pip2" ))
470604
471605 def do_test_html_bundle (self , directory ):
472- self .maxDiff = 5000
473606 nb_path = join (directory , "dummy.ipynb" )
474607
475608 bundle = make_notebook_html_bundle (
@@ -521,7 +654,6 @@ def test_keep_manifest_specified_file(self):
521654 self .assertFalse (keep_manifest_specified_file (".Rproj.user/bogus.file" ))
522655
523656 def test_manifest_bundle (self ):
524- self .maxDiff = 5000
525657 # noinspection SpellCheckingInspection
526658 manifest_path = join (dirname (__file__ ), "testdata" , "R" , "shinyapp" , "manifest.json" )
527659
0 commit comments