Beispiel #1
0
        public void SequenceDecoderTest()
        {
            var codec = SequenceDecoder.Instance;
            var items = new List <PyObject>()
            {
                new PyInt(1), new PyInt(2), new PyInt(3)
            };

            //SequenceConverter can only convert to any ICollection
            using var pyList   = new PyList(items.ToArray());
            using var listType = pyList.GetPythonType();
            //it can convert a PyList, since PyList satisfies the python sequence protocol

            Assert.IsFalse(codec.CanDecode(listType, typeof(bool)));
            Assert.IsFalse(codec.CanDecode(listType, typeof(IList <int>)));
            Assert.IsFalse(codec.CanDecode(listType, typeof(System.Collections.IEnumerable)));
            Assert.IsFalse(codec.CanDecode(listType, typeof(IEnumerable <int>)));

            Assert.IsTrue(codec.CanDecode(listType, typeof(ICollection <float>)));
            Assert.IsTrue(codec.CanDecode(listType, typeof(ICollection <string>)));
            Assert.IsTrue(codec.CanDecode(listType, typeof(ICollection <int>)));

            //convert to collection of int
            ICollection <int> intCollection = null;

            Assert.DoesNotThrow(() => { codec.TryDecode(pyList, out intCollection); });
            CollectionAssert.AreEqual(intCollection, new List <object> {
                1, 2, 3
            });

            //no python exception should have occurred during the above conversion and check
            Runtime.CheckExceptionOccurred();

            //convert to collection of string.   This will not work.
            //The SequenceWrapper class will throw a python exception when it tries to access any element.
            //TryDecode is a lossless conversion so there will be no exception at that point
            //interestingly, since the size of the python sequence can be queried without any conversion,
            //the IList will report a Count of 3.
            ICollection <string> stringCollection = null;

            Assert.DoesNotThrow(() => { codec.TryDecode(pyList, out stringCollection); });
            Assert.AreEqual(3, stringCollection.Count());
            Assert.Throws(typeof(InvalidCastException), () => {
                string[] array = new string[3];
                stringCollection.CopyTo(array, 0);
            });

            Runtime.CheckExceptionOccurred();

            //can't convert python iterable to collection (this will require a copy which isn't lossless)
            //python iterables do not satisfy the python sequence protocol
            var foo     = GetPythonIterable();
            var fooType = foo.GetPythonType();

            Assert.IsFalse(codec.CanDecode(fooType, typeof(ICollection <int>)));

            //python tuples do satisfy the python sequence protocol
            var pyTuple     = new PyTuple(items.ToArray());
            var pyTupleType = pyTuple.GetPythonType();

            Assert.IsTrue(codec.CanDecode(pyTupleType, typeof(ICollection <float>)));
            Assert.IsTrue(codec.CanDecode(pyTupleType, typeof(ICollection <int>)));
            Assert.IsTrue(codec.CanDecode(pyTupleType, typeof(ICollection <string>)));

            //convert to collection of int
            ICollection <int> intCollection2 = null;

            Assert.DoesNotThrow(() => { codec.TryDecode(pyTuple, out intCollection2); });
            CollectionAssert.AreEqual(intCollection2, new List <object> {
                1, 2, 3
            });

            //no python exception should have occurred during the above conversion and check
            Runtime.CheckExceptionOccurred();

            //convert to collection of string.   This will not work.
            //The SequenceWrapper class will throw a python exception when it tries to access any element.
            //TryDecode is a lossless conversion so there will be no exception at that point
            //interestingly, since the size of the python sequence can be queried without any conversion,
            //the IList will report a Count of 3.
            ICollection <string> stringCollection2 = null;

            Assert.DoesNotThrow(() => { codec.TryDecode(pyTuple, out stringCollection2); });
            Assert.AreEqual(3, stringCollection2.Count());
            Assert.Throws(typeof(InvalidCastException), () => {
                string[] array = new string[3];
                stringCollection2.CopyTo(array, 0);
            });

            Runtime.CheckExceptionOccurred();
        }