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
8 changes: 8 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@
path for a root node rather than nil, matching AppKit.
* Tests/gui/NSTreeNode/basic.m: Check the root index path.

2026-07-12 Todd White <todd.white@thalion.global>

* Tests/gui/NSObjectController/basic.m:
* Tests/gui/NSObjectController/TestInfo:
Add tests for NSObjectController: the defaults, newObject, the content
and selected objects round-trip, add: and remove:, and how the
editable flag gates canAdd and canRemove.

2026-07-12 Todd White <todd.white@thalion.global>

* Tests/gui/NSTreeNode/basic.m:
Expand Down
Empty file.
73 changes: 73 additions & 0 deletions Tests/gui/NSObjectController/basic.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/* Coverage for NSObjectController: the defaults, newObject, the content and
* selected objects round-trip, add: and remove:, and how the editable flag
* gates canAdd and canRemove. These are plain controller operations and need
* no backend.
*/
#include "Testing.h"
#include <Foundation/Foundation.h>
#include <AppKit/NSObjectController.h>

int
main(int argc, char **argv)
{
CREATE_AUTORELEASE_POOL(arp);

START_SET("defaults")
NSObjectController *oc = AUTORELEASE([[NSObjectController alloc] init]);

PASS([oc content] == nil, "a new controller has no content");
PASS([oc objectClass] == [NSMutableDictionary class],
"the default object class is NSMutableDictionary");
PASS([oc isEditable] == YES, "a new controller is editable");
PASS([oc automaticallyPreparesContent] == NO,
"a new controller does not automatically prepare content");
PASS([[oc selectedObjects] count] == 0,
"a new controller has no selected objects");
PASS([oc canAdd] == YES, "an editable controller can add");
PASS([oc canRemove] == NO, "a controller with no content cannot remove");
END_SET("defaults")

START_SET("newObject")
NSObjectController *oc = AUTORELEASE([[NSObjectController alloc] init]);

PASS([[oc newObject] isKindOfClass: [NSMutableDictionary class]],
"newObject makes an instance of the object class");
END_SET("newObject")

START_SET("content and selection")
NSObjectController *oc = AUTORELEASE([[NSObjectController alloc] init]);
NSMutableDictionary *d = [NSMutableDictionary dictionary];

[oc setContent: d];
PASS([oc content] == d, "setContent: round trips");
PASS([[oc selectedObjects] count] == 1
&& [[oc selectedObjects] objectAtIndex: 0] == d,
"the content is the selected object");
PASS([oc canRemove] == YES, "a controller with content can remove");

oc = AUTORELEASE([[NSObjectController alloc] initWithContent: d]);
PASS([oc content] == d, "initWithContent: stores the content");
END_SET("content and selection")

START_SET("the editable flag gates adding and removing")
NSObjectController *oc = AUTORELEASE([[NSObjectController alloc]
initWithContent: [NSMutableDictionary dictionary]]);

[oc setEditable: NO];
PASS([oc canAdd] == NO, "a non-editable controller cannot add");
PASS([oc canRemove] == NO, "a non-editable controller cannot remove");
END_SET("the editable flag gates adding and removing")

START_SET("addObject: and removeObject:")
NSObjectController *oc = AUTORELEASE([[NSObjectController alloc] init]);
NSMutableDictionary *d = [NSMutableDictionary dictionary];

[oc addObject: d];
PASS([oc content] == d, "addObject: sets the content");
[oc removeObject: d];
PASS([oc content] == nil, "removeObject: clears the content");
END_SET("addObject: and removeObject:")

DESTROY(arp);
return 0;
}
Loading