| 1 | package export_test |
| 2 | |
| 3 | import ( |
| 4 | "os" |
| 5 | "testing" |
| 6 | |
| 7 | "github.com/carlosframework/docs/internal/export" |
| 8 | ) |
| 9 | |
| 10 | // TestWriteSamplePDF is a development aid, not a gate: with |
| 11 | // $DOCS_PDF_SAMPLE set to a path, it writes a PDF there so a person |
| 12 | // (or a browser drive) can open it in a real reader. Skipped |
| 13 | // otherwise, so it costs the gate nothing. |
| 14 | // |
| 15 | // It exists because everything else in this package checks the PDF |
| 16 | // with this package's own reader (pdfread_test.go), and a writer and a |
| 17 | // reader that agree with each other can still both be wrong about the |
| 18 | // specification. Opening the output in something nobody here wrote is |
| 19 | // the only check that closes that gap. |
| 20 | func TestWriteSamplePDF(t *testing.T) { |
| 21 | path := os.Getenv("DOCS_PDF_SAMPLE") |
| 22 | if path == "" { |
| 23 | t.Skip("set DOCS_PDF_SAMPLE=<path> to write a sample PDF") |
| 24 | } |
| 25 | |
| 26 | js := `{"type":"doc","content":[ |
| 27 | {"type":"heading","attrs":{"level":2},"content":[{"type":"text","text":"What the exporter can set"}]}, |
| 28 | {"type":"paragraph","content":[ |
| 29 | {"type":"text","text":"Ordinary prose, with "}, |
| 30 | {"type":"text","text":"bold","marks":[{"type":"strong"}]}, |
| 31 | {"type":"text","text":", "}, |
| 32 | {"type":"text","text":"italic","marks":[{"type":"em"}]}, |
| 33 | {"type":"text","text":", and "}, |
| 34 | {"type":"text","text":"code()","marks":[{"type":"code"}]}, |
| 35 | {"type":"text","text":" in it. Accents (café, naïve, Zoë) and punctuation the web is full of — em dashes, “curly quotes” — come through the same path."} |
| 36 | ]}, |
| 37 | {"type":"paragraph","content":[ |
| 38 | {"type":"text","text":"This sentence is set in the serif face","marks":[{"type":"font_serif"}]}, |
| 39 | {"type":"text","text":", this one is larger","marks":[{"type":"size_lg"}]}, |
| 40 | {"type":"text","text":", and this one is small.","marks":[{"type":"size_sm"}]} |
| 41 | ]}, |
| 42 | {"type":"heading","attrs":{"level":3},"content":[{"type":"text","text":"Lists"}]}, |
| 43 | {"type":"bullet_list","content":[ |
| 44 | {"type":"list_item","content":[{"type":"paragraph","content":[{"type":"text","text":"A bullet, long enough that it has to wrap onto a second line so the hanging indent is visible and can be judged rather than assumed."}]}]}, |
| 45 | {"type":"list_item","content":[ |
| 46 | {"type":"paragraph","content":[{"type":"text","text":"A bullet with a list inside it"}]}, |
| 47 | {"type":"ordered_list","content":[ |
| 48 | {"type":"list_item","content":[{"type":"paragraph","content":[{"type":"text","text":"First"}]}]}, |
| 49 | {"type":"list_item","content":[{"type":"paragraph","content":[{"type":"text","text":"Second"}]}]} |
| 50 | ]} |
| 51 | ]} |
| 52 | ]}, |
| 53 | {"type":"blockquote","content":[ |
| 54 | {"type":"paragraph","content":[{"type":"text","text":"A quotation, set italic and grey with a rule down its left edge, long enough to wrap so the rule can be seen to run the whole height of it rather than only beside the first line."}]} |
| 55 | ]}, |
| 56 | {"type":"paragraph","content":[{"type":"text","text":"A closing paragraph."}]} |
| 57 | ]}` |
| 58 | |
| 59 | doc, err := export.Parse("Sample document", js) |
| 60 | if err != nil { |
| 61 | t.Fatal(err) |
| 62 | } |
| 63 | data, report, err := export.PDF(doc) |
| 64 | if err != nil { |
| 65 | t.Fatal(err) |
| 66 | } |
| 67 | if err := os.WriteFile(path, data, 0o644); err != nil { |
| 68 | t.Fatal(err) |
| 69 | } |
| 70 | t.Logf("wrote %s (%d bytes), %s", path, len(data), report) |
| 71 | } |
| 72 | |