mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-11-03 13:49:45 +00:00
Adds targeted test infrastructure and validation checks to protect table drawing hooks and drop-in framework contracts against unintended modifications. * CPTableViewDrawingTest: Verifies subclass invocation order for drawing steps and ensures application-specified background colors persist across theme-state changes. * DropInCompatibilityTest: Validates default theme names, window control configurations, pop-up button bezel styles, and table class defaults. * DropInSnapshot: Encapsulates theme attribute defaults, public API surface, default view construction, and window controls as structured data. * DropInBaselineGenerator: Provides tooling to capture current framework state as a baseline. * DropInBaselineTest: Compares framework artifacts against the established baseline, permitting additions while reporting modifications and removals. * DropInBaseline.json: Introduces the initial compatibility baseline artifact.
181 lines
5.2 KiB
Plaintext
181 lines
5.2 KiB
Plaintext
/*
|
|
* DropInBaselineTest.j
|
|
* AppKit
|
|
*
|
|
* Created by David Richardson on 31/10/2026.
|
|
* Copyright David Richardson 2026.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
@import "DropInSnapshot.j"
|
|
|
|
/*
|
|
Compares the running frameworks with the recorded drop-in baseline. See
|
|
DropInSnapshot.j for what the baseline holds and DropInBaselineGenerator.j for
|
|
how to update it.
|
|
|
|
Each test reports every difference it finds. A list is more useful here than
|
|
a failure at the first difference, because one change often affects several
|
|
classes.
|
|
*/
|
|
var fs = require("fs"),
|
|
path = require("path"),
|
|
DropInBaseline = nil,
|
|
DropInCurrent = nil;
|
|
|
|
@implementation DropInBaselineTest : OJTestCase
|
|
|
|
- (void)setUp
|
|
{
|
|
// This will init the global var CPApp which are used internally in the AppKit
|
|
[[CPApplication alloc] init];
|
|
|
|
if (DropInBaseline)
|
|
return;
|
|
|
|
var baselinePath = path.join(path.dirname(__filename), "Resources", "DropInBaseline.json");
|
|
|
|
DropInBaseline = JSON.parse(fs.readFileSync(baselinePath, {encoding: 'utf-8'}));
|
|
DropInCurrent = DropInCreateSnapshot();
|
|
}
|
|
|
|
- (void)assertNoDifferences:(CPArray)differences
|
|
{
|
|
[self assertTrue:differences.length === 0 message:"\n" + differences.join("\n")];
|
|
}
|
|
|
|
/*
|
|
A themed application reads these values whenever its theme supplies none, so a
|
|
changed default changes the application.
|
|
*/
|
|
- (void)testThemeAttributeDefaultsAreUnchanged
|
|
{
|
|
var differences = [];
|
|
|
|
for (var className in DropInBaseline.themeAttributes)
|
|
{
|
|
var expected = DropInBaseline.themeAttributes[className],
|
|
current = DropInCurrent.themeAttributes[className];
|
|
|
|
if (!current)
|
|
{
|
|
differences.push(className + ": class no longer declares theme attributes");
|
|
continue;
|
|
}
|
|
|
|
for (var attribute in expected)
|
|
if (expected[attribute] !== current[attribute])
|
|
differences.push(className + " " + attribute + ": " + expected[attribute] + " is now " + current[attribute]);
|
|
}
|
|
|
|
[self assertNoDifferences:differences];
|
|
}
|
|
|
|
- (void)testPublicClassesExist
|
|
{
|
|
var differences = DropInBaseline.publicClasses.filter(function(aName)
|
|
{
|
|
return !objj_getClass(aName);
|
|
});
|
|
|
|
[self assertNoDifferences:differences];
|
|
}
|
|
|
|
/*
|
|
A public method may move to a superclass, since the class still responds to it.
|
|
It may not disappear. This test cannot detect a method that remains but no
|
|
longer does its work. Behavior tests cover that.
|
|
*/
|
|
- (void)testPublicMethodsExist
|
|
{
|
|
var differences = [];
|
|
|
|
DropInBaseline.publicClasses.forEach(function(aName)
|
|
{
|
|
var aClass = objj_getClass(aName);
|
|
|
|
if (!aClass)
|
|
return;
|
|
|
|
DropInBaseline.instanceMethods[aName].forEach(function(aSelector)
|
|
{
|
|
if (!class_getInstanceMethod(aClass, aSelector))
|
|
differences.push("-[" + aName + " " + aSelector + "]");
|
|
});
|
|
|
|
DropInBaseline.classMethods[aName].forEach(function(aSelector)
|
|
{
|
|
if (!class_getClassMethod(aClass, aSelector))
|
|
differences.push("+[" + aName + " " + aSelector + "]");
|
|
});
|
|
});
|
|
|
|
[self assertNoDifferences:differences];
|
|
}
|
|
|
|
/*
|
|
A view created in code has these values until the application changes them.
|
|
*/
|
|
- (void)testDefaultViewConstructionIsUnchanged
|
|
{
|
|
var differences = [];
|
|
|
|
for (var className in DropInBaseline.construction)
|
|
{
|
|
var expected = DropInBaseline.construction[className],
|
|
current = DropInCurrent.construction[className];
|
|
|
|
if (!current)
|
|
{
|
|
differences.push(className + ": cannot be created");
|
|
continue;
|
|
}
|
|
|
|
for (var key in expected)
|
|
{
|
|
var expectedValue = String(expected[key]),
|
|
currentValue = String(current[key]);
|
|
|
|
if (expectedValue !== currentValue)
|
|
differences.push(className + " " + key + ": " + expectedValue + " is now " + currentValue);
|
|
}
|
|
}
|
|
|
|
[self assertNoDifferences:differences];
|
|
}
|
|
|
|
/*
|
|
The public subviews of a window view are the controls a person sees in the
|
|
title bar, so they are part of how an existing application looks.
|
|
*/
|
|
- (void)testWindowControlsAreUnchanged
|
|
{
|
|
var differences = [];
|
|
|
|
for (var style in DropInBaseline.windows)
|
|
{
|
|
var expected = String(DropInBaseline.windows[style]),
|
|
current = String(DropInCurrent.windows[style]);
|
|
|
|
if (expected !== current)
|
|
differences.push(style + ": " + expected + " is now " + current);
|
|
}
|
|
|
|
[self assertNoDifferences:differences];
|
|
}
|
|
|
|
@end
|