go-hep.org/x/hep@v0.38.1/groot/internal/rtests/rtests_test.go (about)

     1  // Copyright ©2019 The go-hep Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package rtests_test
     6  
     7  import (
     8  	"bytes"
     9  	"errors"
    10  	"fmt"
    11  	"testing"
    12  
    13  	"go-hep.org/x/hep/groot/internal/rtests"
    14  )
    15  
    16  func TestRunCxxROOTWithoutROOT(t *testing.T) {
    17  	hasROOT := rtests.HasROOT
    18  	rtests.HasROOT = false
    19  	defer func() {
    20  		rtests.HasROOT = hasROOT
    21  	}()
    22  
    23  	out, err := rtests.RunCxxROOT("hello", []byte(`void hello(const char* name) { std::cout << name << std::endl; }`), "hello")
    24  	if !errors.Is(err, rtests.ErrNoROOT) {
    25  		t.Fatalf("unexpected error: got=%v, want=%v\noutput:\n%s", err, rtests.ErrNoROOT, out)
    26  	}
    27  }
    28  
    29  func TestRunCxxROOTInvalidMacro(t *testing.T) {
    30  	out, err := rtests.RunCxxROOT("hello", []byte(`void hello(const char* name) { std::cout << nameXXX << std::endl; }`), "hello")
    31  	if err == nil {
    32  		t.Fatalf("expected C++ ROOT macro to fail")
    33  	}
    34  	if !rtests.HasROOT {
    35  		return
    36  	}
    37  	var dst rtests.ROOTError
    38  	if !errors.As(err, &dst) {
    39  		t.Fatalf("unexpected error-type (%T): got=%+v", err, err)
    40  	}
    41  	const suffix = `hello.C:1:45: error: use of undeclared identifier 'nameXXX'
    42  void hello(const char* name) { std::cout << nameXXX << std::endl; }
    43                                              ^
    44  `
    45  	if !bytes.HasSuffix(out, []byte(suffix)) {
    46  		t.Fatalf("unexpected error: got=%+v\noutput:\n%s", err, out)
    47  	}
    48  }
    49  
    50  func TestRunCxxROOT(t *testing.T) {
    51  	out, err := rtests.RunCxxROOT("hello", []byte(`void hello(const char* name, int d) { std::cout << name << "-" << d << std::endl; }`), "hello", 42)
    52  	if err != nil {
    53  		switch {
    54  		case rtests.HasROOT:
    55  			t.Fatalf("expected C++ ROOT macro to run correctly: %+v\noutput:\n%s", err, out)
    56  		default:
    57  			if !errors.Is(err, rtests.ErrNoROOT) {
    58  				t.Fatalf("unexpected error: got=%v, want=%v", err, rtests.ErrNoROOT)
    59  			}
    60  		}
    61  		return
    62  	}
    63  
    64  	// ROOT macros start with printing out:
    65  	// \nProcessing /tmp/groot-rtests-516158679/hello.C(\"hello\")...\n
    66  	if i := bytes.Index(out, []byte("...\n")); i > 0 {
    67  		out = out[i+len([]byte("...\n")):]
    68  	}
    69  	if got, want := string(out), string("hello-42\n"); got != want {
    70  		t.Fatalf("invalid ROOT macro result. got=%q, want=%q", got, want)
    71  	}
    72  }
    73  
    74  func TestROOTError(t *testing.T) {
    75  	var err error = rtests.ROOTError{
    76  		Err:  fmt.Errorf("err1"),
    77  		Cmd:  "root.exe",
    78  		Args: []string{"arg1", "arg2"},
    79  		Out:  []byte("some output"),
    80  	}
    81  
    82  	const want = `could not run 'root.exe arg1 arg2': err1
    83  output:
    84  some output`
    85  	if got, want := err.Error(), want; got != want {
    86  		t.Fatalf("invalid error:\ngot= %q\nwant=%q", got, want)
    87  	}
    88  
    89  	err = fmt.Errorf("wrap: %w", err)
    90  	if got, want := err.Error(), "wrap: "+want; got != want {
    91  		t.Fatalf("invalid error:\ngot= %q\nwant=%q", got, want)
    92  	}
    93  
    94  	err = errors.Unwrap(errors.Unwrap(err))
    95  	if got, want := err.Error(), "err1"; got != want {
    96  		t.Fatalf("invalid error:\ngot= %q\nwant=%q", got, want)
    97  	}
    98  }
    99  
   100  func TestGenROOTDictCodeWithoutROOT(t *testing.T) {
   101  	hasROOT := rtests.HasROOT
   102  	rtests.HasROOT = false
   103  	defer func() {
   104  		rtests.HasROOT = hasROOT
   105  	}()
   106  
   107  	out, err := rtests.GenROOTDictCode("struct Event {};", "")
   108  	if !errors.Is(err, rtests.ErrNoROOT) {
   109  		t.Fatalf("unexpected error: got=%v, want=%v\noutput:\n%s", err, rtests.ErrNoROOT, out)
   110  	}
   111  }
   112  
   113  func TestGenROOTDictCodeWithROOT(t *testing.T) {
   114  	if !rtests.HasROOT {
   115  		t.Skipf("ROOT isn't installed")
   116  	}
   117  
   118  	const event = `struct Event {
   119  	double D;
   120  };
   121  `
   122  
   123  	const link = `
   124  #ifdef __CINT__
   125  
   126  #pragma link off all globals;
   127  #pragma link off all classes;
   128  #pragma link off all functions;
   129  
   130  #pragma link C++ class Event+;
   131  
   132  #endif
   133  `
   134  	out, err := rtests.GenROOTDictCode(event, link)
   135  	if err != nil {
   136  		t.Fatalf("could not generate ROOT dict: %+v", err)
   137  	}
   138  
   139  	const want = `// Do NOT change. Changes will be lost next time file is generated`
   140  	if !bytes.HasPrefix(out, []byte(want)) {
   141  		t.Fatalf("unexpected ROOT dict content:\n%s", out)
   142  	}
   143  }