github.com/google/grumpy@v0.0.0-20171122020858-3ec87959189c/runtime/seq_test.go (about)

     1  // Copyright 2016 Google Inc. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package grumpy
    16  
    17  import (
    18  	"testing"
    19  )
    20  
    21  func TestSeqApply(t *testing.T) {
    22  	fun := wrapFuncForTest(func(f *Frame, seq *Object) (*Object, *BaseException) {
    23  		var got *Object
    24  		raised := seqApply(f, seq, func(elems []*Object, borrowed bool) *BaseException {
    25  			got = newTestTuple(NewTuple(elems...), GetBool(borrowed)).ToObject()
    26  			return nil
    27  		})
    28  		if raised != nil {
    29  			return nil, raised
    30  		}
    31  		return got, nil
    32  	})
    33  	cases := []invokeTestCase{
    34  		{args: wrapArgs(NewTuple()), want: newTestTuple(NewTuple(), true).ToObject()},
    35  		{args: wrapArgs(newTestList("foo", "bar")), want: newTestTuple(newTestTuple("foo", "bar"), true).ToObject()},
    36  		{args: wrapArgs(newTestDict("foo", None)), want: newTestTuple(newTestTuple("foo"), false).ToObject()},
    37  		{args: wrapArgs(42), wantExc: mustCreateException(TypeErrorType, "'int' object is not iterable")},
    38  	}
    39  	for _, cas := range cases {
    40  		if err := runInvokeTestCase(fun, &cas); err != "" {
    41  			t.Error(err)
    42  		}
    43  	}
    44  }
    45  
    46  func TestSeqCount(t *testing.T) {
    47  	badEqType := newTestClass("Eq", []*Type{IntType}, newStringDict(map[string]*Object{
    48  		"__eq__": newBuiltinFunction("__eq__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
    49  			return nil, f.RaiseType(TypeErrorType, "uh oh")
    50  		}).ToObject(),
    51  	}))
    52  	badNonZeroType := newTestClass("BadNonZeroType", []*Type{ObjectType}, newStringDict(map[string]*Object{
    53  		"__nonzero__": newBuiltinFunction("__nonzero__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
    54  			return nil, f.RaiseType(TypeErrorType, "uh oh")
    55  		}).ToObject(),
    56  	}))
    57  	worseEqType := newTestClass("WorseEqCmp", []*Type{IntType}, newStringDict(map[string]*Object{
    58  		"__eq__": newBuiltinFunction("__eq__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
    59  			return newObject(badNonZeroType), nil
    60  		}).ToObject(),
    61  	}))
    62  	cases := []invokeTestCase{
    63  		{args: wrapArgs(newTestList(), NewInt(1)), want: NewInt(0).ToObject()},
    64  		{args: wrapArgs(newTestList(1, 2, 3, 4, 5, 6), NewInt(7)), want: NewInt(0).ToObject()},
    65  		{args: wrapArgs(newTestList(1, 2, 3, 2, 2, 4), NewInt(2)), want: NewInt(3).ToObject()},
    66  		{args: wrapArgs(newTestList(1, None, None, 3), None), want: NewInt(2).ToObject()},
    67  		{args: wrapArgs(newTestList("a", "b", "c", "d", "e"), NewStr("c")), want: NewInt(1).ToObject()},
    68  		{args: wrapArgs(newTestList(newObject(badEqType)), newObject(badEqType)), wantExc: mustCreateException(TypeErrorType, "uh oh")},
    69  		{args: wrapArgs(newTestList(newObject(worseEqType)), newObject(worseEqType)), wantExc: mustCreateException(TypeErrorType, "uh oh")},
    70  	}
    71  	for _, cas := range cases {
    72  		if err := runInvokeTestCase(wrapFuncForTest(seqCount), &cas); err != "" {
    73  			t.Error(err)
    74  		}
    75  	}
    76  }
    77  
    78  func TestSeqForEach(t *testing.T) {
    79  	fun := wrapFuncForTest(func(f *Frame, seq *Object) (*Object, *BaseException) {
    80  		elems := []*Object{}
    81  		raised := seqForEach(f, seq, func(elem *Object) *BaseException {
    82  			elems = append(elems, elem)
    83  			return nil
    84  		})
    85  		if raised != nil {
    86  			return nil, raised
    87  		}
    88  		return NewTuple(elems...).ToObject(), nil
    89  	})
    90  	cases := []invokeTestCase{
    91  		{args: wrapArgs(NewList()), want: NewTuple().ToObject()},
    92  		{args: wrapArgs(newTestDict("foo", 1, "bar", 2)), want: newTestTuple("foo", "bar").ToObject()},
    93  		{args: wrapArgs(123), wantExc: mustCreateException(TypeErrorType, "'int' object is not iterable")},
    94  	}
    95  	for _, cas := range cases {
    96  		if err := runInvokeTestCase(fun, &cas); err != "" {
    97  			t.Error(err)
    98  		}
    99  	}
   100  }
   101  
   102  func TestSeqIterator(t *testing.T) {
   103  	fun := newBuiltinFunction("TestSeqIterator", func(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   104  		return TupleType.Call(f, args, nil)
   105  	}).ToObject()
   106  	exhaustedIter := newSeqIterator(NewStr("foo").ToObject())
   107  	TupleType.Call(NewRootFrame(), []*Object{exhaustedIter}, nil)
   108  	cases := []invokeTestCase{
   109  		{args: wrapArgs(newSeqIterator(NewStr("bar").ToObject())), want: newTestTuple("b", "a", "r").ToObject()},
   110  		{args: wrapArgs(newSeqIterator(newTestTuple(123, 456).ToObject())), want: newTestTuple(123, 456).ToObject()},
   111  		{args: wrapArgs(exhaustedIter), want: NewTuple().ToObject()},
   112  	}
   113  	for _, cas := range cases {
   114  		if err := runInvokeTestCase(fun, &cas); err != "" {
   115  			t.Error(err)
   116  		}
   117  	}
   118  }
   119  
   120  func TestSeqNew(t *testing.T) {
   121  	fun := newBuiltinFunction("TestSeqNew", func(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   122  		elems, raised := seqNew(f, args)
   123  		if raised != nil {
   124  			return nil, raised
   125  		}
   126  		return NewTuple(elems...).ToObject(), nil
   127  	}).ToObject()
   128  	cases := []invokeTestCase{
   129  		{want: NewTuple().ToObject()},
   130  		{args: wrapArgs(newTestTuple("foo", "bar")), want: newTestTuple("foo", "bar").ToObject()},
   131  		{args: wrapArgs(newTestDict("foo", 1)), want: newTestTuple("foo").ToObject()},
   132  	}
   133  	for _, cas := range cases {
   134  		if err := runInvokeTestCase(fun, &cas); err != "" {
   135  			t.Error(err)
   136  		}
   137  	}
   138  }