Skip to content

Commit

Permalink
Merge pull request Quick#145 from modocache/66-objc-shorthand
Browse files Browse the repository at this point in the history
QCKDSL: no 'qck_' prefix unless shorthand disabled
  • Loading branch information
jeffh committed Oct 13, 2014
2 parents 2c98538 + a733262 commit f656a4e
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 48 deletions.
16 changes: 16 additions & 0 deletions Quick/Quick/QCKDSL.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,22 @@
#define qck_xcontext(description, ...) [QCKDSL xcontext:description closure:__VA_ARGS__]
#define qck_xit(description, ...) [QCKDSL xit:description closure:__VA_ARGS__]

#ifndef QUICK_DISABLE_SHORT_SYNTAX
#define beforeSuite(...) qck_beforeSuite(__VA_ARGS__)
#define afterSuite(...) qck_afterSuite(__VA_ARGS__)
#define sharedExamples(name, ...) qck_sharedExamples(name, __VA_ARGS__)
#define describe(description, ...) qck_describe(description, __VA_ARGS__)
#define context(description, ...) qck_context(description, __VA_ARGS__)
#define beforeEach(...) qck_beforeEach(__VA_ARGS__)
#define afterEach(...) qck_afterEach(__VA_ARGS__)
#define it(description, ...) qck_it(description, __VA_ARGS__)
#define itBehavesLike(name, ...) qck_itBehavesLike(name, __VA_ARGS__)
#define pending(description, ...) qck_pending(description, __VA_ARGS__)
#define xdescribe(description, ...) qck_xdescribe(description, __VA_ARGS__)
#define xcontext(description, ...) qck_xcontext(description, __VA_ARGS__)
#define xit(description, ...) qck_xit(description, __VA_ARGS__)
#endif

typedef NSDictionary *(^QCKDSLSharedExampleContext)(void);
typedef void (^QCKDSLSharedExampleBlock)(QCKDSLSharedExampleContext);

Expand Down
32 changes: 16 additions & 16 deletions Quick/QuickTests/FunctionalTests+ObjC.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@

QuickSharedExampleGroupsBegin(FunctionalTestsObjCSharedExampleGroups)

