mirror of
				https://github.com/Dadido3/go-typst.git
				synced 2025-11-04 05:09:35 +00:00 
			
		
		
		
	- Allow multiple errors and warnings - Remove ErrorWithPath, which is now replaced by Error - Simplify parsing, allow multiple errors - Add more tests for stderr parsing
		
			
				
	
	
		
			183 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			183 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright (c) 2024-2025 David Vogel
 | 
						|
//
 | 
						|
// This software is released under the MIT License.
 | 
						|
// https://opensource.org/licenses/MIT
 | 
						|
 | 
						|
package typst_test
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"errors"
 | 
						|
	"testing"
 | 
						|
 | 
						|
	"github.com/Dadido3/go-typst"
 | 
						|
	"github.com/google/go-cmp/cmp"
 | 
						|
)
 | 
						|
 | 
						|
func TestErrors0(t *testing.T) {
 | 
						|
	cli := typst.CLI{}
 | 
						|
 | 
						|
	r := bytes.NewBufferString(`This is a test!`)
 | 
						|
 | 
						|
	var w bytes.Buffer
 | 
						|
	if err := cli.Compile(r, &w, nil); err != nil {
 | 
						|
		t.Fatalf("Failed to compile document: %v", err)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestErrors1(t *testing.T) {
 | 
						|
	cli := typst.CLI{}
 | 
						|
 | 
						|
	r := bytes.NewBufferString(`This is a test!
 | 
						|
 | 
						|
#assert(1 < 1, message: "Test")`)
 | 
						|
 | 
						|
	var w bytes.Buffer
 | 
						|
	if err := cli.Compile(r, &w, nil); err == nil {
 | 
						|
		t.Fatalf("Expected error, but got nil")
 | 
						|
	} else {
 | 
						|
		var errTypst *typst.Error
 | 
						|
		if errors.As(err, &errTypst) {
 | 
						|
			if len(errTypst.Details) != 1 {
 | 
						|
				t.Fatalf("Expected error doesn't contain the expected number of detail entries. Got %v, want %v", len(errTypst.Details), 1)
 | 
						|
			}
 | 
						|
			details := errTypst.Details[0]
 | 
						|
			if details.Message != "error: assertion failed: Test" {
 | 
						|
				t.Errorf("Expected error with error message %q, got %q", "error: assertion failed: Test", details.Message)
 | 
						|
			}
 | 
						|
			/*if details.Path != "" {
 | 
						|
				t.Errorf("Expected error to point to path %q, got path %q", "", details.Path)
 | 
						|
			}*/
 | 
						|
			if details.Line != 3 {
 | 
						|
				t.Errorf("Expected error to point at line %d, got line %d", 3, details.Line)
 | 
						|
			}
 | 
						|
			if details.Column != 1 {
 | 
						|
				t.Errorf("Expected error to point at column %d, got column %d", 1, details.Column)
 | 
						|
			}
 | 
						|
		} else {
 | 
						|
			t.Errorf("Expected error type %T, got %T: %v", errTypst, err, err)
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestErrors2(t *testing.T) {
 | 
						|
	cli := typst.CLI{}
 | 
						|
 | 
						|
	opts := typst.CLIOptions{
 | 
						|
		Pages: "a",
 | 
						|
	}
 | 
						|
 | 
						|
	r := bytes.NewBufferString(`This is a test!`)
 | 
						|
 | 
						|
	var w bytes.Buffer
 | 
						|
	if err := cli.Compile(r, &w, &opts); err == nil {
 | 
						|
		t.Fatalf("Expected error, but got nil")
 | 
						|
	} else {
 | 
						|
		var errTypst *typst.Error
 | 
						|
		if errors.As(err, &errTypst) {
 | 
						|
			if len(errTypst.Details) != 1 {
 | 
						|
				t.Fatalf("Expected error doesn't contain the expected number of detail entries. Got %v, want %v", len(errTypst.Details), 1)
 | 
						|
			}
 | 
						|
			details := errTypst.Details[0]
 | 
						|
			// Don't check the specific error message, as that may change over time.
 | 
						|
			// The expected message should be similar to: error: invalid value 'a' for '--pages <PAGES>': not a valid page number.
 | 
						|
			if details.Message == "" {
 | 
						|
				t.Errorf("Expected error message, got %q", details.Message)
 | 
						|
			}
 | 
						|
		} else {
 | 
						|
			t.Errorf("Expected error type %T, got %T: %v", errTypst, err, err)
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestErrorParsing(t *testing.T) {
 | 
						|
	var tests = map[string]struct {
 | 
						|
		StdErr          string               // The original and raw stderr message.
 | 
						|
		ExpectedDetails []typst.ErrorDetails // Expected parsed result.
 | 
						|
	}{
 | 
						|
		"Typst 0.13.0 HTML warning + error": {
 | 
						|
			StdErr: "warning: html export is under active development and incomplete\n = hint: its behaviour may change at any time\n = hint: do not rely on this feature for production use cases\n = hint: see https://github.com/typst/typst/issues/5512 for more information\n\nerror: page configuration is not allowed inside of containers\n  ┌─ \\\\?\\C:\\Users\\David Vogel\\Desktop\\Synced\\Go\\Libraries\\go-typst\\<stdin>:1:1\n  │\n1 │ #set page(width: 100mm, height: auto, margin: 5mm)\n  │  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n",
 | 
						|
			ExpectedDetails: []typst.ErrorDetails{
 | 
						|
				{
 | 
						|
					Message: "warning: html export is under active development and incomplete\n = hint: its behaviour may change at any time\n = hint: do not rely on this feature for production use cases\n = hint: see https://github.com/typst/typst/issues/5512 for more information",
 | 
						|
				},
 | 
						|
				{
 | 
						|
					Message: "error: page configuration is not allowed inside of containers",
 | 
						|
					Path:    "\\\\?\\C:\\Users\\David Vogel\\Desktop\\Synced\\Go\\Libraries\\go-typst\\<stdin>",
 | 
						|
					Line:    1,
 | 
						|
					Column:  1,
 | 
						|
				},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		"Typst 0.13.0 error with path": {
 | 
						|
			StdErr: "error: expected expression\n   ┌─ \\\\?\\C:\\Users\\David Vogel\\Desktop\\Synced\\Go\\Libraries\\go-typst\\<stdin>:12:34\n   │\n12 │ - Test coverage of most features.#\n   │                                   ^\n\n",
 | 
						|
			ExpectedDetails: []typst.ErrorDetails{
 | 
						|
				{
 | 
						|
					Message: "error: expected expression",
 | 
						|
					Path:    "\\\\?\\C:\\Users\\David Vogel\\Desktop\\Synced\\Go\\Libraries\\go-typst\\<stdin>",
 | 
						|
					Line:    12,
 | 
						|
					Column:  34,
 | 
						|
				},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		"Typst 0.13.0 multiple errors with paths": {
 | 
						|
			StdErr: "error: expected expression\n   ┌─ \\\\?\\C:\\Users\\David Vogel\\Desktop\\Synced\\Go\\Libraries\\go-typst\\<stdin>:11:53\n   │\n11 │ - Uses stdio; No temporary files need to be created.#\n   │                                                      ^\n\nerror: expected expression\n   ┌─ \\\\?\\C:\\Users\\David Vogel\\Desktop\\Synced\\Go\\Libraries\\go-typst\\<stdin>:12:34\n   │\n12 │ - Test coverage of most features.#\n   │                                   ^\n\n",
 | 
						|
			ExpectedDetails: []typst.ErrorDetails{
 | 
						|
				{
 | 
						|
					Message: "error: expected expression",
 | 
						|
					Path:    "\\\\?\\C:\\Users\\David Vogel\\Desktop\\Synced\\Go\\Libraries\\go-typst\\<stdin>",
 | 
						|
					Line:    11,
 | 
						|
					Column:  53,
 | 
						|
				},
 | 
						|
				{
 | 
						|
					Message: "error: expected expression",
 | 
						|
					Path:    "\\\\?\\C:\\Users\\David Vogel\\Desktop\\Synced\\Go\\Libraries\\go-typst\\<stdin>",
 | 
						|
					Line:    12,
 | 
						|
					Column:  34,
 | 
						|
				},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		"Typst 0.13.0 stacked errors with paths": {
 | 
						|
			StdErr: "error: expected expression\n  ┌─ \\\\?\\C:\\Users\\David Vogel\\Desktop\\Synced\\Go\\Libraries\\go-typst\\test.typ:1:4\n  │\n1 │ hey#\n  │     ^\n\nhelp: error occurred while importing this module\n   ┌─ \\\\?\\C:\\Users\\David Vogel\\Desktop\\Synced\\Go\\Libraries\\go-typst\\<stdin>:14:9\n   │\n14 │ #include \"test.typ\"\n   │          ^^^^^^^^^^\n\n",
 | 
						|
			ExpectedDetails: []typst.ErrorDetails{
 | 
						|
				{
 | 
						|
					Message: "error: expected expression",
 | 
						|
					Path:    "\\\\?\\C:\\Users\\David Vogel\\Desktop\\Synced\\Go\\Libraries\\go-typst\\test.typ",
 | 
						|
					Line:    1,
 | 
						|
					Column:  4,
 | 
						|
				},
 | 
						|
				{
 | 
						|
					Message: "help: error occurred while importing this module",
 | 
						|
					Path:    "\\\\?\\C:\\Users\\David Vogel\\Desktop\\Synced\\Go\\Libraries\\go-typst\\<stdin>",
 | 
						|
					Line:    14,
 | 
						|
					Column:  9,
 | 
						|
				},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		"Typst 0.13.0 error without path": {
 | 
						|
			StdErr: "error: invalid value 'a' for '--pages <PAGES>': not a valid page number\n\nFor more information, try '--help'.\n",
 | 
						|
			ExpectedDetails: []typst.ErrorDetails{
 | 
						|
				{
 | 
						|
					Message: "error: invalid value 'a' for '--pages <PAGES>': not a valid page number",
 | 
						|
				},
 | 
						|
			},
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	for name, tt := range tests {
 | 
						|
		t.Run(name, func(t *testing.T) {
 | 
						|
			result := typst.ParseStderr(tt.StdErr, nil)
 | 
						|
 | 
						|
			var typstError *typst.Error
 | 
						|
			if errors.As(result, &typstError) {
 | 
						|
				if !cmp.Equal(typstError.Details, tt.ExpectedDetails) {
 | 
						|
					t.Errorf("Parsed details don't match expected details: %s", cmp.Diff(tt.ExpectedDetails, typstError.Details))
 | 
						|
				}
 | 
						|
			} else {
 | 
						|
				t.Errorf("Parsed error is not of type %T", typstError)
 | 
						|
			}
 | 
						|
 | 
						|
		})
 | 
						|
	}
 | 
						|
}
 |