Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info Ref="widgets/examples/templates" Type="Relative"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="3455837e-0fca-40ad-bdd0-5c6ee613fa96" type="Reference"/>
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
<?xml version='1.0' encoding='UTF-8'?>
<Info Ref="widgets/examples" Type="Relative" />
<?xml version="1.0" encoding="UTF-8"?>
<Info Ref="widgets/examples" Type="Relative"/>
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
<?xml version='1.0' encoding='UTF-8'?>
<Info location="3e6a7481-8733-409c-bfa6-02e29452eeab" type="Reference" />
<?xml version="1.0" encoding="UTF-8"?>
<Info location="3e6a7481-8733-409c-bfa6-02e29452eeab" type="Reference"/>
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
<?xml version='1.0' encoding='UTF-8'?>
<Info Ref="deploy" Type="Relative" />
<?xml version="1.0" encoding="UTF-8"?>
<Info Ref="deploy" Type="Relative"/>
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
<?xml version='1.0' encoding='UTF-8'?>
<Info location="68fdb71a-f6db-4d2b-9a4e-76e3570d1276" type="Reference" />
<?xml version="1.0" encoding="UTF-8"?>
<Info location="68fdb71a-f6db-4d2b-9a4e-76e3570d1276" type="Reference"/>
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
<?xml version='1.0' encoding='UTF-8'?>
<Info Ref="widgets" Type="Relative" />
<?xml version="1.0" encoding="UTF-8"?>
<Info Ref="widgets" Type="Relative"/>
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
<?xml version='1.0' encoding='UTF-8'?>
<Info location="96a61ccb-178c-44ac-b446-b707f70144fb" type="Reference" />
<?xml version="1.0" encoding="UTF-8"?>
<Info location="96a61ccb-178c-44ac-b446-b707f70144fb" type="Reference"/>
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
<?xml version='1.0' encoding='UTF-8'?>
<Info Ref="widgets/doc" Type="Relative" />
<?xml version="1.0" encoding="UTF-8"?>
<Info Ref="widgets/doc" Type="Relative"/>
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
<?xml version='1.0' encoding='UTF-8'?>
<Info location="d29e81e6-6e00-4082-826d-de0a6a1da0c7" type="Reference" />
<?xml version="1.0" encoding="UTF-8"?>
<Info location="d29e81e6-6e00-4082-826d-de0a6a1da0c7" type="Reference"/>
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
<?xml version='1.0' encoding='UTF-8'?>
<Info Ref="widgets/icons" Type="Relative" />
<?xml version="1.0" encoding="UTF-8"?>
<Info Ref="widgets/icons" Type="Relative"/>
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
<?xml version='1.0' encoding='UTF-8'?>
<Info location="94f413ee-d5a4-4016-aa70-226d0d4d9b47" type="Reference" />
<?xml version="1.0" encoding="UTF-8"?>
<Info location="94f413ee-d5a4-4016-aa70-226d0d4d9b47" type="Reference"/>
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
<?xml version='1.0' encoding='UTF-8'?>
<Info Ref="test" Type="Relative" />
<?xml version="1.0" encoding="UTF-8"?>
<Info Ref="test" Type="Relative"/>
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
<?xml version='1.0' encoding='UTF-8'?>
<Info location="f8d40992-9dcd-4000-bc2b-2e41881b91a0" type="Reference" />
<?xml version="1.0" encoding="UTF-8"?>
<Info location="f8d40992-9dcd-4000-bc2b-2e41881b91a0" type="Reference"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info>
<Category UUID="FileClassCategory">
<Label UUID="test"/>
</Category>
</Info>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="TemplateApps.m" type="File"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="templates" type="File"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="1" type="DIR_SIGNIFIER"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info>
<Category UUID="FileClassCategory">
<Label UUID="design"/>
</Category>
</Info>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="TemplateBaseMultiSessionApp.m" type="File"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version='1.0' encoding='UTF-8'?>
<Info>
<Category UUID="FileClassCategory">
<Label UUID="design"/>
</Category>
</Info>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="TemplateBaseSingleSessionApp.m" type="File"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version='1.0' encoding='UTF-8'?>
<Info>
<Category UUID="FileClassCategory">
<Label UUID="design"/>
</Category>
</Info>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="TemplateBaseApp.m" type="File"/>
119 changes: 119 additions & 0 deletions test/+wt/+test/TemplateApps.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
classdef TemplateApps < matlab.uitest.TestCase
% Implements unit tests for the app templates

% Copyright 2025 The MathWorks Inc.

%% Properties
properties
App
Figure matlab.ui.Figure
% TempFolder
end


%% Test Method Setup
methods (TestMethodSetup)

% function prepareTempFolder(testCase)
%
% % Use a temporary folder for sessions
% import matlab.unittest.fixtures.TemporaryFolderFixture
% fixture = testCase.applyFixture(TemporaryFolderFixture);
% testCase.TempFolder = fixture.Folder;
%
% end %function

