Skip to content

Commit

Permalink
apacheGH-38652: [MATLAB] Add tests about time precision preservation …
Browse files Browse the repository at this point in the history
…when converting MATLAB duration to `arrow.array.Time32Array` and `arrow.array.Time64Array` (apache#38661)

### Rationale for this change

The current conversion from MATLAB duration to `arrow.array.Time32Array` and `arrow.array.Time64Array` loses time precision, and there is no test to cover such limitation. It is best practice to have tests cover software design. In addition, such tests will be helpful to evaluate the impact in the future when we improve the design.  

### What changes are included in this PR?  

I mainly added three test cases for each of `arrow.array.Time32Array` and `arrow.array.Time64Array`.

- Updated the basic test case to verify both class and value. In the MATLAB interface tests, we would like to verify the value to make sure there is no precision loss. The basic test case will serve as a test example when people learn to write tests. Updating the basic test case will set a good example for contributors to learn. 
- Test the default value of "TimeUnit".
- Test the functionality of "TimeUnit".

### Are these changes tested?

No software change. The updated test files passed on my local machine.

### Are there any user-facing changes?

No
* Closes: apache#38652

Authored-by: Lei Hou <[email protected]>
Signed-off-by: Kevin Gurney <[email protected]>
  • Loading branch information
leihou6116 authored Nov 16, 2023
1 parent 971bf38 commit 1fd11d3
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 0 deletions.
33 changes: 33 additions & 0 deletions matlab/test/arrow/array/tTime32Array.m
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ function Basic(tc)
times = seconds(1:4);
array = tc.ArrowArrayConstructorFcn(times);
tc.verifyInstanceOf(array, "arrow.array.Time32Array");
tc.verifyEqual(array.toMATLAB, times');
end

function TimeUnitDefaultValue(tc)
% Verify that the default value of "TimeUnit" is "second".
times = seconds([1.2 1.3 1.4 1.5 1.7]);
array = tc.ArrowArrayConstructorFcn(times);
tc.verifyEqual(array.Type.TimeUnit, arrow.type.TimeUnit.Second);
tc.verifyEqual(array.toMATLAB, seconds([1;1;1;2;2]));
end

function TypeIsTime32(tc)
Expand Down Expand Up @@ -274,6 +283,30 @@ function TestIsEqualFalseTimeUnitMistmatch(tc)
% arrays are not equal
tc.verifyFalse(isequal(array1, array2));
end

function RoundTimeBySpecifiedTimeUnit(tc)
% Verify that the input parameter "TimeUnit" is used to specify
% the time resolution. The value is rounded off based on the
% specified "TimeUnit".

% TimeUnit="Second"
matlabTimes = seconds([1.1, 1.4, 1.5, 1.9, 2.001]);
arrowTimes = tc.ArrowArrayConstructorFcn(matlabTimes, TimeUnit="Second");
tc.verifyEqual(arrowTimes.toMATLAB(),seconds([1, 1, 2, 2, 2])');

% TimeUnit="Millisecond"
matlabTimes = seconds([1.1, 1.99, 1.001, 1.0004, 1.0005, 2.001]);
arrowTimes = tc.ArrowArrayConstructorFcn(matlabTimes, TimeUnit="Millisecond");
tc.verifyEqual(arrowTimes.toMATLAB(),seconds([1.1, 1.99, 1.001, 1, 1.001, 2.001])','AbsTol',seconds(1e-15));
end

function TimeUnitIsReadOnly(tc)
% Verify that arrowArray.Type.TimeUnit cannot be changed.

matlabTimes = seconds([1.1, 1.4, 1.5, 1.9, 2.001]);
arrowArray = tc.ArrowArrayConstructorFcn(matlabTimes);
tc.verifyError(@()setfield(arrowArray.Type,"TimeUnit", "millisecond"),'MATLAB:class:SetProhibited');
end
end

methods
Expand Down
76 changes: 76 additions & 0 deletions matlab/test/arrow/array/tTime64Array.m
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,26 @@ function Basic(tc)
times = seconds(1:4);
array = tc.ArrowArrayConstructorFcn(times);
tc.verifyInstanceOf(array, "arrow.array.Time64Array");
tc.verifyEqual(array.toMATLAB, times');
end

function TimeUnitDefaultValue(tc)
% Verify that the default value of "TimeUnit" is "Microsecond".
matlabTimes = seconds([1; ...
0.001; ...
2.004521; ...
3.1234564; ...
4.1234566; ...
5.000000123]);
arrowArray = tc.ArrowArrayConstructorFcn(matlabTimes);
tc.verifyEqual(arrowArray.Type.TimeUnit, arrow.type.TimeUnit.Microsecond);
tc.verifyEqual(arrowArray.toMATLAB(), ...
seconds([1;...
0.001; ...
2.004521; ...
3.123456; ...
4.123457; ...
5]));
end

function TypeIsTime64(tc)
Expand Down Expand Up @@ -290,6 +310,62 @@ function TestIsEqualFalseTimeUnitMistmatch(tc)
% arrays are not equal
tc.verifyFalse(isequal(array1, array2));
end

function RoundTimeBySpecifiedTimeUnit(tc)
% Verify that the input parameter "TimeUnit" is used to specify
% the time resolution. The value is rounded off based on the
% specified "TimeUnit".

% TimeUnit="Microsecond"
matlabTimes = seconds([1.000001, ...
2.999999, ...
0.0002004, ...
0.0000035, ...
10.123456499, ...
9.999999543]);
arrowTimes = tc.ArrowArrayConstructorFcn(matlabTimes, TimeUnit="Microsecond");
tc.verifyEqual(arrowTimes.toMATLAB(), ...
seconds([1.000001, ...
2.999999, ...
0.0002, ...
0.000004, ...
10.123456, ...
10])', ...
'AbsTol',seconds(1e-14));

% TimeUnit="Nanosecond"
matlabTimes = seconds([1, ...
1.123, ...
1.12345, ...
1.123456, ...
1.1234567, ...
1.12345678, ...
1.123456789, ...
1.1234567894, ...
1.1234567895, ...
1.123456789009]);
arrowTimes = tc.ArrowArrayConstructorFcn(matlabTimes, TimeUnit="Nanosecond");
tc.verifyEqual(arrowTimes.toMATLAB(),...
seconds([1, ...
1.123, ...
1.12345, ...
1.123456, ...
1.1234567, ...
1.12345678, ...
1.123456789, ...
1.123456789, ...
1.123456790, ...
1.123456789])',...
'AbsTol',seconds(1e-15));
end

function TimeUnitIsReadOnly(tc)
% Verify that arrowArray.Type.TimeUnit cannot be changed.

matlabTimes = seconds([1.000001, 2.999999, 0.0002004]);
arrowArray = tc.ArrowArrayConstructorFcn(matlabTimes);
tc.verifyError(@()setfield(arrowArray.Type,"TimeUnit", "Nanosecond"),'MATLAB:class:SetProhibited');
end
end

methods
Expand Down

0 comments on commit 1fd11d3

Please sign in to comment.