From 47cda68a4b03d9e966b17fddfa463726094ce97b Mon Sep 17 00:00:00 2001 From: Sarah Gilmore Date: Wed, 17 May 2023 13:32:00 -0400 Subject: [PATCH 1/2] 1. Create an abstract TestClass called hNumericArray that has shared tests for numeric arrays. 2. Change tFloat32Array and tFloat64Array to inherit from hNumericArray. Co-authored-by: Kevin Gurney --- matlab/test/arrow/array/hNumericArray.m | 133 ++++++++++++++++++++++++ matlab/test/arrow/array/tFloat32Array.m | 86 ++------------- matlab/test/arrow/array/tFloat64Array.m | 104 ++---------------- 3 files changed, 150 insertions(+), 173 deletions(-) create mode 100644 matlab/test/arrow/array/hNumericArray.m diff --git a/matlab/test/arrow/array/hNumericArray.m b/matlab/test/arrow/array/hNumericArray.m new file mode 100644 index 00000000000..4a2485f4905 --- /dev/null +++ b/matlab/test/arrow/array/hNumericArray.m @@ -0,0 +1,133 @@ +classdef hNumericArray < matlab.unittest.TestCase + % Test class containing shared tests for numeric arrays. + + % Licensed to the Apache Software Foundation (ASF) under one or more + % contributor license agreements. See the NOTICE file distributed with + % this work for additional information regarding copyright ownership. + % The ASF licenses this file to you under the Apache License, Version + % 2.0 (the "License"); you may not use this file except in compliance + % with the License. You may obtain a copy of the License at + % + % http://www.apache.org/licenses/LICENSE-2.0 + % + % Unless required by applicable law or agreed to in writing, software + % distributed under the License is distributed on an "AS IS" BASIS, + % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + % implied. See the License for the specific language governing + % permissions and limitations under the License. + properties (Abstract) + ArrowArrayClassName(1, 1) string + ArrowArrayConstructor + MatlabArrayFcn + MatlabConversionFcn + MaxValue (1, 1) + MinValue (1, 1) + end + + properties (TestParameter) + MakeDeepCopy = {true false} + end + + methods(TestClassSetup) + function verifyOnMatlabPath(tc) + % Verify the arrow array class is on the MATLAB Search Path. + tc.assertTrue(~isempty(which(tc.ArrowArrayClassName)), ... + """" + tc.ArrowArrayClassName + """must be on the MATLAB path. " + ... + "Use ""addpath"" to add folders to the MATLAB path."); + end + end + + methods(Test) + function BasicTest(tc, MakeDeepCopy) + A = tc.ArrowArrayConstructor(tc.MatlabArrayFcn([1 2 3]), DeepCopy=MakeDeepCopy); + className = string(class(A)); + tc.verifyEqual(className, tc.ArrowArrayClassName); + end + + function ShallowCopyTest(tc) + % By default, NumericArrays do not create a deep copy on + % construction when constructed from a MATLAB array. Instead, + % it stores a shallow copy of the array keep the memory alive. + A = tc.ArrowArrayConstructor(tc.MatlabArrayFcn([1, 2, 3])); + tc.verifyEqual(A.MatlabArray, tc.MatlabArrayFcn([1, 2, 3])); + tc.verifyEqual(toMATLAB(A), tc.MatlabArrayFcn([1 2 3]')); + + A = tc.ArrowArrayConstructor(tc.MatlabArrayFcn([1, 2, 3]), DeepCopy=false); + tc.verifyEqual(A.MatlabArray, tc.MatlabArrayFcn([1 2 3])); + tc.verifyEqual(toMATLAB(A), tc.MatlabArrayFcn([1 2 3]')); + end + + function DeepCopyTest(tc) + % Verify NumericArrays does not store shallow copy of the + % MATLAB array if DeepCopy=true was supplied. + A = tc.ArrowArrayConstructor(tc.MatlabArrayFcn([1, 2, 3]), DeepCopy=true); + tc.verifyEqual(A.MatlabArray, tc.MatlabArrayFcn([])); + tc.verifyEqual(toMATLAB(A), tc.MatlabArrayFcn([1 2 3]')); + end + + function ToMATLAB(tc, MakeDeepCopy) + % Create array from a scalar + A1 = tc.ArrowArrayConstructor(tc.MatlabArrayFcn(100), DeepCopy=MakeDeepCopy); + data = toMATLAB(A1); + tc.verifyEqual(data, tc.MatlabArrayFcn(100)); + + % Create array from a vector + A2 = tc.ArrowArrayConstructor(tc.MatlabArrayFcn([1 2 3]), DeepCopy=MakeDeepCopy); + data = toMATLAB(A2); + tc.verifyEqual(data, tc.MatlabArrayFcn([1 2 3]')); + + % Create a Float64Array from an empty double vector + A3 = tc.ArrowArrayConstructor(tc.MatlabArrayFcn([]), DeepCopy=MakeDeepCopy); + data = toMATLAB(A3); + tc.verifyEqual(data, tc.MatlabArrayFcn(reshape([], 0, 1))); + end + + function MatlabConversion(tc, MakeDeepCopy) + % Tests the type-specific conversion methods, e.g. single for + % arrow.array.Float32Array, double for array.array.Float64Array + + % Create array from a scalar + A1 = tc.ArrowArrayConstructor(tc.MatlabArrayFcn(100), DeepCopy=MakeDeepCopy); + data = tc.MatlabConversionFcn(A1); + tc.verifyEqual(data, tc.MatlabArrayFcn(100)); + + % Create array from a vector + A2 = tc.ArrowArrayConstructor(tc.MatlabArrayFcn([1 2 3]), DeepCopy=MakeDeepCopy); + data = tc.MatlabConversionFcn(A2); + tc.verifyEqual(data, tc.MatlabArrayFcn([1 2 3]')); + + % Create an array from an empty vector + A3 = tc.ArrowArrayConstructor(tc.MatlabArrayFcn([]), DeepCopy=MakeDeepCopy); + data = tc.MatlabConversionFcn(A3); + tc.verifyEqual(data, tc.MatlabArrayFcn(reshape([], 0, 1))); + end + + function MinValueTest(tc, MakeDeepCopy) + A = tc.ArrowArrayConstructor(tc.MinValue, DeepCopy=MakeDeepCopy); + tc.verifyEqual(toMATLAB(A), tc.MinValue); + end + + function MaxValueTest(tc, MakeDeepCopy) + A1 = tc.ArrowArrayConstructor(tc.MaxValue, DeepCopy=MakeDeepCopy); + tc.verifyEqual(toMATLAB(A1), tc.MaxValue); + end + + function ErrorIfComplex(tc, MakeDeepCopy) + fcn = @() tc.ArrowArrayConstructor(tc.MatlabArrayFcn([10 + 1i, 4]), DeepCopy=MakeDeepCopy); + tc.verifyError(fcn, "MATLAB:expectedReal"); + end + + function ErrorIfNotTwoDimensional(tc, MakeDeepCopy) + data = tc.MatlabArrayFcn([1 2 3 4 5 6 7 8 9]); + data = reshape(data, 3, 1, 3); + fcn = @() tc.ArrowArrayConstructor(tc.MatlabArrayFcn(data), DeepCopy=MakeDeepCopy); + tc.verifyError(fcn, "MATLAB:expected2D"); + end + + function ErrorIfNonVector(tc, MakeDeepCopy) + data = tc.MatlabArrayFcn([1 2; 3 4]); + fcn = @() tc.ArrowArrayConstructor(data, DeepCopy=MakeDeepCopy); + tc.verifyError(fcn, "MATLAB:expectedVector"); + end + end +end \ No newline at end of file diff --git a/matlab/test/arrow/array/tFloat32Array.m b/matlab/test/arrow/array/tFloat32Array.m index 9768ee8f537..e9a3206fbf0 100644 --- a/matlab/test/arrow/array/tFloat32Array.m +++ b/matlab/test/arrow/array/tFloat32Array.m @@ -1,4 +1,4 @@ -classdef tFloat32Array < matlab.unittest.TestCase +classdef tFloat32Array < hNumericArray % Tests for arrow.array.Float32rray % Licensed to the Apache Software Foundation (ASF) under one or more @@ -16,90 +16,20 @@ % implied. See the License for the specific language governing % permissions and limitations under the License. - properties (TestParameter) - MakeDeepCopy = {true false} + properties + ArrowArrayClassName = "arrow.array.Float32Array" + ArrowArrayConstructor = @arrow.array.Float32Array + MatlabConversionFcn = @single % single method on class + MatlabArrayFcn = @single % single function + MaxValue = realmax("single") + MinValue = realmin("single") end - methods(TestClassSetup) - function verifyOnMatlabPath(testCase) - % arrow.array.Float32Array must be on the MATLAB path. - testCase.assertTrue(~isempty(which('arrow.array.Float32Array')), ... - '''arrow.array.Float32Array'' must be on the MATLAB path. Use ''addpath'' to add folders to the MATLAB path.'); - end - end - methods(Test) - function Basic(testCase, MakeDeepCopy) - A = arrow.array.Float32Array(single([1, 2, 3]), DeepCopy=MakeDeepCopy); - className = string(class(A)); - testCase.verifyEqual(className, "arrow.array.Float32Array"); - end - - function ShallowCopy(testCase) - % By default, Float32Array does not create a deep copy on - % construction when constructed from a MATLAB array. Instead, - % it stores a shallow copy of the array keep the memory alive. - A = arrow.array.Float32Array(single([1, 2, 3])); - testCase.verifyEqual(A.MatlabArray, single([1 2 3])); - testCase.verifyEqual(single(A), single([1 2 3]')); - - A = arrow.array.Float32Array(single([1, 2, 3]), DeepCopy=false); - testCase.verifyEqual(A.MatlabArray, single([1 2 3])); - testCase.verifyEqual(single(A), single([1 2 3]')); - end - - function DeepCopy(testCase) - % Verify Float32Array does not store shallow copy of the MATLAB - % array if DeepCopy=true was supplied. - A = arrow.array.Float32Array(single([1, 2, 3]), DeepCopy=true); - testCase.verifyEqual(A.MatlabArray, single([])); - testCase.verifyEqual(single(A), single([1 2 3]')); - end - - function Single(testCase, MakeDeepCopy) - % Create a Float32Array from a scalar double - A1 = arrow.array.Float32Array(single(100), DeepCopy=MakeDeepCopy); - data = single(A1); - testCase.verifyEqual(data, single(100)); - - % Create a Float32Array from a double vector - A2 = arrow.array.Float32Array(single([1 2 3]), DeepCopy=MakeDeepCopy); - data = single(A2); - testCase.verifyEqual(data, single([1 2 3]')); - - % Create a Float32Array from an empty double vector - A3 = arrow.array.Float32Array(single([]), DeepCopy=MakeDeepCopy); - data = single(A3); - testCase.verifyEqual(data, single.empty(0, 1)); - end - - function MinValue(testCase, MakeDeepCopy) - A1 = arrow.array.Float32Array(realmin("single"), DeepCopy=MakeDeepCopy); - data = single(A1); - testCase.verifyEqual(data, realmin("single")); - end - - function MaxValue(testCase, MakeDeepCopy) - A1 = arrow.array.Float32Array(realmax('single'), DeepCopy=MakeDeepCopy); - data = single(A1); - testCase.verifyEqual(data, realmax('single')); - end - function InfValues(testCase, MakeDeepCopy) A1 = arrow.array.Float32Array(single([Inf -Inf]), DeepCopy=MakeDeepCopy); data = single(A1); testCase.verifyEqual(data, single([Inf -Inf]')); end - - function ErrorIfComplex(testCase, MakeDeepCopy) - fcn = @() arrow.array.Float32Array(single([10 + 1i, 4]), DeepCopy=MakeDeepCopy); - testCase.verifyError(fcn, "MATLAB:expectedReal"); - end - - function toMATLAB(testCase, MakeDeepCopy) - A1 = arrow.array.Float32Array(single(100), DeepCopy=MakeDeepCopy); - data = toMATLAB(A1); - testCase.verifyEqual(data, single(100)); - end end end diff --git a/matlab/test/arrow/array/tFloat64Array.m b/matlab/test/arrow/array/tFloat64Array.m index 96a02d0174e..6bd84d8f67e 100755 --- a/matlab/test/arrow/array/tFloat64Array.m +++ b/matlab/test/arrow/array/tFloat64Array.m @@ -1,4 +1,4 @@ -classdef tFloat64Array < matlab.unittest.TestCase +classdef tFloat64Array < hNumericArray % Tests for arrow.array.Float64Array % Licensed to the Apache Software Foundation (ASF) under one or more @@ -16,112 +16,26 @@ % implied. See the License for the specific language governing % permissions and limitations under the License. - properties (TestParameter) - MakeDeepCopy = {true false} - end - methods(TestClassSetup) - function verifyOnMatlabPath(testCase) - % arrow.array.Float64Array must be on the MATLAB path. - testCase.assertTrue(~isempty(which('arrow.array.Float64Array')), ... - '''arrow.array.Float64Array'' must be on the MATLAB path. Use ''addpath'' to add folders to the MATLAB path.'); - end + properties + ArrowArrayClassName = "arrow.array.Float64Array" + ArrowArrayConstructor = @arrow.array.Float64Array + MatlabConversionFcn = @double % double method on class + MatlabArrayFcn = @double % double function + MaxValue = realmax("double") + MinValue = realmin("double") end - - methods(Test) - function Basic(testCase, MakeDeepCopy) - A = arrow.array.Float64Array([1, 2, 3], DeepCopy=MakeDeepCopy); - className = string(class(A)); - testCase.verifyEqual(className, "arrow.array.Float64Array"); - end - - function ShallowCopy(testCase) - % By default, Float64Array does not create a deep copy on - % construction when constructed from a MATLAB array. Instead, - % it stores a shallow copy of the array keep the memory alive. - A = arrow.array.Float64Array([1, 2, 3]); - testCase.verifyEqual(A.MatlabArray, [1 2 3]); - testCase.verifyEqual(double(A), [1 2 3]'); - - A = arrow.array.Float64Array([1, 2, 3], DeepCopy=false); - testCase.verifyEqual(A.MatlabArray, [1 2 3]); - testCase.verifyEqual(double(A), [1 2 3]'); - end - - function DeepCopy(testCase) - % Verify Float64Array does not store shallow copy of the MATLAB - % array if DeepCopy=true was supplied. - A = arrow.array.Float64Array([1, 2, 3], DeepCopy=true); - testCase.verifyEqual(A.MatlabArray, []); - testCase.verifyEqual(double(A), [1 2 3]'); - end - - function Double(testCase, MakeDeepCopy) - % Create a Float64Array from a scalar double - A1 = arrow.array.Float64Array(100, DeepCopy=MakeDeepCopy); - data = double(A1); - testCase.verifyEqual(data, 100); - - % Create a Float64Array from a double vector - A2 = arrow.array.Float64Array([1 2 3], DeepCopy=MakeDeepCopy); - data = double(A2); - testCase.verifyEqual(data, [1 2 3]'); - - % Create a Float64Array from an empty double vector - A3 = arrow.array.Float64Array([], DeepCopy=MakeDeepCopy); - data = double(A3); - testCase.verifyEqual(data, double.empty(0, 1)); - end - - function MinValue(testCase, MakeDeepCopy) - A1 = arrow.array.Float64Array(realmin, DeepCopy=MakeDeepCopy); - data = double(A1); - testCase.verifyEqual(data, realmin); - end - - function MaxValue(testCase, MakeDeepCopy) - A1 = arrow.array.Float64Array(realmax, DeepCopy=MakeDeepCopy); - data = double(A1); - testCase.verifyEqual(data, realmax); - end + methods(Test) function InfValues(testCase, MakeDeepCopy) A1 = arrow.array.Float64Array([Inf -Inf], DeepCopy=MakeDeepCopy); data = double(A1); testCase.verifyEqual(data, [Inf -Inf]'); end - function ErrorIfComplex(testCase, MakeDeepCopy) - fcn = @() arrow.array.Float64Array([10 + 1i, 4], DeepCopy=MakeDeepCopy); - testCase.verifyError(fcn, "MATLAB:expectedReal"); - end - function ErrorIfSparse(testCase, MakeDeepCopy) fcn = @() arrow.array.Float64Array(sparse(ones([10 1])), DeepCopy=MakeDeepCopy); testCase.verifyError(fcn, "MATLAB:expectedNonsparse"); end - - function Length(testCase, MakeDeepCopy) - % Zero length array - A = arrow.array.Float64Array([], DeepCopy=MakeDeepCopy); - expectedLength = int64(0); - testCase.verifyEqual(A.Length, expectedLength); - - % Scalar - A = arrow.array.Float64Array(1, DeepCopy=MakeDeepCopy); - expectedLength = int64(1); - testCase.verifyEqual(A.Length, expectedLength); - - % Vector - A = arrow.array.Float64Array(1:100, DeepCopy=MakeDeepCopy); - expectedLength = int64(100); - testCase.verifyEqual(A.Length, expectedLength); - end - - function toMATLAB(testCase, MakeDeepCopy) - A1 = arrow.array.Float64Array(100, DeepCopy=MakeDeepCopy); - data = toMATLAB(A1); - testCase.verifyEqual(data, 100); - end end end From fa413de0f8d092f08843bcb4a01a857466930fbf Mon Sep 17 00:00:00 2001 From: sgilmore10 <74676073+sgilmore10@users.noreply.github.com> Date: Thu, 18 May 2023 09:26:22 -0400 Subject: [PATCH 2/2] Fix indentation Co-authored-by: Sutou Kouhei --- matlab/test/arrow/array/hNumericArray.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/matlab/test/arrow/array/hNumericArray.m b/matlab/test/arrow/array/hNumericArray.m index 4a2485f4905..f76daa04694 100644 --- a/matlab/test/arrow/array/hNumericArray.m +++ b/matlab/test/arrow/array/hNumericArray.m @@ -83,8 +83,8 @@ function ToMATLAB(tc, MakeDeepCopy) end function MatlabConversion(tc, MakeDeepCopy) - % Tests the type-specific conversion methods, e.g. single for - % arrow.array.Float32Array, double for array.array.Float64Array + % Tests the type-specific conversion methods, e.g. single for + % arrow.array.Float32Array, double for array.array.Float64Array % Create array from a scalar A1 = tc.ArrowArrayConstructor(tc.MatlabArrayFcn(100), DeepCopy=MakeDeepCopy);