@@ -67,6 +67,27 @@ func newTestDirWithFiles(t *testing.T) string {
6767 return directoryPath
6868}
6969
70+ // chdirWithCleanup changes the current working directory to the named directory,
71+ // and then restore the original working directory at the end of the test.
72+ //
73+ // TODO: Once we are on 1.24 we can replace this with t.Chdir()
74+ func chdirWithCleanup (t * testing.T , dir string ) {
75+ olddir , err := os .Getwd ()
76+ if err != nil {
77+ t .Fatalf ("chdir: %v" , err )
78+ }
79+ if err := os .Chdir (dir ); err != nil {
80+ t .Fatalf ("chdir %s: %v" , dir , err )
81+ }
82+
83+ t .Cleanup (func () {
84+ if err := os .Chdir (olddir ); err != nil {
85+ t .Errorf ("chdir to original working directory %s: %v" , olddir , err )
86+ os .Exit (1 )
87+ }
88+ })
89+ }
90+
7091func writePipeChar (buf * bytes.Buffer , index int ) {
7192 if index == 0 {
7293 return
@@ -306,10 +327,80 @@ func TestExecute_NotOverwrite(t *testing.T) {
306327 expectRepresentation (t , directoryPath , `
307328.
308329├─output.md "**file content A**"
309- ` )
330+ ` )
310331 })
311332}
312333
334+ func TestExecute_DuplicateFiles (t * testing.T ) {
335+ directoryPath := newTestDir (t )
336+ defer os .RemoveAll (directoryPath )
337+
338+ chdirWithCleanup (t , directoryPath )
339+
340+ inputFolderA := filepath .Join (directoryPath , "input" , "a" )
341+ inputFolderB := filepath .Join (directoryPath , "input" , "b" )
342+ inputFolderC := filepath .Join (directoryPath , "input" , "nested" , "c" )
343+
344+ err := os .MkdirAll (inputFolderA , os .ModePerm )
345+ if err != nil {
346+ t .Fatal (err )
347+ }
348+ err = os .MkdirAll (inputFolderB , os .ModePerm )
349+ if err != nil {
350+ t .Fatal (err )
351+ }
352+ err = os .MkdirAll (inputFolderC , os .ModePerm )
353+ if err != nil {
354+ t .Fatal (err )
355+ }
356+
357+ err = os .WriteFile (filepath .Join (inputFolderA , "random.html" ), []byte ("file a" ), 0644 )
358+ if err != nil {
359+ t .Fatal (err )
360+ }
361+ err = os .WriteFile (filepath .Join (inputFolderB , "random.html" ), []byte ("file b" ), 0644 )
362+ if err != nil {
363+ t .Fatal (err )
364+ }
365+ err = os .WriteFile (filepath .Join (inputFolderC , "random.html" ), []byte ("file c" ), 0644 )
366+ if err != nil {
367+ t .Fatal (err )
368+ }
369+
370+ // - - - - - - - - - //
371+ args := []string {"html2markdown" , "--input" , filepath .Join ("." , "input" , "**" , "*" ), "--output" , filepath .Join ("." , "output" ) + "/" }
372+
373+ stdin := & FakeFile {mode : modeTerminal }
374+ stdout := & FakeFile {mode : modePipe }
375+ stderr := & FakeFile {mode : modePipe }
376+
377+ Run (stdin , stdout , stderr , args , testRelease )
378+
379+ if len (stderr .Bytes ()) != 0 {
380+ t .Fatalf ("expected no stderr content but got %q" , stderr .String ())
381+ }
382+ if len (stdout .Bytes ()) != 0 {
383+ t .Fatalf ("expected no stdout content" )
384+ }
385+ // - - - - - - - - - //
386+
387+ expectRepresentation (t , directoryPath , `
388+ .
389+ ├─input
390+ │ ├─a
391+ │ │ ├─random.html "file a"
392+ │ ├─b
393+ │ │ ├─random.html "file b"
394+ │ ├─nested
395+ │ │ ├─c
396+ │ │ │ ├─random.html "file c"
397+ ├─output
398+ │ ├─random.689330a60f.md "file b"
399+ │ ├─random.f679b6e0c2.md "file c"
400+ │ ├─random.md "file a"
401+ ` )
402+ }
403+
313404// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //
314405
315406func TestExecute_FilePattern (t * testing.T ) {
@@ -355,7 +446,27 @@ func TestExecute_FilePattern(t *testing.T) {
355446├─output
356447│ ├─websites
357448│ │ ├─the_cool_website.md "**file content A**"
449+ ` ,
450+ },
451+ {
452+ desc : "output to a specific extension" ,
453+ assembleArgs : func (dir string ) []string {
454+ input := filepath .Join (dir , "input" , "website_a.html" )
455+ output := filepath .Join (dir , "output" , "websites" , "the_cool_website.txt" )
358456
457+ return []string {"html2markdown" , "--input" , input , "--output" , output }
458+ },
459+ expected : `
460+ .
461+ ├─input
462+ │ ├─nested
463+ │ │ ├─website_c.html "<i>file content C</i>"
464+ │ ├─random.txt "other random file"
465+ │ ├─website_a.html "<strong>file content A</strong>"
466+ │ ├─website_b.html "<strong>file content B</strong>"
467+ ├─output
468+ │ ├─websites
469+ │ │ ├─the_cool_website.txt "**file content A**"
359470 ` ,
360471 },
361472 {
@@ -379,6 +490,72 @@ func TestExecute_FilePattern(t *testing.T) {
379490
380491 ` ,
381492 },
493+
494+ // - - - - - - - - - - - - relative path - - - - - - - - - - - - //
495+ {
496+ desc : "relative path: output to a specific file" ,
497+ assembleArgs : func (_ string ) []string {
498+ input := filepath .Join ("." , "input" , "website_a.html" )
499+ output := filepath .Join ("." , "output" , "websites" , "the_cool_website.md" )
500+
501+ return []string {"html2markdown" , "--input" , input , "--output" , output }
502+ },
503+ expected : `
504+ .
505+ ├─input
506+ │ ├─nested
507+ │ │ ├─website_c.html "<i>file content C</i>"
508+ │ ├─random.txt "other random file"
509+ │ ├─website_a.html "<strong>file content A</strong>"
510+ │ ├─website_b.html "<strong>file content B</strong>"
511+ ├─output
512+ │ ├─websites
513+ │ │ ├─the_cool_website.md "**file content A**"
514+ ` ,
515+ },
516+ {
517+ desc : "relative path: direct website html files" ,
518+ assembleArgs : func (_ string ) []string {
519+ input := filepath .Join ("." , "input" , "website*.html" )
520+ output := filepath .Join ("." , "output" ) + string (os .PathSeparator )
521+
522+ return []string {"html2markdown" , "--input" , input , "--output" , output }
523+ },
524+ expected : `
525+ .
526+ ├─input
527+ │ ├─nested
528+ │ │ ├─website_c.html "<i>file content C</i>"
529+ │ ├─random.txt "other random file"
530+ │ ├─website_a.html "<strong>file content A</strong>"
531+ │ ├─website_b.html "<strong>file content B</strong>"
532+ ├─output
533+ │ ├─website_a.md "**file content A**"
534+ │ ├─website_b.md "**file content B**"
535+ ` ,
536+ },
537+ {
538+ desc : "relative path: output to current directory" ,
539+ assembleArgs : func (_ string ) []string {
540+ input := filepath .Join ("." , "input" , "website*.html" )
541+ output := "." + string (os .PathSeparator )
542+
543+ return []string {"html2markdown" , "--input" , input , "--output" , output }
544+ },
545+ expected : `
546+ .
547+ ├─input
548+ │ ├─nested
549+ │ │ ├─website_c.html "<i>file content C</i>"
550+ │ ├─random.txt "other random file"
551+ │ ├─website_a.html "<strong>file content A</strong>"
552+ │ ├─website_b.html "<strong>file content B</strong>"
553+ ├─output
554+ ├─website_a.md "**file content A**"
555+ ├─website_b.md "**file content B**"
556+ ` ,
557+ },
558+
382559 // - - - - - - - - - - - - pattern - - - - - - - - - - - - //
383560 {
384561 desc : "pattern matches single file" ,
@@ -522,6 +699,8 @@ func TestExecute_FilePattern(t *testing.T) {
522699 directoryPath := newTestDirWithFiles (t )
523700 defer os .RemoveAll (directoryPath )
524701
702+ chdirWithCleanup (t , directoryPath )
703+
525704 args := tC .assembleArgs (directoryPath )
526705 t .Logf ("args: %+v\n " , args )
527706
0 commit comments