end %methods


%% Test Method Teardown
methods (TestMethodTeardown)
% Teardown for each test

function deleteApp(testCase)

if isscalar(testCase.App) && isvalid(testCase.App)
if isscalar(testCase.App.Figure)
delete(testCase.App.Figure)
end
delete(testCase.App)
end

end %function

end %methods

%% Test methods
methods (Test)

function testTemplateBaseApp(testCase)
% Verifies behavior of the app template

% Launch the app
diag = "Expected app to launch without warnings.";
fcn = @()TemplateBaseApp();
testCase.App = testCase.verifyWarningFree(fcn, diag);

% Verify app and component creation
diag = "Expected app figure to be populated.";
testCase.verifyNotEmpty(testCase.App.Figure, diag)

% Verify app closes
diag = "Expected app to close without warnings.";
fcn = @()close(testCase.App);
testCase.verifyWarningFree(fcn, diag);

diag = "Expected app to be deleted.";
testCase.verifyFalse(isvalid(testCase.App), diag)

end %function


function testTemplateBaseSingleSessionApp(testCase)
% Verifies behavior of the app template

% Launch the app
diag = "Expected app to launch without warnings.";
fcn = @()TemplateBaseSingleSessionApp();
testCase.App = testCase.verifyWarningFree(fcn, diag);

% Verify app and component creation
diag = "Expected app figure to be populated.";
testCase.verifyNotEmpty(testCase.App.Figure, diag)

% Verify app closes
diag = "Expected app to close without warnings.";
fcn = @()close(testCase.App);
testCase.verifyWarningFree(fcn, diag);

diag = "Expected app to be deleted.";
testCase.verifyFalse(isvalid(testCase.App), diag)

end %function


function testTemplateBaseMultiSessionApp(testCase)
% Verifies behavior of the app template

% Launch the app
diag = "Expected app to launch without warnings.";
fcn = @()TemplateBaseMultiSessionApp();
testCase.App = testCase.verifyWarningFree(fcn, diag);

% Verify app and component creation
diag = "Expected app figure to be populated.";
testCase.verifyNotEmpty(testCase.App.Figure, diag)

% Verify app closes
diag = "Expected app to close without warnings.";
fcn = @()close(testCase.App);
testCase.verifyWarningFree(fcn, diag);

diag = "Expected app to be deleted.";
testCase.verifyFalse(isvalid(testCase.App), diag)

end %function

end %methods

end %classdef
28 changes: 19 additions & 9 deletions widgets/+wt/+apps/AbstractSessionApp.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
?wt.apps.BaseMultiSessionApp}) AbstractSessionApp < wt.apps.BaseApp
% Abstract base class for Widgets Toolbox app with 1+ sessions

% Copyright 2024-2025 The MathWorks Inc.
% Copyright 2024-2025 The MathWorks Inc.


%% Abstract Public Properties
Expand Down Expand Up @@ -87,10 +87,6 @@
% Call superclass constructor
[email protected](varargin{:});

% Attach listeners to Session being set
app.SessionSetListener = listener(app,"Session","PostSet",...
@(~,~)app.onSessionSet_Private());

end %function

end %methods
Expand All @@ -99,6 +95,19 @@
%% Protected Methods
methods (Access = protected)

function setup_internal(app)
% Preform internal pre-setup necessary

% Show output if Debug is on
app.displayDebugText();

% Attach listeners to Session being set
app.SessionSetListener = listener(app,"Session","PostSet",...
@(~,~)app.onSessionSet_Private());

end %function


function onSessionSet(app)
% This method is called when the Session property has changed,
% such as a session being added or removed from the app. The
Expand Down Expand Up @@ -248,11 +257,12 @@ function saveSession_Internal(app, useSaveAs, session)
cleanupObj = onCleanup(@()delete(dlg));

% Save the session
% This will trigger update if path updates and/or session
% is no longer dirty
session.save(sessionPath);

% Update the app in case filepath changed
% Update the title
app.updateTitle()
app.update()

end %if strlength(sessionPath)

Expand Down Expand Up @@ -359,7 +369,7 @@ function saveSession_Internal(app, useSaveAs, session)
% Define arguments
arguments
app (1,1) wt.apps.BaseApp
session (1,1) wt.model.BaseSession = app.Session
session wt.model.BaseSession = app.Session
end

% Show output if Debug is on
Expand All @@ -369,7 +379,7 @@ function saveSession_Internal(app, useSaveAs, session)
isCancelled = false;

% Don't save and return now if session is invalid or clean
if ~isvalid(session) || ~session.Dirty
if ~isscalar(session) || ~isvalid(session) || ~session.Dirty
return
end

Expand Down
Loading