Skip to content

Commit

Permalink
apacheGH-37179: [MATLAB] Add a test utility that creates a MATLAB `ta…
Browse files Browse the repository at this point in the history
…ble` containing all supported types (apache#37191)

### Rationale for this change

It would be helpful it we had a test utility that created a MATLAB `table` containing all the supported types. This would help avoid code duplication in our tests.

### What changes are included in this PR?

1. Added a new utility named `arrow.internal.test.tabular.createTableWithSupportedTypes()`
2. Updated `tRecordBatch.m` to use this utility.
3. Updated `tfeather.m` to use this utility.

### Are these changes tested?

Yes.

### Are there any user-facing changes?

No.

* Closes: apache#37179

Authored-by: Sarah Gilmore <[email protected]>
Signed-off-by: Sutou Kouhei <[email protected]>
  • Loading branch information
sgilmore10 authored Aug 15, 2023
1 parent 7c8c2fb commit 01a9f72
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 108 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
%CREATETABLEWITHSUPPORTEDTYPES Creates a MATLAB table containing all the
%MATLAB types that can be converted into arrow 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.

function T = createTableWithSupportedTypes(opts)
arguments
opts.NumRows(1, 1) {mustBeFinite, mustBeNonnegative} = 3;
end

numRows = opts.NumRows;

variableNames = ["uint8", ...
"uint16", ...
"uint32", ...
"uint64", ...
"int8", ...
"int16", ...
"int32", ...
"int64", ...
"logical", ...
"single", ...
"double", ...
"string", ...
"datetime"];

T = table(uint8 ((1:numRows)'), ...
uint16 ((1:numRows)'), ...
uint32 ((1:numRows)'), ...
uint64 ((1:numRows)'), ...
int8 ((1:numRows)'), ...
int16 ((1:numRows)'), ...
int32 ((1:numRows)'), ...
int64 ((1:numRows)'), ...
logical ((1:numRows)'), ...
single ((1:numRows)'), ...
double ((1:numRows)'), ...
string ((1:numRows)'), ...
datetime(2023, 6, 28) + days(0:numRows-1)', ...
VariableNames=variableNames);
end
31 changes: 10 additions & 21 deletions matlab/test/arrow/tabular/tRecordBatch.m
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ function Basic(tc)

function SupportedTypes(tc)
% Create a table all supported MATLAB types.
TOriginal = createTableWithAllSupportedTypes();
import arrow.internal.test.tabular.createTableWithSupportedTypes

TOriginal = createTableWithSupportedTypes();
arrowRecordBatch = arrow.recordbatch(TOriginal);
expectedColumnNames = compose("Var%d", 1:13);
expectedColumnNames = string(TOriginal.Properties.VariableNames);
tc.verifyRecordBatch(arrowRecordBatch, expectedColumnNames, TOriginal);
end

Expand Down Expand Up @@ -123,16 +125,17 @@ function FromArraysColumnNamesNotProvided(tc)
% RecordBatch when given a comma-separated list of
% arrow.array.Array values.
import arrow.tabular.RecordBatch
import arrow.internal.test.tabular.createTableWithSupportedTypes

TOriginal = createTableWithAllSupportedTypes();
TOriginal = createTableWithSupportedTypes();

arrowArrays = cell([1 width(TOriginal)]);
for ii = 1:width(TOriginal)
arrowArrays{ii} = arrow.array(TOriginal.(ii));
end

arrowRecordBatch = RecordBatch.fromArrays(arrowArrays{:});
expectedColumnNames = compose("Column%d", 1:13);
expectedColumnNames = compose("Column%d", 1:width(TOriginal));
TOriginal.Properties.VariableNames = expectedColumnNames;
tc.verifyRecordBatch(arrowRecordBatch, expectedColumnNames, TOriginal);
end
Expand All @@ -142,15 +145,16 @@ function FromArraysWithColumnNamesProvided(tc)
% RecordBatch when given a comma-separated list of
% arrow.array.Array values and the ColumnNames nv-pair is provided.
import arrow.tabular.RecordBatch
import arrow.internal.test.tabular.createTableWithSupportedTypes

TOriginal = createTableWithAllSupportedTypes();
TOriginal = createTableWithSupportedTypes();

arrowArrays = cell([1 width(TOriginal)]);
for ii = 1:width(TOriginal)
arrowArrays{ii} = arrow.array(TOriginal.(ii));
end

columnNames = string(char(65:77)')';
columnNames = compose("MyVar%d", 1:numel(arrowArrays));
arrowRecordBatch = RecordBatch.fromArrays(arrowArrays{:}, ColumnNames=columnNames);
TOriginal.Properties.VariableNames = columnNames;
tc.verifyRecordBatch(arrowRecordBatch, columnNames, TOriginal);
Expand Down Expand Up @@ -237,18 +241,3 @@ function verifyRecordBatch(tc, recordBatch, expectedColumnNames, expectedTable)
end
end

function T = createTableWithAllSupportedTypes()
T = table(int8 ([1, 2, 3]'), ...
int16 ([1, 2, 3]'), ...
int32 ([1, 2, 3]'), ...
int64 ([1, 2, 3]'), ...
uint8 ([1, 2, 3]'), ...
uint16 ([1, 2, 3]'), ...
uint32 ([1, 2, 3]'), ...
uint64 ([1, 2, 3]'), ...
logical([1, 0, 1]'), ...
single ([1, 2, 3]'), ...
double ([1, 2, 3]'), ...
string (["A", "B", "C"]'), ...
datetime(2023, 6, 28) + days(0:2)');
end
64 changes: 45 additions & 19 deletions matlab/test/tfeather.m
Original file line number Diff line number Diff line change
Expand Up @@ -39,28 +39,34 @@ function setupTempWorkingDirectory(testCase)
methods(Test)

function NumericDatatypesNoNulls(testCase)
import arrow.internal.test.tabular.createTableWithSupportedTypes
filename = fullfile(pwd, 'temp.feather');

actualTable = createTable;
actualTable = createTableWithSupportedTypes;
expectedTable = featherRoundTrip(filename, actualTable);
testCase.verifyEqual(actualTable, expectedTable);
end

function NumericDatatypesWithNaNRow(testCase)
import arrow.internal.test.tabular.createTableWithSupportedTypes

filename = fullfile(pwd, 'temp.feather');

t = createTable;
t = createTableWithSupportedTypes;
t = removevars(t, ["logical", "string", "datetime"]);

variableNames = {'single', ...
'double', ...
variableNames = {'uint8', ...
'uint16', ...
'uint32', ...
'uint64', ...
'int8', ...
'int16', ...
'int32', ...
'int64', ...
'uint8', ...
'uint16', ...
'uint32', ...
'uint64'};
'single', ...
'double', ...
};

variableTypes = repmat({'double'}, 10, 1)';
numRows = 1;
numVariables = 10;
Expand All @@ -75,9 +81,11 @@ function NumericDatatypesWithNaNRow(testCase)
end

function NumericDatatypesWithNaNColumns(testCase)
import arrow.internal.test.tabular.createTableWithSupportedTypes

filename = fullfile(pwd, 'temp.feather');

actualTable = createTable;
actualTable = createTableWithSupportedTypes;
actualTable.double = [NaN; NaN; NaN];
actualTable.int64 = [NaN; NaN; NaN];

Expand All @@ -86,9 +94,11 @@ function NumericDatatypesWithNaNColumns(testCase)
end

function NumericDatatypesWithExpInfSciNotation(testCase)
import arrow.internal.test.tabular.createTableWithSupportedTypes

filename = fullfile(pwd, 'temp.feather');

actualTable = createTable;
actualTable = createTableWithSupportedTypes;
actualTable.single(2) = 1.0418e+06;

actualTable.double(1) = Inf;
Expand All @@ -101,20 +111,24 @@ function NumericDatatypesWithExpInfSciNotation(testCase)
end

function IgnoreRowVarNames(testCase)
import arrow.internal.test.tabular.createTableWithSupportedTypes

filename = fullfile(pwd, 'temp.feather');

actualTable = createTable;
actualTable = createTableWithSupportedTypes;
time = {'day1', 'day2', 'day3'};
actualTable.Properties.RowNames = time;
expectedTable = featherRoundTrip(filename, actualTable);
actualTable = createTable;
actualTable = createTableWithSupportedTypes;
testCase.verifyEqual(actualTable, expectedTable);
end

function NotFeatherExtension(testCase)
import arrow.internal.test.tabular.createTableWithSupportedTypes

filename = fullfile(pwd, 'temp.txt');

actualTable = createTable;
actualTable = createTableWithSupportedTypes;
expectedTable = featherRoundTrip(filename, actualTable);
testCase.verifyEqual(actualTable, expectedTable);
end
Expand All @@ -128,9 +142,11 @@ function EmptyTable(testCase)
end

function zeroByNTable(testCase)
import arrow.internal.test.tabular.createTableWithSupportedTypes

filename = fullfile(pwd, 'temp.feather');

actualTable = createTable;
actualTable = createTableWithSupportedTypes;
actualTable([1, 2], :) = [];
expectedTable = featherRoundTrip(filename, actualTable);
testCase.verifyEqual(actualTable, expectedTable);
Expand All @@ -147,9 +163,11 @@ function ErrorIfUnableToOpenFile(testCase)
end

function ErrorIfCorruptedFeatherFile(testCase)
import arrow.internal.test.tabular.createTableWithSupportedTypes

filename = fullfile(pwd, 'temp.feather');

t = createTable;
t = createTableWithSupportedTypes;
featherwrite(filename, t);

fileID = fopen(filename, 'w');
Expand All @@ -160,15 +178,19 @@ function ErrorIfCorruptedFeatherFile(testCase)
end

function ErrorIfInvalidFilenameDatatype(testCase)
t = createTable;
import arrow.internal.test.tabular.createTableWithSupportedTypes

t = createTableWithSupportedTypes;

testCase.verifyError(@() featherwrite({table}, t), 'MATLAB:validation:UnableToConvert');
end

function ErrorIfTooManyInputs(testCase)
import arrow.internal.test.tabular.createTableWithSupportedTypes

filename = fullfile(pwd, 'temp.feather');

t = createTable;
t = createTableWithSupportedTypes;

testCase.verifyError(@() featherwrite(filename, t, 'SomeValue', 'SomeOtherValue'), 'MATLAB:TooManyInputs');
testCase.verifyError(@() featherread(filename, 'SomeValue', 'SomeOtherValue'), 'MATLAB:TooManyInputs');
Expand All @@ -194,9 +216,11 @@ function ErrorIfMultiColVarExist(testCase)
end

function UnsupportedMATLABDatatypes(testCase)
import arrow.internal.test.tabular.createTableWithSupportedTypes

filename = fullfile(pwd, 'temp.feather');

actualTable = createTable;
actualTable = createTableWithSupportedTypes;
calendarDurationVariable = [calendarDuration(1, 7, 9); ...
calendarDuration(2, 1, 1); ...
calendarDuration(5, 3, 2)];
Expand All @@ -206,9 +230,11 @@ function UnsupportedMATLABDatatypes(testCase)
end

function NumericComplexUnsupported(testCase)
import arrow.internal.test.tabular.createTableWithSupportedTypes

filename = fullfile(pwd, 'temp.feather');

actualTable = createTable;
actualTable = createTableWithSupportedTypes;
actualTable.single(1) = 1.0418 + 2i;
actualTable.double(2) = exp(9) + 5i;
actualTable.int64(2) = 1.0418e+03;
Expand Down
68 changes: 0 additions & 68 deletions matlab/test/util/createTable.m

This file was deleted.

0 comments on commit 01a9f72

Please sign in to comment.