You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by ke...@apache.org on 2023/09/06 20:33:26 UTC
[arrow] branch main updated: GH-37591: [MATLAB] Make `arrow.type.Type` inherit from `matlab.mixin.Heterogeneous` (#37593)
This is an automated email from the ASF dual-hosted git repository.
kevingurney pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git
The following commit(s) were added to refs/heads/main by this push:
new f7b6ddbe87 GH-37591: [MATLAB] Make `arrow.type.Type` inherit from `matlab.mixin.Heterogeneous` (#37593)
f7b6ddbe87 is described below
commit f7b6ddbe8787fe62f5bde5cf9e686380c60adc40
Author: sgilmore10 <74...@users.noreply.github.com>
AuthorDate: Wed Sep 6 16:33:07 2023 -0400
GH-37591: [MATLAB] Make `arrow.type.Type` inherit from `matlab.mixin.Heterogeneous` (#37593)
### Rationale for this change
We should modify `arrow.type.Type` to inherit from `matlab.mixin.Heterogeneous` so that it's possible to create a nonscalar array containing different concrete subclasses of `arrow.type.Type`.
**Example**
```matlab
>> float32Type = arrow.float32();
>> timestampType = arrow.timestamp(TimeZone="Pacific/Fiji");
>> typeArray = [float32Type timestampType]
typeArray =
1×2 heterogeneous FixedWidthType (Float32Type, TimestampType) array with properties:
ID
```
Currently, running the example above results in an error:
```matlab
>> float32Type = arrow.float32();
>> timestampType = arrow.timestamp(TimeZone="Pacific/Fiji");
>> typeArray = [float32Type timestampType]
Error using horzcat
The following error occurred converting from arrow.type.TimestampType to arrow.type.Float32Type:
Invalid argument at position 1. Value must be of type libmexclass.proxy.Proxy or be convertible to libmexclass.proxy.Proxy.
```
### What changes are included in this PR?
1. Updated `arrow.type.Type` to inherit from `matlab.mixin.Heterogeneous`. Previously, it only inherited from `matlab.mixin.CustomDisplay`.
2. Because `arrow.type.Type` is now `heterogeneous`, its subclasses cannot override the protected method `getPropertyGroups` - which is inherited from `matlab.mixin.CustomDisplay`. This method must be `Sealed` and defined on `Type` because only `Sealed` methods can be called on nonscalar `heterogeneous` arrays. To get around this limitation, I defined a new abstract template method called `getDisplayPropertyGroups`, which `getPropertyGroups` invokes if the array is either scalar or no [...]
**Displaying a nonscalar *heterogeneous* `arrow.type.Type`**
```matlab
>> float32Type = arrow.timestamp(TimeUnit="Second");
>> timestampType = arrow.timestamp(TimeZone="Pacific/Fiji");
>> typeArray = [float32Type timestampType]
typeArray =
1×2 heterogeneous FixedWidthType (Float32Type, TimestampType) array with properties:
ID
```
**Displaying a nonscalar *homogeneous* `arrow.type.Type`**
```matlab
>> timestampType1 = arrow.timestamp(TimeUnit="Second");
>> timestampType2 = arrow.timestamp(TimeZone="Pacific/Fiji");
>> typeArray = [timestampType1 timestampType2]
typeArray =
1×2 TimestampType array with properties:
ID
TimeUnit
TimeZone
```
### Are these changes tested?
Yes
1. Added a new test class in `test/arrow/type` called `tDisplay.m`
2. Added display unit tests for all concrete subclasses of `arrow.type.Type` if they did not already exist.
3. Added a new test class in `test/arrow/type` called `tIsEqual.m`. This class contains unit tests verifying the `isequal` method of `arrow.type.Type` behaves as expected when called on heterogeneous arrays.
### Are there any user-facing changes?
Yes. Users can now create nonscalar arrays with different concrete subclasses of `arrow.type.Type`.
### Future Directions
1. Move all display unit tests to `tDisplay.m`
2. Add an `arrow.type.NumericType` class from which all numeric types inherit. This class will define `getDisplayPropertyGroups` for all numeric types.
* Closes: #37591
Authored-by: Sarah Gilmore <sg...@mathworks.com>
Signed-off-by: Kevin Gurney <kg...@mathworks.com>
---
matlab/src/matlab/+arrow/+type/BooleanType.m | 7 +
matlab/src/matlab/+arrow/+type/DateType.m | 4 +-
matlab/src/matlab/+arrow/+type/Float32Type.m | 7 +
matlab/src/matlab/+arrow/+type/Float64Type.m | 7 +
matlab/src/matlab/+arrow/+type/Int16Type.m | 7 +
matlab/src/matlab/+arrow/+type/Int32Type.m | 7 +
matlab/src/matlab/+arrow/+type/Int64Type.m | 7 +
matlab/src/matlab/+arrow/+type/Int8Type.m | 7 +
matlab/src/matlab/+arrow/+type/StringType.m | 9 +-
matlab/src/matlab/+arrow/+type/TimeType.m | 4 +-
matlab/src/matlab/+arrow/+type/TimestampType.m | 6 +-
matlab/src/matlab/+arrow/+type/Type.m | 56 +++++-
matlab/src/matlab/+arrow/+type/UInt16Type.m | 8 +
matlab/src/matlab/+arrow/+type/UInt32Type.m | 8 +
matlab/src/matlab/+arrow/+type/UInt64Type.m | 7 +
matlab/src/matlab/+arrow/+type/UInt8Type.m | 7 +
matlab/test/arrow/type/tDate32Type.m | 22 ---
matlab/test/arrow/type/tDate64Type.m | 22 ---
matlab/test/arrow/type/tIsEqual.m | 52 +++++
matlab/test/arrow/type/tTime32Type.m | 22 ---
matlab/test/arrow/type/tTime64Type.m | 22 ---
matlab/test/arrow/type/tTimestampType.m | 23 ---
matlab/test/arrow/type/tTypeDisplay.m | 256 +++++++++++++++++++++++++
23 files changed, 452 insertions(+), 125 deletions(-)
diff --git a/matlab/src/matlab/+arrow/+type/BooleanType.m b/matlab/src/matlab/+arrow/+type/BooleanType.m
index 6afa00e925..197ab51583 100644
--- a/matlab/src/matlab/+arrow/+type/BooleanType.m
+++ b/matlab/src/matlab/+arrow/+type/BooleanType.m
@@ -25,4 +25,11 @@ classdef BooleanType < arrow.type.FixedWidthType
obj@arrow.type.FixedWidthType(proxy);
end
end
+
+ methods (Access=protected)
+ function groups = getDisplayPropertyGroups(~)
+ targets = "ID";
+ groups = matlab.mixin.util.PropertyGroup(targets);
+ end
+ end
end
\ No newline at end of file
diff --git a/matlab/src/matlab/+arrow/+type/DateType.m b/matlab/src/matlab/+arrow/+type/DateType.m
index f8a3966602..ac6ece47ce 100644
--- a/matlab/src/matlab/+arrow/+type/DateType.m
+++ b/matlab/src/matlab/+arrow/+type/DateType.m
@@ -36,9 +36,9 @@ classdef DateType < arrow.type.TemporalType
end
methods (Access=protected)
- function group = getPropertyGroups(~)
+ function groups = getDisplayPropertyGroups(~)
targets = ["ID" "DateUnit"];
- group = matlab.mixin.util.PropertyGroup(targets);
+ groups = matlab.mixin.util.PropertyGroup(targets);
end
end
diff --git a/matlab/src/matlab/+arrow/+type/Float32Type.m b/matlab/src/matlab/+arrow/+type/Float32Type.m
index df5fa1ce84..98c9f5fd79 100644
--- a/matlab/src/matlab/+arrow/+type/Float32Type.m
+++ b/matlab/src/matlab/+arrow/+type/Float32Type.m
@@ -25,4 +25,11 @@ classdef Float32Type < arrow.type.FixedWidthType
obj@arrow.type.FixedWidthType(proxy);
end
end
+
+ methods (Access=protected)
+ function groups = getDisplayPropertyGroups(~)
+ targets = "ID";
+ groups = matlab.mixin.util.PropertyGroup(targets);
+ end
+ end
end
\ No newline at end of file
diff --git a/matlab/src/matlab/+arrow/+type/Float64Type.m b/matlab/src/matlab/+arrow/+type/Float64Type.m
index ba93265ebc..634e7d1a5c 100644
--- a/matlab/src/matlab/+arrow/+type/Float64Type.m
+++ b/matlab/src/matlab/+arrow/+type/Float64Type.m
@@ -25,4 +25,11 @@ classdef Float64Type < arrow.type.FixedWidthType
obj@arrow.type.FixedWidthType(proxy);
end
end
+
+ methods (Access=protected)
+ function groups = getDisplayPropertyGroups(~)
+ targets = "ID";
+ groups = matlab.mixin.util.PropertyGroup(targets);
+ end
+ end
end
\ No newline at end of file
diff --git a/matlab/src/matlab/+arrow/+type/Int16Type.m b/matlab/src/matlab/+arrow/+type/Int16Type.m
index c16d3fd5ca..ca59f1c077 100644
--- a/matlab/src/matlab/+arrow/+type/Int16Type.m
+++ b/matlab/src/matlab/+arrow/+type/Int16Type.m
@@ -25,5 +25,12 @@ classdef Int16Type < arrow.type.FixedWidthType
obj@arrow.type.FixedWidthType(proxy);
end
end
+
+ methods (Access=protected)
+ function groups = getDisplayPropertyGroups(~)
+ targets = "ID";
+ groups = matlab.mixin.util.PropertyGroup(targets);
+ end
+ end
end
diff --git a/matlab/src/matlab/+arrow/+type/Int32Type.m b/matlab/src/matlab/+arrow/+type/Int32Type.m
index 786697bf11..68036d6485 100644
--- a/matlab/src/matlab/+arrow/+type/Int32Type.m
+++ b/matlab/src/matlab/+arrow/+type/Int32Type.m
@@ -25,5 +25,12 @@ classdef Int32Type < arrow.type.FixedWidthType
obj@arrow.type.FixedWidthType(proxy);
end
end
+
+ methods (Access=protected)
+ function groups = getDisplayPropertyGroups(~)
+ targets = "ID";
+ groups = matlab.mixin.util.PropertyGroup(targets);
+ end
+ end
end
diff --git a/matlab/src/matlab/+arrow/+type/Int64Type.m b/matlab/src/matlab/+arrow/+type/Int64Type.m
index bf6c71d622..d5bd7ff3a5 100644
--- a/matlab/src/matlab/+arrow/+type/Int64Type.m
+++ b/matlab/src/matlab/+arrow/+type/Int64Type.m
@@ -25,4 +25,11 @@ classdef Int64Type < arrow.type.FixedWidthType
obj@arrow.type.FixedWidthType(proxy);
end
end
+
+ methods (Access=protected)
+ function groups = getDisplayPropertyGroups(~)
+ targets = "ID";
+ groups = matlab.mixin.util.PropertyGroup(targets);
+ end
+ end
end
\ No newline at end of file
diff --git a/matlab/src/matlab/+arrow/+type/Int8Type.m b/matlab/src/matlab/+arrow/+type/Int8Type.m
index b28785f876..5df75afe76 100644
--- a/matlab/src/matlab/+arrow/+type/Int8Type.m
+++ b/matlab/src/matlab/+arrow/+type/Int8Type.m
@@ -25,5 +25,12 @@ classdef Int8Type < arrow.type.FixedWidthType
obj@arrow.type.FixedWidthType(proxy);
end
end
+
+ methods (Access=protected)
+ function groups = getDisplayPropertyGroups(~)
+ targets = "ID";
+ groups = matlab.mixin.util.PropertyGroup(targets);
+ end
+ end
end
diff --git a/matlab/src/matlab/+arrow/+type/StringType.m b/matlab/src/matlab/+arrow/+type/StringType.m
index c269bfa6db..53c73b3e33 100644
--- a/matlab/src/matlab/+arrow/+type/StringType.m
+++ b/matlab/src/matlab/+arrow/+type/StringType.m
@@ -24,6 +24,13 @@ classdef StringType < arrow.type.Type
import arrow.internal.proxy.validate
obj@arrow.type.Type(proxy);
end
- end
+ end
+
+ methods (Access=protected)
+ function groups = getDisplayPropertyGroups(~)
+ targets = "ID";
+ groups = matlab.mixin.util.PropertyGroup(targets);
+ end
+ end
end
diff --git a/matlab/src/matlab/+arrow/+type/TimeType.m b/matlab/src/matlab/+arrow/+type/TimeType.m
index 59d9387889..a0f8beb704 100644
--- a/matlab/src/matlab/+arrow/+type/TimeType.m
+++ b/matlab/src/matlab/+arrow/+type/TimeType.m
@@ -36,9 +36,9 @@ classdef TimeType < arrow.type.TemporalType
end
methods (Access=protected)
- function group = getPropertyGroups(~)
+ function groups = getDisplayPropertyGroups(~)
targets = ["ID" "TimeUnit"];
- group = matlab.mixin.util.PropertyGroup(targets);
+ groups = matlab.mixin.util.PropertyGroup(targets);
end
end
diff --git a/matlab/src/matlab/+arrow/+type/TimestampType.m b/matlab/src/matlab/+arrow/+type/TimestampType.m
index cb47743148..07e61f9570 100644
--- a/matlab/src/matlab/+arrow/+type/TimestampType.m
+++ b/matlab/src/matlab/+arrow/+type/TimestampType.m
@@ -42,9 +42,9 @@ classdef TimestampType < arrow.type.TemporalType
end
methods (Access=protected)
- function group = getPropertyGroups(~)
- targets = ["ID" "TimeUnit" "TimeZone"];
- group = matlab.mixin.util.PropertyGroup(targets);
+ function groups = getDisplayPropertyGroups(~)
+ targets = ["ID" "TimeUnit" "TimeZone"];
+ groups = matlab.mixin.util.PropertyGroup(targets);
end
end
end
\ No newline at end of file
diff --git a/matlab/src/matlab/+arrow/+type/Type.m b/matlab/src/matlab/+arrow/+type/Type.m
index cc2da1403b..8f4ce4dd6c 100644
--- a/matlab/src/matlab/+arrow/+type/Type.m
+++ b/matlab/src/matlab/+arrow/+type/Type.m
@@ -13,7 +13,8 @@
% implied. See the License for the specific language governing
% permissions and limitations under the License.
-classdef (Abstract) Type < matlab.mixin.CustomDisplay
+classdef (Abstract) Type < matlab.mixin.CustomDisplay & ...
+ matlab.mixin.Heterogeneous
%TYPE Abstract type class.
properties (Dependent, GetAccess=public, SetAccess=private)
@@ -42,14 +43,57 @@ classdef (Abstract) Type < matlab.mixin.CustomDisplay
end
end
- methods (Access=protected)
- function propgrp = getPropertyGroups(~)
- proplist = {'ID'};
- propgrp = matlab.mixin.util.PropertyGroup(proplist);
+ methods(Access = protected)
+ groups = getDisplayPropertyGroups(obj)
+ end
+
+ methods (Sealed, Access = protected)
+ function header = getHeader(obj)
+ header = getHeader@matlab.mixin.CustomDisplay(obj);
+ end
+
+ function groups = getPropertyGroups(obj)
+ if isscalar(obj)
+ groups = getDisplayPropertyGroups(obj);
+ else
+ % Check if every type in the array has the same class type.
+ % If so, call getDisplayPropertyGroups() so that all
+ % properties assoicated with that class are displayed.
+ classnames = arrayfun(@(type) string(class(type)), obj);
+ if numel(unique(classnames)) == 1
+ groups = getDisplayPropertyGroups(obj(1));
+ else
+ % If the array is heterogeneous, just display ID, which
+ % is the only property shared by all concrete
+ % subclasses of arrow.type.Type.
+ proplist = "ID";
+ groups = matlab.mixin.util.PropertyGroup(proplist);
+ end
+ end
+ end
+
+ function footer = getFooter(obj)
+ footer = getFooter@matlab.mixin.CustomDisplay(obj);
+ end
+
+ function displayNonScalarObject(obj)
+ displayNonScalarObject@matlab.mixin.CustomDisplay(obj);
+ end
+
+ function displayScalarObject(obj)
+ displayScalarObject@matlab.mixin.CustomDisplay(obj)
+ end
+
+ function displayEmptyObject(obj)
+ displayEmptyObject@matlab.mixin.CustomDisplay(obj);
+ end
+
+ function displayScalarHandleToDeletedObject(obj)
+ displayScalarHandleToDeletedObject@matlab.mixin.CustomDisplay(obj);
end
end
- methods
+ methods (Sealed)
function tf = isequal(obj, varargin)
narginchk(2, inf);
diff --git a/matlab/src/matlab/+arrow/+type/UInt16Type.m b/matlab/src/matlab/+arrow/+type/UInt16Type.m
index 3198b78671..d7600c982b 100644
--- a/matlab/src/matlab/+arrow/+type/UInt16Type.m
+++ b/matlab/src/matlab/+arrow/+type/UInt16Type.m
@@ -25,4 +25,12 @@ classdef UInt16Type < arrow.type.FixedWidthType
obj@arrow.type.FixedWidthType(proxy);
end
end
+
+
+ methods (Access=protected)
+ function groups = getDisplayPropertyGroups(~)
+ targets = "ID";
+ groups = matlab.mixin.util.PropertyGroup(targets);
+ end
+ end
end
\ No newline at end of file
diff --git a/matlab/src/matlab/+arrow/+type/UInt32Type.m b/matlab/src/matlab/+arrow/+type/UInt32Type.m
index 53e60e4e34..e16699cba5 100644
--- a/matlab/src/matlab/+arrow/+type/UInt32Type.m
+++ b/matlab/src/matlab/+arrow/+type/UInt32Type.m
@@ -25,4 +25,12 @@ classdef UInt32Type < arrow.type.FixedWidthType
obj@arrow.type.FixedWidthType(proxy);
end
end
+
+
+ methods (Access=protected)
+ function groups = getDisplayPropertyGroups(~)
+ targets = "ID";
+ groups = matlab.mixin.util.PropertyGroup(targets);
+ end
+ end
end
\ No newline at end of file
diff --git a/matlab/src/matlab/+arrow/+type/UInt64Type.m b/matlab/src/matlab/+arrow/+type/UInt64Type.m
index f8512ec594..c190f252ab 100644
--- a/matlab/src/matlab/+arrow/+type/UInt64Type.m
+++ b/matlab/src/matlab/+arrow/+type/UInt64Type.m
@@ -25,4 +25,11 @@ classdef UInt64Type < arrow.type.FixedWidthType
obj@arrow.type.FixedWidthType(proxy);
end
end
+
+ methods (Access=protected)
+ function groups = getDisplayPropertyGroups(~)
+ targets = "ID";
+ groups = matlab.mixin.util.PropertyGroup(targets);
+ end
+ end
end
\ No newline at end of file
diff --git a/matlab/src/matlab/+arrow/+type/UInt8Type.m b/matlab/src/matlab/+arrow/+type/UInt8Type.m
index 898426e3a4..89715991ed 100644
--- a/matlab/src/matlab/+arrow/+type/UInt8Type.m
+++ b/matlab/src/matlab/+arrow/+type/UInt8Type.m
@@ -25,4 +25,11 @@ classdef UInt8Type < arrow.type.FixedWidthType
obj@arrow.type.FixedWidthType(proxy);
end
end
+
+ methods (Access=protected)
+ function groups = getDisplayPropertyGroups(~)
+ targets = "ID";
+ groups = matlab.mixin.util.PropertyGroup(targets);
+ end
+ end
end
\ No newline at end of file
diff --git a/matlab/test/arrow/type/tDate32Type.m b/matlab/test/arrow/type/tDate32Type.m
index 71a9e5cf48..c486772c45 100644
--- a/matlab/test/arrow/type/tDate32Type.m
+++ b/matlab/test/arrow/type/tDate32Type.m
@@ -40,28 +40,6 @@ classdef tDate32Type < hFixedWidthType
testCase.verifyEqual(actualUnit, expectedUnit);
end
- function Display(testCase)
- % Verify the display of Date32Type objects.
- %
- % Example:
- %
- % Date32Type with properties:
- %
- % ID: Date32
- % DateUnit: Day
- %
- type = testCase.ConstructionFcn(); %#ok<NASGU>
- classnameLink = "<a href=""matlab:helpPopup arrow.type.Date32Type"" style=""font-weight:bold"">Date32Type</a>";
- header = " " + classnameLink + " with properties:" + newline;
- body = strjust(pad(["ID:"; "DateUnit:"]));
- body = body + " " + ["Date32"; "Day"];
- body = " " + body;
- footer = string(newline);
- expectedDisplay = char(strjoin([header body' footer], newline));
- actualDisplay = evalc('disp(type)');
- testCase.verifyEqual(actualDisplay, expectedDisplay);
- end
-
function DateUnitNoSetter(testCase)
% Verify that an error is thrown when trying to set the value
% of the DateUnit property.
diff --git a/matlab/test/arrow/type/tDate64Type.m b/matlab/test/arrow/type/tDate64Type.m
index 9345f6dbde..b9e9c3637e 100644
--- a/matlab/test/arrow/type/tDate64Type.m
+++ b/matlab/test/arrow/type/tDate64Type.m
@@ -40,28 +40,6 @@ classdef tDate64Type < hFixedWidthType
testCase.verifyEqual(actualUnit, expectedUnit);
end
- function Display(testCase)
- % Verify the display of Date64Type objects.
- %
- % Example:
- %
- % Date32Type with properties:
- %
- % ID: Date64
- % DateUnit: Millisecond
- %
- type = testCase.ConstructionFcn(); %#ok<NASGU>
- classnameLink = "<a href=""matlab:helpPopup arrow.type.Date64Type"" style=""font-weight:bold"">Date64Type</a>";
- header = " " + classnameLink + " with properties:" + newline;
- body = strjust(pad(["ID:"; "DateUnit:"]));
- body = body + " " + ["Date64"; "Millisecond"];
- body = " " + body;
- footer = string(newline);
- expectedDisplay = char(strjoin([header body' footer], newline));
- actualDisplay = evalc('disp(type)');
- testCase.verifyEqual(actualDisplay, expectedDisplay);
- end
-
function DateUnitNoSetter(testCase)
% Verify that an error is thrown when trying to set the value
% of the DateUnit property.
diff --git a/matlab/test/arrow/type/tIsEqual.m b/matlab/test/arrow/type/tIsEqual.m
new file mode 100644
index 0000000000..babb08a04e
--- /dev/null
+++ b/matlab/test/arrow/type/tIsEqual.m
@@ -0,0 +1,52 @@
+%TISEQUAL Verifies the behavior of arrow.type.Type's isequal method on
+%nonscalar heterogeneous 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.
+
+classdef tIsEqual < matlab.unittest.TestCase
+
+ methods (Test)
+ % Test methods
+
+ function IsEqualTrue(testCase)
+ float32Type = arrow.float32();
+ timestampType = arrow.timestamp(TimeUnit="Second");
+ typeArray = [float32Type, timestampType];
+ testCase.verifyTrue(isequal(typeArray, typeArray));
+ end
+
+ function IsEqualFalse(testCase)
+ float32Type = arrow.float32();
+ timestampType1 = arrow.timestamp(TimeUnit="Second");
+ typeArray1 = [float32Type, timestampType1];
+
+ % Their dimensions are not equal
+ testCase.verifyFalse(isequal(typeArray1, typeArray1'));
+
+ % Corresponding elements are not equal
+ timestampType2 = arrow.timestamp(TimeUnit="Millisecond");
+ typeArray2 = [float32Type, timestampType2];
+ testCase.verifyFalse(isequal(typeArray1, typeArray2));
+
+ % Corresponding elements have different class types
+ stringType = arrow.string();
+ typeArray3 = [float32Type, stringType];
+ testCase.verifyFalse(isequal(typeArray1, typeArray3));
+ end
+
+ end
+
+end
\ No newline at end of file
diff --git a/matlab/test/arrow/type/tTime32Type.m b/matlab/test/arrow/type/tTime32Type.m
index 0bb467b1ba..86615312a1 100644
--- a/matlab/test/arrow/type/tTime32Type.m
+++ b/matlab/test/arrow/type/tTime32Type.m
@@ -82,28 +82,6 @@ classdef tTime32Type < hFixedWidthType
testCase.verifyError(fcn, "MATLAB:validation:IncompatibleSize");
end
- function Display(testCase)
- % Verify the display of Time32Type objects.
- %
- % Example:
- %
- % Time32Type with properties:
- %
- % ID: Time32
- % TimeUnit: Second
- %
- type = testCase.ConstructionFcn(TimeUnit="Second"); %#ok<NASGU>
- classnameLink = "<a href=""matlab:helpPopup arrow.type.Time32Type"" style=""font-weight:bold"">Time32Type</a>";
- header = " " + classnameLink + " with properties:" + newline;
- body = strjust(pad(["ID:"; "TimeUnit:"]));
- body = body + " " + ["Time32"; "Second"];
- body = " " + body;
- footer = string(newline);
- expectedDisplay = char(strjoin([header body' footer], newline));
- actualDisplay = evalc('disp(type)');
- testCase.verifyEqual(actualDisplay, expectedDisplay);
- end
-
function TimeUnitNoSetter(testCase)
% Verify that an error is thrown when trying to set the value
% of the TimeUnit property.
diff --git a/matlab/test/arrow/type/tTime64Type.m b/matlab/test/arrow/type/tTime64Type.m
index 01460d9c1b..a698081990 100644
--- a/matlab/test/arrow/type/tTime64Type.m
+++ b/matlab/test/arrow/type/tTime64Type.m
@@ -83,28 +83,6 @@ classdef tTime64Type < hFixedWidthType
testCase.verifyError(fcn, "MATLAB:validation:IncompatibleSize");
end
- function Display(testCase)
- % Verify the display of Time64Type objects.
- %
- % Example:
- %
- % Time64Type with properties:
- %
- % ID: Time64
- % TimeUnit: Microsecond
- %
- type = testCase.ConstructionFcn(TimeUnit="Microsecond"); %#ok<NASGU>
- classnameLink = "<a href=""matlab:helpPopup arrow.type.Time64Type"" style=""font-weight:bold"">Time64Type</a>";
- header = " " + classnameLink + " with properties:" + newline;
- body = strjust(pad(["ID:"; "TimeUnit:"]));
- body = body + " " + ["Time64"; "Microsecond"];
- body = " " + body;
- footer = string(newline);
- expectedDisplay = char(strjoin([header body' footer], newline));
- actualDisplay = evalc('disp(type)');
- testCase.verifyEqual(actualDisplay, expectedDisplay);
- end
-
function TimeUnitNoSetter(testCase)
% Verify that an error is thrown when trying to set the value
% of the TimeUnit property.
diff --git a/matlab/test/arrow/type/tTimestampType.m b/matlab/test/arrow/type/tTimestampType.m
index 6a626ebde7..1266faff4a 100644
--- a/matlab/test/arrow/type/tTimestampType.m
+++ b/matlab/test/arrow/type/tTimestampType.m
@@ -112,29 +112,6 @@ classdef tTimestampType < hFixedWidthType
testCase.verifyError(fcn, "MATLAB:validation:IncompatibleSize");
end
- function Display(testCase)
- % Verify the display of TimestampType objects.
- %
- % Example:
- %
- % TimestampType with properties:
- %
- % ID: Timestamp
- % TimeUnit: Second
- % TimeZone: "America/Anchorage"
- %
- type = arrow.timestamp(TimeUnit="Second", TimeZone="America/Anchorage"); %#ok<NASGU>
- classnameLink = "<a href=""matlab:helpPopup arrow.type.TimestampType"" style=""font-weight:bold"">TimestampType</a>";
- header = " " + classnameLink + " with properties:" + newline;
- body = strjust(pad(["ID:"; "TimeUnit:"; "TimeZone:"]));
- body = body + " " + ["Timestamp"; "Second"; """America/Anchorage"""];
- body = " " + body;
- footer = string(newline);
- expectedDisplay = char(strjoin([header body' footer], newline));
- actualDisplay = evalc('disp(type)');
- testCase.verifyEqual(actualDisplay, expectedDisplay);
- end
-
function IsEqualTrue(testCase, TimeZone)
% Verifies isequal method of arrow.type.TimestampType returns
% true if these conditions are met:
diff --git a/matlab/test/arrow/type/tTypeDisplay.m b/matlab/test/arrow/type/tTypeDisplay.m
new file mode 100644
index 0000000000..4d3c023da7
--- /dev/null
+++ b/matlab/test/arrow/type/tTypeDisplay.m
@@ -0,0 +1,256 @@
+%TTYPEDISPLAY Unit tests verifying the display of all classes within the
+%arrow.type.Type class hierarchy.
+
+% 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.
+
+classdef tTypeDisplay < matlab.unittest.TestCase
+
+ properties(TestParameter)
+ TypeDisplaysOnlyID = {arrow.boolean(), ...
+ arrow.uint8(), ...
+ arrow.uint16(), ...
+ arrow.uint32(), ...
+ arrow.uint64(), ...
+ arrow.int8(), ...
+ arrow.int16(), ...
+ arrow.int32(), ...
+ arrow.int64(), ...
+ arrow.float32(), ...
+ arrow.float64(), ...
+ arrow.float64(), ...
+ arrow.string()}
+
+ TimeType = {arrow.time32(TimeUnit="Second"), ...
+ arrow.time64(TimeUnit="Nanosecond")};
+
+ DateType = {arrow.date32(), ...
+ arrow.date64()};
+ end
+
+ methods (Test)
+ function EmptyTypeDisplay(testCase)
+ % Verify the display of an empty arrow.type.Type instance.
+ %
+ % Example:
+ %
+ % 0x1 Type array with properties:
+ %
+ % ID
+
+ type = arrow.type.Type.empty(0, 1);
+ typeLink = makeLinkString(FullClassName="arrow.type.Type", ClassName="Type", BoldFont=true);
+ dimensionString = makeDimensionString(size(type));
+ header = " " + dimensionString + " " + typeLink + " array with properties:" + newline;
+ body = strjust(pad("ID"));
+ body = " " + body;
+ footer = string(newline);
+ expectedDisplay = char(strjoin([header body' footer], newline));
+ actualDisplay = evalc('disp(type)');
+ testCase.verifyDisplay(actualDisplay, expectedDisplay);
+ end
+
+ function NonScalarArrayDifferentTypes(testCase)
+ % Verify the display of a nonscalar, heterogeneous arrow.type.Type array:
+ %
+ % Example:
+ %
+ % 1×2 heterogeneous FixedWidthType (Float32Type, TimestampType) array with properties:
+ %
+ % ID
+
+ float32Type = arrow.float32();
+ timestampType = arrow.timestamp();
+ typeArray = [float32Type timestampType];
+
+ heterogeneousLink = makeLinkString(FullClassName="matlab.mixin.Heterogeneous", ClassName="heterogeneous", BoldFont=false);
+ fixedWidthLink = makeLinkString(FullClassName="arrow.type.FixedWidthType", ClassName="FixedWidthType", BoldFont=true);
+ timestampLink = makeLinkString(FullClassName="arrow.type.TimestampType", ClassName="TimestampType", BoldFont=false);
+ float32Link = makeLinkString(FullClassName="arrow.type.Float32Type", ClassName="Float32Type", BoldFont=false);
+
+ dimensionString = makeDimensionString(size(typeArray));
+
+ header = " " + dimensionString + " " + heterogeneousLink + " " + fixedWidthLink + ...
+ " (" + float32Link + ", " + timestampLink + ") array with properties:" + newline;
+ body = " " + "ID";
+ footer = string(newline);
+ expectedDisplay = char(strjoin([header body' footer], newline));
+ actualDisplay = evalc('disp(typeArray)');
+ testCase.verifyDisplay(actualDisplay, expectedDisplay);
+ end
+
+ function NonScalarArraySameTypes(testCase)
+ % Verify the display of a scalar, homogeneous arrow.type.Type array:
+ %
+ % Example:
+ %
+ % 1×2 TimestampType array with properties:
+ %
+ % ID
+ % TimeUnit
+ % TimeZone
+
+ timestampType1 = arrow.timestamp(TimeZone="Pacific/Fiji");
+ timestampType2 = arrow.timestamp(TimeUnit="Second");
+ typeArray = [timestampType1 timestampType2];
+
+ timestampLink = makeLinkString(FullClassName="arrow.type.TimestampType", ClassName="TimestampType", BoldFont=true);
+ dimensionString = makeDimensionString(size(typeArray));
+ header = " " + dimensionString + " " + timestampLink + " array with properties:" + newline;
+ body = strjust(["ID"; "TimeUnit"; "TimeZone"], "left");
+ body = " " + body;
+ footer = string(newline);
+ expectedDisplay = char(strjoin([header body' footer], newline));
+ actualDisplay = evalc('disp(typeArray)');
+ testCase.verifyDisplay(actualDisplay, expectedDisplay);
+ end
+
+ function TestTypeDisplaysOnlyID(testCase, TypeDisplaysOnlyID)
+ % Verify the display of arrow.type.Type subclasses that only
+ % display the ID property.
+ %
+ % Example:
+ %
+ % BooleanType with properties:
+ %
+ % ID: Boolean
+
+ type = TypeDisplaysOnlyID;
+ fullClassName = string(class(type));
+ className = reverse(extractBefore(reverse(fullClassName), "."));
+ typeLink = makeLinkString(FullClassName=fullClassName, ClassName=className, BoldFont=true);
+ header = " " + typeLink + " with properties:" + newline;
+ body = " ID: " + string(type.ID);
+ footer = string(newline);
+ expectedDisplay = char(strjoin([header body' footer], newline));
+ actualDisplay = evalc('disp(type)');
+ testCase.verifyDisplay(actualDisplay, expectedDisplay);
+ end
+
+ function TestTimeType(testCase, TimeType)
+ % Verify the display of TimeType objects.
+ %
+ % Example:
+ %
+ % Time32Type with properties:
+ %
+ % ID: Time32
+ % TimeUnit: Second
+
+ type = TimeType;
+ fullClassName = string(class(type));
+ className = reverse(extractBefore(reverse(fullClassName), "."));
+ typeLink = makeLinkString(FullClassName=fullClassName, ClassName=className, BoldFont=true);
+
+ header = " " + typeLink + " with properties:" + newline;
+ body = strjust(pad(["ID:"; "TimeUnit:"]));
+ body = body + " " + [string(type.ID); string(type.TimeUnit)];
+ body = " " + body;
+ footer = string(newline);
+ expectedDisplay = char(strjoin([header body' footer], newline));
+ actualDisplay = evalc('disp(type)');
+ testCase.verifyEqual(actualDisplay, expectedDisplay);
+ end
+
+ function TestDateType(testCase, DateType)
+ % Verify the display of DateType objects.
+ %
+ % Example:
+ %
+ % Date32Type with properties:
+ %
+ % ID: Date32
+ % DateUnit: Day
+
+ type = DateType;
+ fullClassName = string(class(type));
+ className = reverse(extractBefore(reverse(fullClassName), "."));
+ typeLink = makeLinkString(FullClassName=fullClassName, ClassName=className, BoldFont=true);
+
+ header = " " + typeLink + " with properties:" + newline;
+ body = strjust(pad(["ID:"; "DateUnit:"]));
+ body = body + " " + [string(type.ID); string(type.DateUnit)];
+ body = " " + body;
+ footer = string(newline);
+ expectedDisplay = char(strjoin([header body' footer], newline));
+ actualDisplay = evalc('disp(type)');
+ testCase.verifyEqual(actualDisplay, expectedDisplay);
+ end
+
+ function Display(testCase)
+ % Verify the display of TimestampType objects.
+ %
+ % Example:
+ %
+ % TimestampType with properties:
+ %
+ % ID: Timestamp
+ % TimeUnit: Second
+ % TimeZone: "America/Anchorage"
+
+ type = arrow.timestamp(TimeUnit="Second", TimeZone="America/Anchorage"); %#ok<NASGU>
+ classnameLink = makeLinkString(FullClassName="arrow.type.TimestampType", ClassName="TimestampType", BoldFont=true);
+ header = " " + classnameLink + " with properties:" + newline;
+ body = strjust(pad(["ID:"; "TimeUnit:"; "TimeZone:"]));
+ body = body + " " + ["Timestamp"; "Second"; """America/Anchorage"""];
+ body = " " + body;
+ footer = string(newline);
+ expectedDisplay = char(strjoin([header body' footer], newline));
+ actualDisplay = evalc('disp(type)');
+ testCase.verifyEqual(actualDisplay, expectedDisplay);
+ end
+ end
+
+ methods
+ function verifyDisplay(testCase, actualDisplay, expectedDisplay)
+ % When the MATLAB GUI is running, '×' (char(215)) is used as
+ % the delimiter between dimension values. However, when the
+ % GUI is not running, 'x' (char(120)) is used as the delimiter.
+ % To account for this discrepancy, check if actualDisplay
+ % contains char(215). If not, replace all instances of
+ % char(215) in expectedDisplay with char(120).
+
+ tf = contains(actualDisplay, char(215));
+ if ~tf
+ idx = strfind(expectedDisplay, char(215));
+ expectedDisplay(idx) = char(120);
+ end
+ testCase.verifyEqual(actualDisplay, expectedDisplay);
+ end
+ end
+end
+
+function link = makeLinkString(opts)
+ arguments
+ opts.FullClassName(1, 1) string
+ opts.ClassName(1, 1) string
+ % When displaying heterogeneous arrays, only the name of the
+ % closest shared anscestor class is displayed in bold. All other
+ % class names are not bolded.
+ opts.BoldFont(1, 1) logical
+ end
+
+ if opts.BoldFont
+ link = compose("<a href=""matlab:helpPopup %s"" style=""font-weight:bold"">%s</a>", ...
+ opts.FullClassName, opts.ClassName);
+ else
+ link = compose("<a href=""matlab:helpPopup %s"">%s</a>", opts.FullClassName, opts.ClassName);
+ end
+end
+
+function dimensionString = makeDimensionString(arraySize)
+ dimensionString = string(arraySize);
+ dimensionString = join(dimensionString, char(215));
+end
\ No newline at end of file