qck_sharedExamples(@"a truthy value", ^(QCKDSLSharedExampleContext context) {
sharedExamples(@"a truthy value", ^(QCKDSLSharedExampleContext sharedExampleContext) {
__block NSNumber *value = nil;
qck_beforeEach(^{
value = context()[@"value"];
beforeEach(^{
value = sharedExampleContext()[@"value"];
});

qck_it(@"is true", ^{
it(@"is true", ^{
expect(value).to(beTruthy());
});
});
Expand All @@ -31,40 +31,40 @@

QuickSpecBegin(FunctionalTestsObjC)

qck_beforeSuite(^{
beforeSuite(^{
beforeSuiteExecuted_afterSuiteNotYetExecuted = YES;
});

qck_afterSuite(^{
afterSuite(^{
beforeSuiteExecuted_afterSuiteNotYetExecuted = NO;
});

qck_describe(@"a describe block", ^{
qck_it(@"contains an it block", ^{
describe(@"a describe block", ^{
it(@"contains an it block", ^{
expect(@(beforeSuiteExecuted_afterSuiteNotYetExecuted)).to(beTruthy());
});

qck_itBehavesLike(@"a truthy value", ^{ return @{ @"value": @YES }; });
itBehavesLike(@"a truthy value", ^{ return @{ @"value": @YES }; });

qck_pending(@"a pending block", ^{
qck_it(@"contains a failing it block", ^{
pending(@"a pending block", ^{
it(@"contains a failing it block", ^{
expect(@NO).to(beTruthy());
});
});

qck_xdescribe(@"a pending (shorthand) describe block", ^{
qck_it(@"contains a failing it block", ^{
xdescribe(@"a pending (shorthand) describe block", ^{
it(@"contains a failing it block", ^{
expect(@NO).to(beTruthy());
});
});

qck_xcontext(@"a pending (shorthand) context block", ^{
qck_it(@"contains a failing it block", ^{
xcontext(@"a pending (shorthand) context block", ^{
it(@"contains a failing it block", ^{
expect(@NO).to(beTruthy());
});
});

qck_xit(@"contains a pending (shorthand) it block", ^{
xit(@"contains a pending (shorthand) it block", ^{
expect(@NO).to(beTruthy());
});
});
Expand Down
86 changes: 54 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ class TableOfContentsSpec: QuickSpec {
- [Sharing Setup/Teardown Code Using `beforeEach` and `afterEach`](#sharing-setupteardown-code-using-beforeeach-and-aftereach)
- [Specifying Conditional Behavior Using `context`](#specifying-conditional-behavior-using-context)
- [Temporarily Disabling Examples or Groups Using `pending`](#temporarily-disabling-examples-or-groups-using-pending)
- [Shorthand syntax](#shorthand-syntax)
- [Global Setup/Teardown Using `beforeSuite` and `afterSuite`](#global-setupteardown-using-beforesuite-and-aftersuite)
- [Sharing Examples](#sharing-examples)
- [Using Quick in Objective-C: The Optional Shorthand Syntax](#using-quick-in-objective-c-the-optional-shorthand-syntax)
- [Nimble: Assertions Using `expect(...).to`](#nimble-assertions-using-expectto)
- [Testing UIKit with Quick](#testing-uikit-with-quick)
- [How to Install Quick](#how-to-install-quick)
Expand Down Expand Up @@ -105,11 +107,11 @@ class DolphinSpec: QuickSpec {

QuickSpecBegin(DolphinSpec)

qck_it(@"is friendly", ^{
it(@"is friendly", ^{
expect(@([[Dolphin new] isFriendly])).to(beTruthy());
});

qck_it(@"is smart", ^{
it(@"is smart", ^{
expect(@([[Dolphin new] isSmart])).to(beTruthy());
});

Expand Down Expand Up @@ -164,14 +166,14 @@ class DolphinSpec: QuickSpec {

QuickSpecBegin(DolphinSpec)

qck_describe(@"a dolphin", ^{
qck_describe(@"its click", ^{
qck_it(@"is loud", ^{
describe(@"a dolphin", ^{
describe(@"its click", ^{
it(@"is loud", ^{
Click *click = [[Dolphin new] click];
expect(@(click.isLoud)).to(beTruthy());
});

qck_it(@"has a high frequency", ^{
it(@"has a high frequency", ^{
Click *click = [[Dolphin new] click];
expect(@(click.hasHighFrequency)).to(beTruthy());
});
Expand Down Expand Up @@ -231,23 +233,23 @@ class DolphinSpec: QuickSpec {

QuickSpecBegin(DolphinSpec)

qck_describe(@"a dolphin", ^{
describe(@"a dolphin", ^{
__block Dolphin *dolphin = nil;
qck_beforeEach(^{
beforeEach(^{
dolphin = [Dolphin new];
});

qck_describe(@"its click", ^{
describe(@"its click", ^{
__block Click *click = nil;
qck_beforeEach(^{
beforeEach(^{
click = [dolphin click];
});

qck_it(@"is loud", ^{
it(@"is loud", ^{
expect(@(click.isLoud)).to(beTruthy());
});

qck_it(@"has a high frequency", ^{
it(@"has a high frequency", ^{
expect(@(click.hasHighFrequency)).to(beTruthy());
});
});
Expand Down Expand Up @@ -320,24 +322,24 @@ class DolphinSpec: QuickSpec {

QuickSpecBegin(DolphinSpec)

qck_describe(@"a dolphin", ^{
describe(@"a dolphin", ^{
__block Dolphin *dolphin = nil;
qck_beforeEach(^{ dolphin = [Dolphin new]; });
beforeEach(^{ dolphin = [Dolphin new]; });

qck_describe(@"its click", ^{
qck_context(@"when the dolphin is not near anything interesting", ^{
qck_it(@"is only emitted once", ^{
describe(@"its click", ^{
context(@"when the dolphin is not near anything interesting", ^{
it(@"is only emitted once", ^{
expect(@([[dolphin click] count])).to(equal(@1));
});
});

qck_context(@"when the dolphin is near something interesting", ^{
qck_beforeEach(^{
context(@"when the dolphin is near something interesting", ^{
beforeEach(^{
[[Jamaica dolphinCove] add:[SunkenShip new]];
[[Jamaica dolphinCove] add:dolphin];
});

qck_it(@"is emitted three times", ^{
it(@"is emitted three times", ^{
expect(@([[dolphin click] count])).to(equal(@3));
});
});
Expand All @@ -349,9 +351,8 @@ QuickSpecEnd
### Temporarily Disabling Examples or Groups Using `pending`
For examples that don't pass yet, use `pending` in Swift, or
`qck_pending` in Objective-C. Pending examples are not run,
but are printed out along with the test results.
For examples that don't pass yet, use `pending`. Pending examples
are not run, but are printed out along with the test results.
The example below marks the cases in which the dolphin is close to
something interesting as "pending"--perhaps that functionality hasn't
Expand All @@ -369,16 +370,15 @@ pending("when the dolphin is near something interesting") {
```objc
// Objective-C

qck_pending(@"when the dolphin is near something interesting", ^{
pending(@"when the dolphin is near something interesting", ^{
// ...none of the code in this closure will be run.
});
```
#### Shorthand syntax
Examples and groups can also be marked as pending by using
`xdescribe`, `xcontext`, and `xit` in Swift, and `qck_xdescribe`,
`qck_xcontext`, and `qck_xit` in Objective-C.
`xdescribe`, `xcontext`, and `xit`:
```swift
// Swift
Expand All @@ -399,15 +399,15 @@ xit("is only emitted once") {
```objc
// Objective-C

qck_xdescribe(@"its click", ^{
xdescribe(@"its click", ^{
// ...none of the code in this closure will be run.
});

qck_xcontext(@"when the dolphin is not near anything interesting", ^{
xcontext(@"when the dolphin is not near anything interesting", ^{
// ...none of the code in this closure will be run.
});

qck_xit(@"is only emitted once", ^{
xit(@"is only emitted once", ^{
// ...none of the code in this closure will be run.
});
```
Expand Down Expand Up @@ -451,16 +451,16 @@ class DolphinSpec: QuickSpec {

QuickSpecBegin(DolphinSpec)

qck_beforeSuite(^{
beforeSuite(^{
[OceanDatabase createDatabase:@"test.db"];
[OceanDatabase connectToDatabase:@"test.db"];
});

qck_afterSuite(^{
afterSuite(^{
[OceanDatabase teardownDatabase:@"test.db"];
});

qck_describe(@"a dolphin", ^{
describe(@"a dolphin", ^{
// ...
});

Expand Down Expand Up @@ -594,6 +594,28 @@ itBehavesLike("everything under the sea")
argument. Sorry, but that's the way the cookie crumbles!
:cookie: :bomb:

## Using Quick in Objective-C: The Optional Shorthand Syntax

Quick works equally well in both Swift and Objective-C.

Importing Quick in an Objective-C file defines macros such as `it`,
`context`, and `describe`. It's possible that the project you are
testing also defines symbols with these same names. In that case, you
can avoid namespace collision by turning off Quick's optional "shorthand" syntax:

```objc
#define QUICK_DISABLE_SHORT_SYNTAX 1

#import <Quick/Quick.h>

QuickSpecBegin(DolphinSpec)
// ...
QuickSpecEnd
```
You must define the `QUICK_DISABLE_SHORT_SYNTAX` macro *before*
importing the Quick header.
## Nimble: Assertions Using `expect(...).to`
Quick provides an easy language to define examples and example groups. Within those
Expand Down

0 comments on commit f656a4e

Please sign in to comment.