Skip to content

Basic macro support. #832

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
May 16, 2016
Merged

Basic macro support. #832

merged 6 commits into from
May 16, 2016

Conversation

jamestalmage
Copy link
Contributor

@jamestalmage jamestalmage commented May 14, 2016

This adds basic macro support as discussed in #695.

It does not completely implement the spec outlined there, specifically:

  • The macro can only specify the title using a function in macroFn.title. We discussed allowing macroFn.title to also be a string, and allowing some form of template language for extracting a title. However, using ES2015 string templates is already pretty easy, so we may just skip this.
  • We discussed allowing an array of macro functions.

Both the above proposals are found in this comment. They both enhance the implementation found in this commit, and would not break the contract. So I don't think there is anything preventing us from shipping this now.

@mention-bot
Copy link

By analyzing the blame information on this pull request, we identified @kasperlewau, @BarryThePenguin and @naptowncode to be potential reviewers

This adds basic macro support as discussed in avajs#695.

It does not completely implement the spec outlined there, specifically:

- The macro can only specify the title using a function in `macroFn.title`. We discussed allowing `macroFn.title` to also be a string, and allowing some form of template language for extracting a title. However, using ES2015 string templates is already pretty easy, so we may just skip this.
- We discussed allowing groups of tests to be created using arrays.

Both the above proposals are found in [this comment](avajs#695 (comment)). They both enhance the implementation found in this commit, and would not break the contract. So I don't think there is anything preventing us from shipping this now.
@nfcampos
Copy link
Contributor

The same reason that makes it worthwhile to pass arguments as an array to the test function without spreading them should make us want to give them as an array to test(), or is it somehow more likely we'll want in the future to introduce a third agumment to the test function than a last argument to test()?

test('2 * 3 === 6', macro, '2 * 3', 6);
```

You can build the test title programatically by attaching a `title` function to the macro:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

programmatically

@jfmengels
Copy link
Contributor

🎉 Yay, this is great @jamestalmage! Didn't know whether this was accepted, but glad it's going forward, it's a really nice feature IMO.

@@ -524,6 +524,33 @@ test.only.serial(...);

This means you can temporarily add `.skip` or `.only` at the end of a test or hook definition without having to make any other changes.

### Test macros

Additional arguments after the test function will be passed as an array to the test function. This is useful for creating reusable test macros.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it rather be "creating reusable tests"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That may be a cleaner way of saying it, but I'm trying to introduce the term. Maybe "reusable macros", but I think it's good as is.

@novemberborn
Copy link
Member

LGTM!

@jamestalmage
Copy link
Contributor Author

What about @nfcampos argument? Should it be arrays both places? Spread both places?

@novemberborn
Copy link
Member

Spread in the implementation does prevent us from adding any additional arguments, but having a third argument wouldn't be very pretty anyway.

An array in the declaration is just annoying and prone to confusion. So I guess I'm leaning towards spread in both places.

@jamestalmage
Copy link
Contributor Author

I'm leaning towards spread in both places.

Me too, but that pretty much closes that portion if the API from further expansion. That's a big decision, so let's wait for more input.

@jfmengels
Copy link
Contributor

I would've preferred spread in both places, but it does get tricky if you want to add new args.

If we go for spread and want to go for arrays later, then I think that writing a codemod will be kind of tricky. (easy in most cases, but hard when the macro is defined in a separate file).

I'd go for consistency at least: either spread in both places or arrays in both places.

@jamestalmage
Copy link
Contributor Author

jamestalmage commented May 15, 2016

Updated:

  • Switched to arg spreading everywhere.
  • Added array of macros support.

@jamestalmage
Copy link
Contributor Author

Should the macro.title function get passed title as the first arg?

function macroA() {...}
function macroB() {...}

macro.title = (title, ...remainingArgs) => title + ' - macroA';
macro.title = (title, ...remainingArgs) => title + ' - macroB';

test('groupA', [macroA, macroB], 'some', 'args');
test('groupB', [macroA, macroB], 'more', 'args');

results in the following test titles:

groupA - macroA
groupA - macroB
groupB - macroA
groupB - macroB

@novemberborn
Copy link
Member

Should the macro.title function get passed title as the first arg?

I think that'd be good, but it makes it harder to write macros since it'd be optional. I'm specifically thinking about adding a space separator:

macro.title = (prefix) => prefix + ' - macroA';

Let's assume prefix defaults to the empty string:

macro.title = (prefix) => (prefix ? prefix + ' - ' : '') + 'macroA';

Maybe if the resulting title is always trimmed on its left so you don't have to worry about the spacing?

@novemberborn
Copy link
Member

LGTMO!

@jfmengels
Copy link
Contributor

Should the macro.title function get passed title as the first arg?

👍

@jamestalmage
Copy link
Contributor Author

I think defaulting to the empty string is a good plan. That's still falsy. We should trim results both left and right I say.

@jamestalmage
Copy link
Contributor Author

For spacing, what if we allowed them to return an array of strings which we joined with a space character?

macro.title = (title) => [title, 'macroA'];

Or maybe we allow this:

macro.title = {prefix: 'macroA - '};
// or
macro.title = {suffix: ' - macroB'};

@jfmengels
Copy link
Contributor

I think the former is a bit unnatural. I'd say stick to a function, and seek to improve later it if it feels insufficient.

@jamestalmage
Copy link
Contributor Author

51bed36 passes title as first argument (or empty string if none provided).

I think this should be merge-able now.

@sindresorhus - Haven't heard much from you on this. Specifically, are you good with spreading the args?

Additional arguments passed to the test declaration will be passed to the test implementation. This is useful for creating reusable test macros.

```js
function macro(t, input, expected) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jamestalmage Good thing we decided not to pass the context as the second argument 😝

Copy link
Contributor Author

@jamestalmage jamestalmage May 16, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, eating my words on that. Though not as badly as I've been forced to eat these ones.

Then why are you bringing up the Babel plugin? Is that something someone would use IRL?

@sindresorhus
Copy link
Member

:shipit:

@jamestalmage jamestalmage merged commit a454128 into avajs:master May 16, 2016
@jamestalmage jamestalmage deleted the macro-support branch May 16, 2016 20:42
@jfmengels
Copy link
Contributor

🎉 Folks, 0.15 is starting to get pretty exciting :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants