Index: new_tests/Makefile ================================================================== --- new_tests/Makefile +++ new_tests/Makefile @@ -10,11 +10,12 @@ ${PROG_NOINST}.rpx \ testfile_bin.m \ testfile_ini.m PROG_NOINST = tests${PROG_SUFFIX} -SRCS = ForwardingTests.m \ +SRCS = ${OF_BLOCK_TESTS_M} \ + ForwardingTests.m \ OFArrayTests.m \ OFCharacterSetTests.m \ OFColorTests.m \ OFConcreteArrayTests.m \ OFConcreteMutableArrayTests.m \ ADDED new_tests/OFBlockTests.m Index: new_tests/OFBlockTests.m ================================================================== --- new_tests/OFBlockTests.m +++ new_tests/OFBlockTests.m @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2008-2024 Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#import "ObjFW.h" +#import "ObjFWTest.h" + +@interface OFBlockTests: OTTestCase +@end + +#if defined(OF_OBJFW_RUNTIME) +extern struct objc_class _NSConcreteStackBlock; +extern struct objc_class _NSConcreteGlobalBlock; +extern struct objc_class _NSConcreteMallocBlock; +#elif defined(OF_APPLE_RUNTIME) +extern void *_NSConcreteStackBlock; +extern void *_NSConcreteGlobalBlock; +extern void *_NSConcreteMallocBlock; +#endif + +/* Clang on Win32 generates broken code that crashes for global blocks. */ +#if !defined(OF_WINDOWS) || !defined(__clang__) +static void (^globalBlock)(void) = ^ {}; +#endif + +static int +(^returnStackBlock(void))(void) +{ + __block int i = 42; + + return [Block_copy(^ int { return ++i; }) autorelease]; +} + +static double +forwardTest(void) +{ + __block double d; + void (^block)(void) = Block_copy(^ { + d = 5; + }); + + block(); + Block_release(block); + + return d; +} + +@implementation OFBlockTests +- (void)testClassOfStackBlock +{ + __block int x; + void (^stackBlock)(void) = ^ { + x = 0; + (void)x; + }; + + OTAssertEqual((Class)&_NSConcreteStackBlock, + objc_getClass("OFStackBlock")); + OTAssertTrue([stackBlock isKindOfClass: [OFBlock class]]); +} + +#if !defined(OF_WINDOWS) || !defined(__clang__) +- (void)testClassOfGlobalBlock +{ + OTAssertEqual((Class)&_NSConcreteGlobalBlock, + objc_getClass("OFGlobalBlock")); + OTAssertTrue([globalBlock isKindOfClass: [OFBlock class]]); +} +#endif + +- (void)testClassOfMallocBlock +{ + OTAssertEqual((Class)&_NSConcreteMallocBlock, + objc_getClass("OFMallocBlock")); +} + +- (void)testCopyStackBlock +{ + __block int x; + void (^stackBlock)(void) = ^ { + x = 0; + (void)x; + }; + void (^mallocBlock)(void); + + mallocBlock = [[stackBlock copy] autorelease]; + OTAssertEqual([mallocBlock class], objc_getClass("OFMallocBlock")); + OTAssertTrue([mallocBlock isKindOfClass: [OFBlock class]]); +} + +- (void)testCopyStackBlockAndReferenceVariable +{ + OTAssertEqual(forwardTest(), 5); +} + +- (void)testCopyStackBlockAndReferenceCopiedVariable +{ + int (^voidBlock)(void) = returnStackBlock(); + + OTAssertEqual(voidBlock(), 43); + OTAssertEqual(voidBlock(), 44); + OTAssertEqual(voidBlock(), 45); +} + +#if !defined(OF_WINDOWS) || !defined(__clang__) +- (void)testCopyGlobalBlock +{ + OTAssertEqual([[globalBlock copy] autorelease], (id)globalBlock); +} +#endif + +- (void)testCopyMallocBlock +{ + __block int x; + void (^stackBlock)(void) = ^ { + x = 0; + (void)x; + }; + void (^mallocBlock)(void); + + mallocBlock = [[stackBlock copy] autorelease]; + OTAssertEqual([[mallocBlock copy] autorelease], (id)mallocBlock); + OTAssertEqual([mallocBlock retainCount], 2); +} +@end Index: tests/Makefile ================================================================== --- tests/Makefile +++ tests/Makefile @@ -11,12 +11,11 @@ ${PROG_NOINST}.rpx DISTCLEAN = Info.plist PROG_NOINST = tests${PROG_SUFFIX} STATIC_LIB_NOINST = ${TESTS_STATIC_LIB} -SRCS = ${OF_BLOCK_TESTS_M} \ - OFDataTests.m \ +SRCS = OFDataTests.m \ OFDictionaryTests.m \ OFListTests.m \ OFMemoryStreamTests.m \ OFNotificationCenterTests.m \ OFStreamTests.m \ DELETED tests/OFBlockTests.m Index: tests/OFBlockTests.m ================================================================== --- tests/OFBlockTests.m +++ tests/OFBlockTests.m @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2008-2024 Jonathan Schleifer - * - * All rights reserved. - * - * This file is part of ObjFW. It may be distributed under the terms of the - * Q Public License 1.0, which can be found in the file LICENSE.QPL included in - * the packaging of this file. - * - * Alternatively, it may be distributed under the terms of the GNU General - * Public License, either version 2 or 3, which can be found in the file - * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this - * file. - */ - -#include "config.h" - -#import "TestsAppDelegate.h" - -static OFString *const module = @"OFBlock"; - -#if defined(OF_OBJFW_RUNTIME) -extern struct objc_class _NSConcreteStackBlock; -extern struct objc_class _NSConcreteGlobalBlock; -extern struct objc_class _NSConcreteMallocBlock; -#elif defined(OF_APPLE_RUNTIME) -extern void *_NSConcreteStackBlock; -extern void *_NSConcreteGlobalBlock; -extern void *_NSConcreteMallocBlock; -#endif - -/* Clang on Win32 generates broken code that crashes for global blocks. */ -#if !defined(OF_WINDOWS) || !defined(__clang__) -static void (^globalBlock)(void) = ^ {}; -#endif - -static int -(^returnStackBlock(void))(void) -{ - __block int i = 42; - - return [Block_copy(^ int { return ++i; }) autorelease]; -} - -static double -forwardTest(void) -{ - __block double d; - void (^block)(void) = Block_copy(^ { - d = 5; - }); - - block(); - Block_release(block); - - return d; -} - -@implementation TestsAppDelegate (OFBlockTests) -- (void)blockTests -{ - void *pool = objc_autoreleasePoolPush(); - __block int x; - void (^stackBlock)(void) = ^ { - x = 0; - (void)x; - }; - void (^mallocBlock)(void); - int (^voidBlock)(void); - - TEST(@"Class of stack block", - (Class)&_NSConcreteStackBlock == objc_getClass("OFStackBlock") && - [stackBlock isKindOfClass: [OFBlock class]]) - -#if !defined(OF_WINDOWS) || !defined(__clang__) - TEST(@"Class of global block", - (Class)&_NSConcreteGlobalBlock == objc_getClass("OFGlobalBlock") && - [globalBlock isKindOfClass: [OFBlock class]]) -#endif - - TEST(@"Class of a malloc block", - (Class)&_NSConcreteMallocBlock == objc_getClass("OFMallocBlock")) - - TEST(@"Copying a stack block", - (mallocBlock = [[stackBlock copy] autorelease]) && - [mallocBlock class] == objc_getClass("OFMallocBlock") && - [mallocBlock isKindOfClass: [OFBlock class]]) - - TEST(@"Copying a stack block and referencing its variable", - forwardTest() == 5) - - TEST(@"Copying a stack block and using its copied variable", - (voidBlock = returnStackBlock()) && voidBlock() == 43 && - voidBlock() == 44 && voidBlock() == 45) - -#if !defined(OF_WINDOWS) || !defined(__clang__) - TEST(@"Copying a global block", - (id)globalBlock == [[globalBlock copy] autorelease]) -#endif - -#ifndef __clang_analyzer__ - TEST(@"Copying a malloc block", - (id)mallocBlock == [mallocBlock copy] && - [mallocBlock retainCount] == 2) -#endif - - TEST(@"Autorelease a stack block", R([stackBlock autorelease])) - -#if !defined(OF_WINDOWS) || !defined(__clang__) - TEST(@"Autorelease a global block", R([globalBlock autorelease])) -#endif - -#ifndef __clang_analyzer__ - TEST(@"Autorelease a malloc block", R([mallocBlock autorelease])) -#endif - - objc_autoreleasePoolPop(pool); -} -@end Index: tests/TestsAppDelegate.h ================================================================== --- tests/TestsAppDelegate.h +++ tests/TestsAppDelegate.h @@ -57,14 +57,10 @@ - (void)outputTesting: (OFString *)test inModule: (OFString *)module; - (void)outputSuccess: (OFString *)test inModule: (OFString *)module; - (void)outputFailure: (OFString *)test inModule: (OFString *)module; @end -@interface TestsAppDelegate (OFBlockTests) -- (void)blockTests; -@end - @interface TestsAppDelegate (OFDDPSocketTests) - (void)DDPSocketTests; @end @interface TestsAppDelegate (OFDataTests) Index: tests/TestsAppDelegate.m ================================================================== --- tests/TestsAppDelegate.m +++ tests/TestsAppDelegate.m @@ -372,13 +372,10 @@ [self runtimeTests]; #ifdef COMPILER_SUPPORTS_ARC [self runtimeARCTests]; #endif -#ifdef OF_HAVE_BLOCKS - [self blockTests]; -#endif [self stringTests]; [self dataTests]; [self dictionaryTests]; [self listTests]; [self valueTests];