github.com/jingcheng-WU/gonum@v0.9.1-0.20210323123734-f1a2a11a8f7b/graph/formats/dot/internal/parser/parser_test.go (about)

     1  // This file is dual licensed under CC0 and The Gonum License.
     2  //
     3  // Copyright ©2017 The Gonum Authors. All rights reserved.
     4  // Use of this source code is governed by a BSD-style
     5  // license that can be found in the LICENSE file.
     6  //
     7  // Copyright ©2017 Robin Eklind.
     8  // This file is made available under a Creative Commons CC0 1.0
     9  // Universal Public Domain Dedication.
    10  
    11  package parser_test
    12  
    13  import (
    14  	"archive/zip"
    15  	"bytes"
    16  	"io/ioutil"
    17  	"os"
    18  	"testing"
    19  
    20  	"github.com/jingcheng-WU/gonum/graph/formats/dot"
    21  )
    22  
    23  func TestParseFile(t *testing.T) {
    24  	golden := []struct {
    25  		in  string
    26  		out string
    27  	}{
    28  		{in: "../testdata/empty.dot"},
    29  		{in: "../testdata/graph.dot"},
    30  		{in: "../testdata/digraph.dot"},
    31  		{in: "../testdata/strict.dot"},
    32  		{in: "../testdata/multi.dot"},
    33  		{in: "../testdata/named_graph.dot"},
    34  		{in: "../testdata/node_stmt.dot"},
    35  		{in: "../testdata/edge_stmt.dot"},
    36  		{in: "../testdata/attr_stmt.dot"},
    37  		{in: "../testdata/attr.dot"},
    38  		{
    39  			in:  "../testdata/subgraph.dot",
    40  			out: "../testdata/subgraph.golden",
    41  		},
    42  		{
    43  			in:  "../testdata/semi.dot",
    44  			out: "../testdata/semi.golden",
    45  		},
    46  		{
    47  			in:  "../testdata/empty_attr.dot",
    48  			out: "../testdata/empty_attr.golden",
    49  		},
    50  		{
    51  			in:  "../testdata/attr_lists.dot",
    52  			out: "../testdata/attr_lists.golden",
    53  		},
    54  		{
    55  			in:  "../testdata/attr_sep.dot",
    56  			out: "../testdata/attr_sep.golden",
    57  		},
    58  		{in: "../testdata/subgraph_vertex.dot"},
    59  		{in: "../testdata/port.dot"},
    60  		{in: "../testdata/quoted_id.dot"},
    61  		{
    62  			in:  "../testdata/backslash_newline_id.dot",
    63  			out: "../testdata/backslash_newline_id.golden",
    64  		},
    65  	}
    66  	for _, g := range golden {
    67  		file, err := dot.ParseFile(g.in)
    68  		if err != nil {
    69  			t.Errorf("%q: unable to parse file; %v", g.in, err)
    70  			continue
    71  		}
    72  		// If no output path is specified, the input is already golden.
    73  		out := g.in
    74  		if len(g.out) > 0 {
    75  			out = g.out
    76  		}
    77  		buf, err := ioutil.ReadFile(out)
    78  		if err != nil {
    79  			t.Errorf("%q: unable to read file; %v", g.in, err)
    80  			continue
    81  		}
    82  		got := file.String()
    83  		// Remove trailing newline.
    84  		want := string(bytes.TrimSpace(buf))
    85  		if got != want {
    86  			t.Errorf("%q: graph mismatch; expected `%s`, got `%s`", g.in, want, got)
    87  		}
    88  	}
    89  }
    90  
    91  func TestParseFuzz(t *testing.T) {
    92  	r, err := zip.OpenReader("../../fuzz/corpus.zip")
    93  	if err != nil {
    94  		if os.IsNotExist(err) {
    95  			t.Skip("no corpus")
    96  		}
    97  		t.Fatalf("failed to open corpus: %v", err)
    98  	}
    99  	defer r.Close()
   100  
   101  	for _, f := range r.File {
   102  		rc, err := f.Open()
   103  		if err != nil {
   104  			t.Fatalf("failed to open %q: %v", f.Name, err)
   105  		}
   106  		func() {
   107  			defer func() {
   108  				p := recover()
   109  				if p != nil {
   110  					t.Errorf("unexpected panic parsing %q: %v", f.Name, p)
   111  				}
   112  			}()
   113  
   114  			_, err = dot.Parse(rc)
   115  			if err != nil {
   116  				t.Errorf("unexpected error parsing %q: %v", f.Name, err)
   117  			}
   118  		}()
   119  		rc.Close()
   120  	}
   121  }
   122  
   123  func TestParseError(t *testing.T) {
   124  	golden := []struct {
   125  		path string
   126  		want string
   127  	}{
   128  		{
   129  			path: "../testdata/error.dot",
   130  			want: `Error in S30: INVALID(0,~), Pos(offset=13, line=2, column=7), expected one of: { } graphx ; -- -> node edge [ = subgraph : id `,
   131  		},
   132  	}
   133  	for _, g := range golden {
   134  		_, err := dot.ParseFile(g.path)
   135  		if err == nil {
   136  			t.Errorf("%q: expected error, got nil", g.path)
   137  			continue
   138  		}
   139  		got := err.Error()
   140  		if got != g.want {
   141  			t.Errorf("%q: error mismatch; expected `%v`, got `%v`", g.path, g.want, got)
   142  			continue
   143  		}
   144  	}
   145  }