cedarbdd / cedar

BDD-style testing using Objective-C
http://groups.google.com/group/cedar-discuss
1.19k stars 140 forks source link

Custom matchers fails to compile using Xcode 7.3 #381

Closed PeqNP closed 8 years ago

PeqNP commented 8 years ago

I'm having issues importing custom matchers. The custom matcher fails to compile after I installed Xcode 7.3.

My custom matcher file looks, and is named, almost exactly like the example one this project provides at https://github.com/pivotal/cedar/wiki/Configuration#adding-your-own-custom-matchers.

I believe the issue is due to Xcode attempting to compile the CustomMatchers.h header as a C file rather than a C++ file. I've tried setting the Identity and Type to C++ Header (as well as other options), but no dice.

Specifically, the error is: Unknown type name 'namespace'. This is indicative of the file attempting to be compiled as a C file, rather than C++.

Any advice would be greatly appreciated. Thank you!

PeqNP commented 8 years ago

Hmm... even more interesting. I moved all of the code from the CustomMatchers.h file into the CedarComparators.h file, between the #ifdef CEDAR_CUSTOM_COMPARATORS guard, and I'm getting the same errors. I can safely remove the possibility of the CustomMatchers.h header file being the source of the issue.

briancroom commented 8 years ago

Hey @PeqNP, I think I have an idea why you're experiencing this. With recent Cedar versions, Xcode tries to also build a Swift-compatible "module" version of Cedar, which can only include non-C++ components. This change means that all matchers (built-in and custom) need to be wrapped in an #ifdef __cplusplus / #endif block to ensure that they are only built in Objective-C++ mode. See here for an example. It looks like the documentation in the wiki still needs to be updated to reflect this. Let me know if this helps!

PeqNP commented 8 years ago

That solved the issue! Using the example in the Wiki, I ended up changing the code to look like this:

#import <CoreMedia/CoreMedia.h>

#if TARGET_OS_IPHONE
#import <Cedar-iOS/ComparatorsBase.h>
#import <Cedar-iOS/StringifiersBase.h>
#else
#import <Cedar/ComparatorsBase.h>
#import <Cedar/StringifiersBase.h>
#endif

#ifdef __cplusplus

namespace Cedar { namespace Matchers { namespace Comparators {
    template<typename U>
    bool compare_equal(CMTimeRange const actualValue, const U & expectedValue) {
        return CMTimeRangeEqual(actualValue, expectedValue);
    }
}}}

namespace Cedar { namespace Matchers { namespace Stringifiers {
    inline NSString * string_for(const CMTimeRange value) {
        return [NSString stringWithFormat:@"%lld/%d (duration %lld/%d)", value.start.value, value.start.timescale, value.duration.value, value.duration.timescale];
    }
}}}

#endif

Thank you for the response!

briancroom commented 8 years ago

Note that this was an unintentional breaking change. https://github.com/pivotal/cedar/commit/0b92d9ea15368241408b7210699698997d6f63a9 should fix this such that custom matchers won't need the guard to be manually inserted anymore.