github.com/ipld/go-ipld-prime@v0.21.0/traversal/patch/patch_test.go (about)

     1  package patch
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"os"
     7  	"strings"
     8  	"testing"
     9  
    10  	qt "github.com/frankban/quicktest"
    11  	"github.com/warpfork/go-testmark"
    12  
    13  	"github.com/ipld/go-ipld-prime"
    14  	"github.com/ipld/go-ipld-prime/codec"
    15  	"github.com/ipld/go-ipld-prime/codec/dagjson"
    16  )
    17  
    18  func TestSpecFixtures(t *testing.T) {
    19  	dir := "../../.ipld/specs/patch/fixtures/"
    20  	testOneSpecFixtureFile(t, dir+"fixtures-1.md")
    21  }
    22  
    23  func testOneSpecFixtureFile(t *testing.T, filename string) {
    24  	doc, err := testmark.ReadFile(filename)
    25  	if os.IsNotExist(err) {
    26  		t.Skipf("not running spec suite: %s (did you clone the submodule with the data?)", err)
    27  	}
    28  	if err != nil {
    29  		t.Fatalf("spec file parse failed?!: %s", err)
    30  	}
    31  
    32  	// Data hunk in this spec file are in "directories" of a test scenario each.
    33  	doc.BuildDirIndex()
    34  
    35  	for _, dir := range doc.DirEnt.ChildrenList {
    36  		t.Run(dir.Name, func(t *testing.T) {
    37  			// Grab all the data hunks.
    38  			//  Each "directory" contains three piece of data:
    39  			//   - `initial` -- this is the "block".  It's arbitrary example data.  They're all in json (or dag-json) format, for simplicity.
    40  			//   - `patch` -- this is a list of patch ops.  Again, as json.
    41  			//   - `result` -- this is the expected result object.  Again, as json.
    42  			initialBlob := dir.Children["initial"].Hunk.Body
    43  			patchBlob := dir.Children["patch"].Hunk.Body
    44  			resultBlob := dir.Children["result"].Hunk.Body
    45  
    46  			// Parse everything.
    47  			initial, err := ipld.Decode(initialBlob, dagjson.Decode)
    48  			if err != nil {
    49  				t.Fatalf("failed to parse fixture data: %s", err)
    50  			}
    51  			ops, err := ParseBytes(patchBlob, dagjson.Decode)
    52  			if err != nil {
    53  				t.Fatalf("failed to parse fixture patch: %s", err)
    54  			}
    55  			// We don't actually keep the decoded result object.  We're just gonna serialize the result and textually diff that instead.
    56  			_, err = ipld.Decode(resultBlob, dagjson.Decode)
    57  			if err != nil {
    58  				t.Fatalf("failed to parse fixture data: %s", err)
    59  			}
    60  
    61  			// Do the thing!
    62  			actualResult, err := Eval(initial, ops)
    63  			if strings.HasSuffix(dir.Name, "-fail") {
    64  				if err == nil {
    65  					t.Fatalf("patch was expected to fail")
    66  				} else {
    67  					return
    68  				}
    69  			} else {
    70  				if err != nil {
    71  					t.Fatalf("patch did not apply: %s", err)
    72  				}
    73  			}
    74  
    75  			// Serialize (and pretty print) result, so that we can diff it.
    76  			actualResultBlob, err := ipld.Encode(actualResult, dagjson.EncodeOptions{
    77  				EncodeLinks: true,
    78  				EncodeBytes: true,
    79  				MapSortMode: codec.MapSortMode_None,
    80  			}.Encode)
    81  			if err != nil {
    82  				t.Errorf("failed to reserialize result: %s", err)
    83  			}
    84  			var actualResultBlobPretty bytes.Buffer
    85  			json.Indent(&actualResultBlobPretty, actualResultBlob, "", "\t")
    86  
    87  			// Diff!
    88  			qt.Assert(t, actualResultBlobPretty.String()+"\n", qt.Equals, string(resultBlob))
    89  		})
    90  	}
    91  }