github.com/google/grumpy@v0.0.0-20171122020858-3ec87959189c/runtime/code_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 TestXxx(t *testing.T) {
    22  }
    23  
    24  func TestNewCodeKeywordsCheck(t *testing.T) {
    25  	oldLogFatal := logFatal
    26  	defer func() { logFatal = oldLogFatal }()
    27  	var got string
    28  	logFatal = func(msg string) {
    29  		got = msg
    30  	}
    31  	NewCode("foo", "foo.py", []Param{{"bar", None}, {"baz", nil}}, 0, nil)
    32  	if want := "foo() non-keyword arg baz after keyword arg"; got != want {
    33  		t.Errorf("NewCode logged %q, want %q", got, want)
    34  	}
    35  }
    36  
    37  func TestNewCode(t *testing.T) {
    38  	testFunc := newBuiltinFunction("TestNewCode", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
    39  		if raised := checkFunctionVarArgs(f, "TestNewCode", args, CodeType); raised != nil {
    40  			return nil, raised
    41  		}
    42  		return toCodeUnsafe(args[0]).Eval(f, nil, args[1:], kwargs)
    43  	})
    44  	fn := func(f *Frame, args []*Object) (*Object, *BaseException) {
    45  		return NewTuple(Args(args).makeCopy()...).ToObject(), nil
    46  	}
    47  	nilFn := func(*Frame, []*Object) (*Object, *BaseException) {
    48  		return nil, nil
    49  	}
    50  	cases := []invokeTestCase{
    51  		invokeTestCase{args: wrapArgs(NewCode("f1", "foo.py", nil, 0, fn)), want: NewTuple().ToObject()},
    52  		invokeTestCase{args: wrapArgs(NewCode("f2", "foo.py", []Param{{"a", nil}}, 0, fn), 123), want: newTestTuple(123).ToObject()},
    53  		invokeTestCase{args: wrapArgs(NewCode("f2", "foo.py", []Param{{"a", nil}}, 0, fn)), kwargs: wrapKWArgs("a", "apple"), want: newTestTuple("apple").ToObject()},
    54  		invokeTestCase{args: wrapArgs(NewCode("f2", "foo.py", []Param{{"a", nil}}, 0, fn)), kwargs: wrapKWArgs("b", "bear"), wantExc: mustCreateException(TypeErrorType, "f2() got an unexpected keyword argument 'b'")},
    55  		invokeTestCase{args: wrapArgs(NewCode("f2", "foo.py", []Param{{"a", nil}}, 0, fn)), wantExc: mustCreateException(TypeErrorType, "f2() takes at least 1 arguments (0 given)")},
    56  		invokeTestCase{args: wrapArgs(NewCode("f2", "foo.py", []Param{{"a", nil}}, 0, fn), 1, 2, 3), wantExc: mustCreateException(TypeErrorType, "f2() takes 1 arguments (3 given)")},
    57  		invokeTestCase{args: wrapArgs(NewCode("f3", "foo.py", []Param{{"a", nil}, {"b", nil}}, 0, fn), 1, 2), want: newTestTuple(1, 2).ToObject()},
    58  		invokeTestCase{args: wrapArgs(NewCode("f3", "foo.py", []Param{{"a", nil}, {"b", nil}}, 0, fn), 1), kwargs: wrapKWArgs("b", "bear"), want: newTestTuple(1, "bear").ToObject()},
    59  		invokeTestCase{args: wrapArgs(NewCode("f3", "foo.py", []Param{{"a", nil}, {"b", nil}}, 0, fn)), kwargs: wrapKWArgs("b", "bear", "a", "apple"), want: newTestTuple("apple", "bear").ToObject()},
    60  		invokeTestCase{args: wrapArgs(NewCode("f3", "foo.py", []Param{{"a", nil}, {"b", nil}}, 0, fn), 1), kwargs: wrapKWArgs("a", "alpha"), wantExc: mustCreateException(TypeErrorType, "f3() got multiple values for keyword argument 'a'")},
    61  		invokeTestCase{args: wrapArgs(NewCode("f4", "foo.py", []Param{{"a", nil}, {"b", None}}, 0, fn), 123), want: newTestTuple(123, None).ToObject()},
    62  		invokeTestCase{args: wrapArgs(NewCode("f4", "foo.py", []Param{{"a", nil}, {"b", None}}, 0, fn), 123, "bar"), want: newTestTuple(123, "bar").ToObject()},
    63  		invokeTestCase{args: wrapArgs(NewCode("f4", "foo.py", []Param{{"a", nil}, {"b", None}}, 0, fn)), kwargs: wrapKWArgs("a", 123, "b", "bar"), want: newTestTuple(123, "bar").ToObject()},
    64  		invokeTestCase{args: wrapArgs(NewCode("f5", "foo.py", []Param{{"a", nil}}, CodeFlagVarArg, fn), 1), want: newTestTuple(1, NewTuple()).ToObject()},
    65  		invokeTestCase{args: wrapArgs(NewCode("f5", "foo.py", []Param{{"a", nil}}, CodeFlagVarArg, fn), 1, 2, 3), want: newTestTuple(1, newTestTuple(2, 3)).ToObject()},
    66  		invokeTestCase{args: wrapArgs(NewCode("f6", "foo.py", []Param{{"a", nil}}, CodeFlagKWArg, fn), "bar"), want: newTestTuple("bar", NewDict()).ToObject()},
    67  		invokeTestCase{args: wrapArgs(NewCode("f6", "foo.py", []Param{{"a", nil}}, CodeFlagKWArg, fn)), kwargs: wrapKWArgs("a", "apple", "b", "bear"), want: newTestTuple("apple", newTestDict("b", "bear")).ToObject()},
    68  		invokeTestCase{args: wrapArgs(NewCode("f6", "foo.py", []Param{{"a", nil}}, CodeFlagKWArg, fn), "bar"), kwargs: wrapKWArgs("b", "baz", "c", "qux"), want: newTestTuple("bar", newTestDict("b", "baz", "c", "qux")).ToObject()},
    69  		invokeTestCase{args: wrapArgs(NewCode("f7", "foo.py", nil, 0, nilFn)), want: None},
    70  	}
    71  	for _, cas := range cases {
    72  		if err := runInvokeTestCase(testFunc.ToObject(), &cas); err != "" {
    73  			t.Error(err)
    74  		}
    75  	}
    76  }
    77  
    78  func TestCodeEvalRestoreExc(t *testing.T) {
    79  	e := mustCreateException(RuntimeErrorType, "uh oh")
    80  	ranC1, ranC2 := false, false
    81  	globals := NewDict()
    82  	c1 := NewCode("<c1>", "foo.py", nil, 0, func(f *Frame, _ []*Object) (*Object, *BaseException) {
    83  		if got, _ := f.ExcInfo(); got != e {
    84  			t.Errorf("ExcInfo() = %v, want %v", got, e)
    85  		}
    86  		f.RestoreExc(nil, nil)
    87  		ranC1 = true
    88  		return None, nil
    89  	})
    90  	c2 := NewCode("<c2>", "foo.py", nil, 0, func(f *Frame, _ []*Object) (*Object, *BaseException) {
    91  		f.RestoreExc(e, newTraceback(f, nil))
    92  		c1.Eval(f, globals, nil, nil)
    93  		// The exception was cleared by c1 but when returning to c2, it
    94  		// should have been restored.
    95  		if got, _ := f.ExcInfo(); got != e {
    96  			t.Errorf("ExcInfo() = %v, want <nil>", got)
    97  		}
    98  		f.RestoreExc(nil, nil)
    99  		ranC2 = true
   100  		return None, nil
   101  	})
   102  	c2.Eval(NewRootFrame(), globals, nil, nil)
   103  	if !ranC1 {
   104  		t.Error("c1 did not run")
   105  	}
   106  	if !ranC2 {
   107  		t.Error("c2 did not run")
   108  	}
   109  }