Create Custom Boolean Constraint - MATLAB & Simulink (original) (raw)

Main Content

This example shows how to create a custom Boolean constraint that determines if a given value is the same size as an expected value.

In a file in your current folder, create a class namedIsSameSizeAs that derives from the matlab.unittest.constraints.BooleanConstraint class. The class constructor accepts an expected value whose size is compared to the size of an actual value. The expected value is stored in theValueWithExpectedSize property. The recommended practice is to make BooleanConstraint implementations immutable, so set the property SetAccess attribute toimmutable.

classdef IsSameSizeAs < matlab.unittest.constraints.BooleanConstraint properties (SetAccess=immutable) ValueWithExpectedSize end

methods
    function constraint = IsSameSizeAs(value)
        constraint.ValueWithExpectedSize = value;
    end
end  

end

In a methods block with private access, define a helper method sizeMatchesExpected that determines if the actual and expected values are the same size. This method is invoked by other constraint methods.

methods (Access=private)
    function tf = sizeMatchesExpected(constraint,actual)
        tf = isequal(size(actual), ...
            size(constraint.ValueWithExpectedSize));
    end
end

The matlab.unittest.constraints.BooleanConstraint class is a subclass of the matlab.unittest.constraints.Constraint class. Therefore, classes that derive from the BooleanConstraint class must implement the methods of the Constraint class. Within amethods block, implement thesatisfiedBy and getDiagnosticFor methods. The satisfiedBy implementation must contain the comparison logic and return a logical value. ThegetDiagnosticFor implementation must evaluate the actual value against the constraint and provide a Diagnostic object. In this example, getDiagnosticFor returns a StringDiagnostic object.

methods
    function tf = satisfiedBy(constraint,actual)
        tf = constraint.sizeMatchesExpected(actual);
    end

    function diagnostic = getDiagnosticFor(constraint,actual)
        import matlab.automation.diagnostics.StringDiagnostic
        if constraint.sizeMatchesExpected(actual)
            diagnostic = StringDiagnostic("IsSameSizeAs passed.");
        else
            diagnostic = StringDiagnostic( ...
                "IsSameSizeAs failed." + newline + "Actual Size: [" ...
                + int2str(size(actual)) + "]" + newline ...
                + "Expected Size: [" ...
                + int2str(size(constraint.ValueWithExpectedSize)) ...
                + "]");
        end
    end
end

Classes that derive from BooleanConstraint must implement the getNegativeDiagnosticFor method. This method must provide a Diagnostic object when the constraint is negated. ImplementgetNegativeDiagnosticFor in a methods block with protected access.

methods (Access=protected)
    function diagnostic = getNegativeDiagnosticFor(constraint,actual)
        import matlab.automation.diagnostics.StringDiagnostic
        if constraint.sizeMatchesExpected(actual)
            diagnostic = StringDiagnostic( ...
                "Negated IsSameSizeAs failed." + newline + ...
                "Actual and expected sizes were the same ([" ...
                + int2str(size(actual)) + ...
                "]) but should not have been.");
        else
            diagnostic = StringDiagnostic( ...
                "Negated IsSameSizeAs passed.");
        end
    end
end

In exchange for implementing the required methods, the constraint inherits the appropriate and, or, andnot overloads, so it can be combined with otherBooleanConstraint objects or negated.

IsSameSizeAs Class Definition

This is the complete code for the IsSameSizeAs class.

classdef IsSameSizeAs < matlab.unittest.constraints.BooleanConstraint properties (SetAccess=immutable) ValueWithExpectedSize end

methods
    function constraint = IsSameSizeAs(value)
        constraint.ValueWithExpectedSize = value;
    end

    function tf = satisfiedBy(constraint,actual)
        tf = constraint.sizeMatchesExpected(actual);
    end

    function diagnostic = getDiagnosticFor(constraint,actual)
        import matlab.automation.diagnostics.StringDiagnostic
        if constraint.sizeMatchesExpected(actual)
            diagnostic = StringDiagnostic("IsSameSizeAs passed.");
        else
            diagnostic = StringDiagnostic( ...
                "IsSameSizeAs failed." + newline + "Actual Size: [" ...
                + int2str(size(actual)) + "]" + newline ...
                + "Expected Size: [" ...
                + int2str(size(constraint.ValueWithExpectedSize)) ...
                + "]");
        end
    end
end

methods (Access=protected)
    function diagnostic = getNegativeDiagnosticFor(constraint,actual)
        import matlab.automation.diagnostics.StringDiagnostic
        if constraint.sizeMatchesExpected(actual)
            diagnostic = StringDiagnostic( ...
                "Negated IsSameSizeAs failed." + newline + ...
                "Actual and expected sizes were the same ([" ...
                + int2str(size(actual)) + ...
                "]) but should not have been.");
        else
            diagnostic = StringDiagnostic( ...
                "Negated IsSameSizeAs passed.");
        end
    end
end

methods (Access=private)
    function tf = sizeMatchesExpected(constraint,actual)
        tf = isequal(size(actual), ...
            size(constraint.ValueWithExpectedSize));
    end
end

end

Test for Expected Size

At the command prompt, create a test case for interactive testing.

import matlab.unittest.TestCase import matlab.unittest.constraints.HasLength testCase = TestCase.forInteractiveUse;

Test a passing case. The test passes because one of the or conditions, HasLength(5), is true.

testCase.verifyThat(zeros(5),HasLength(5) | ~IsSameSizeAs(repmat(1,5)))

Test a failing case. The test fails because one of the and conditions, ~IsSameSizeAs(repmat(1,5)), is false.

testCase.verifyThat(zeros(5),HasLength(5) & ~IsSameSizeAs(repmat(1,5)))

Verification failed. --------------------- Framework Diagnostic: --------------------- AndConstraint failed. --> + [First Condition]: | HasLength passed. |
| Actual Value: | 0 0 0 0 0 | 0 0 0 0 0 | 0 0 0 0 0 | 0 0 0 0 0 | 0 0 0 0 0 | Expected Length: | 5 --> AND + [Second Condition]: | Negated ISameSizeAs failed. | Actual and expected sizes were the same ([5 5]) but should not have been. -+---------------------

See Also

Classes

Topics