...

Source file src/github.com/launchdarkly/go-jsonstream/v3/jreader/token_reader_test.go

Documentation: github.com/launchdarkly/go-jsonstream/v3/jreader

     1  package jreader
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"io"
     7  	"testing"
     8  
     9  	"github.com/launchdarkly/go-jsonstream/v3/internal/commontest"
    10  )
    11  
    12  // This uses the framework defined in ReaderTestSuite to exercise any TokenReader implementation
    13  // with a large number of valid and invalid JSON inputs.
    14  
    15  type tokenReaderTestContext struct {
    16  	input []byte
    17  	tr    *tokenReader
    18  }
    19  
    20  type tokenReaderValueTestFactory struct{}
    21  type tokenReaderErrorTestFactory struct{}
    22  
    23  type TokenReaderTestSuite struct {
    24  	Factory func([]byte) *tokenReader
    25  }
    26  
    27  func TestTokenReader(t *testing.T) {
    28  	s := TokenReaderTestSuite{
    29  		Factory: func(input []byte) *tokenReader {
    30  			tr := newTokenReader(input)
    31  			return &tr
    32  		},
    33  	}
    34  	s.Run(t)
    35  }
    36  
    37  func (s TokenReaderTestSuite) Run(t *testing.T) {
    38  	rs := commontest.ReaderTestSuite{
    39  		ContextFactory: func(input []byte) commontest.TestContext {
    40  			return &tokenReaderTestContext{
    41  				input: input,
    42  				tr:    s.Factory(input),
    43  			}
    44  		},
    45  		ValueTestFactory:     tokenReaderValueTestFactory{},
    46  		ReadErrorTestFactory: tokenReaderErrorTestFactory{},
    47  	}
    48  	rs.Run(t)
    49  }
    50  
    51  func (c tokenReaderTestContext) JSONData() []byte { return c.input }
    52  
    53  func (f tokenReaderValueTestFactory) EOF() commontest.Action {
    54  	return func(c commontest.TestContext) error {
    55  		return commontest.AssertTrue(c.(*tokenReaderTestContext).tr.EOF(), "unexpected data after end")
    56  	}
    57  }
    58  
    59  func (f tokenReaderValueTestFactory) Null() commontest.Action {
    60  	return func(c commontest.TestContext) error {
    61  		tr := c.(*tokenReaderTestContext).tr
    62  		ok, err := tr.Null()
    63  		if err != nil {
    64  			return err
    65  		}
    66  		if !ok {
    67  			any, _ := tr.Any()
    68  			return TypeError{Expected: NullValue, Actual: any.Kind}
    69  		}
    70  		return nil
    71  	}
    72  }
    73  
    74  func (f tokenReaderValueTestFactory) Variants(value commontest.AnyValue) []commontest.ValueVariant {
    75  	// TokenReader does not need to use ValueVariants because it does not have any ambiguity
    76  	// about what type a value is being read as.
    77  	return nil
    78  }
    79  
    80  func (f tokenReaderValueTestFactory) Value(value commontest.AnyValue, variant commontest.ValueVariant) commontest.Action {
    81  	return func(c commontest.TestContext) error {
    82  		ctx := c.(*tokenReaderTestContext)
    83  		tr := ctx.tr
    84  
    85  		switch value.Kind {
    86  		case commontest.NullValue:
    87  			return f.Null()(c)
    88  
    89  		case commontest.BoolValue:
    90  			gotVal, err := tr.Bool()
    91  			return commontest.AssertNoErrors(err, commontest.AssertEqual(value.Bool, gotVal))
    92  
    93  		case commontest.NumberValue:
    94  			gotVal, err := tr.Number()
    95  			return commontest.AssertNoErrors(err, commontest.AssertEqual(value.Number, gotVal))
    96  
    97  		case commontest.StringValue:
    98  			gotVal, err := tr.String()
    99  			return commontest.AssertNoErrors(err, commontest.AssertEqual(value.String, gotVal))
   100  
   101  		case commontest.ArrayValue:
   102  			gotDelim, err := tr.Delimiter('[')
   103  			if err != nil {
   104  				return err
   105  			}
   106  			if !gotDelim {
   107  				return errors.New("expected start of array")
   108  			}
   109  
   110  			first := true
   111  			for _, e := range value.Array {
   112  				if !first {
   113  					isEnd, err := tr.EndDelimiterOrComma(']')
   114  					if err := commontest.AssertNoErrors(err, commontest.AssertTrue(!isEnd, "array ended too soon")); err != nil {
   115  						return err
   116  					}
   117  				}
   118  				first = false
   119  				if err := e(c); err != nil {
   120  					return err
   121  				}
   122  			}
   123  
   124  			isEnd, err := tr.EndDelimiterOrComma(']')
   125  			return commontest.AssertNoErrors(err, commontest.AssertTrue(isEnd, "expected end of array"))
   126  
   127  		case commontest.ObjectValue:
   128  			gotDelim, err := tr.Delimiter('{')
   129  			if err != nil {
   130  				return err
   131  			}
   132  			if !gotDelim {
   133  				return errors.New("expected start of object")
   134  			}
   135  
   136  			first := true
   137  			for _, p := range value.Object {
   138  				if !first {
   139  					isEnd, err := tr.EndDelimiterOrComma('}')
   140  					if err := commontest.AssertNoErrors(err, commontest.AssertTrue(!isEnd, "object ended too soon")); err != nil {
   141  						return err
   142  					}
   143  				}
   144  				first = false
   145  				name, err := tr.PropertyName()
   146  				if err := commontest.AssertNoErrors(err, commontest.AssertEqual(string(name), p.Name)); err != nil {
   147  					return err
   148  				}
   149  				if err := p.Action(c); err != nil {
   150  					return err
   151  				}
   152  			}
   153  
   154  			isEnd, err := tr.EndDelimiterOrComma('}')
   155  			return commontest.AssertNoErrors(err, commontest.AssertTrue(isEnd, "expected end of object"))
   156  		}
   157  		return nil
   158  	}
   159  }
   160  
   161  func (f tokenReaderErrorTestFactory) ExpectEOFError(err error) error {
   162  	return commontest.AssertEqual(io.EOF, err)
   163  }
   164  
   165  func (f tokenReaderErrorTestFactory) ExpectWrongTypeError(err error, expected commontest.ValueKind,
   166  	variant commontest.ValueVariant, actual commontest.ValueKind) error {
   167  	if te, ok := err.(TypeError); ok {
   168  		if te.Actual == valueKindFromTestValueKind(actual) && te.Expected == valueKindFromTestValueKind(expected) {
   169  			return nil
   170  		}
   171  	}
   172  	return fmt.Errorf("expected TypeError{Expected: %s, Actual: %s}, got %T %+v",
   173  		valueKindFromTestValueKind(expected), valueKindFromTestValueKind(actual), err, err)
   174  }
   175  
   176  func (f tokenReaderErrorTestFactory) ExpectSyntaxError(err error) error {
   177  	if _, ok := err.(SyntaxError); ok {
   178  		return nil
   179  	}
   180  	return fmt.Errorf("expected SyntaxError, got %T %+v", err, err)
   181  }
   182  
   183  func valueKindFromTestValueKind(kind commontest.ValueKind) ValueKind {
   184  	switch kind {
   185  	case commontest.NullValue:
   186  		return NullValue
   187  	case commontest.BoolValue:
   188  		return BoolValue
   189  	case commontest.NumberValue:
   190  		return NumberValue
   191  	case commontest.StringValue:
   192  		return StringValue
   193  	case commontest.ArrayValue:
   194  		return ArrayValue
   195  	case commontest.ObjectValue:
   196  		return ObjectValue
   197  	}
   198  	return NullValue
   199  }
   200  

View as plain text