Skip to content

Integration.prototype.map — add support for array type #45

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 2 commits into from
Jun 24, 2015
Merged

Conversation

sperand-io
Copy link
Contributor

This PR adds support for mapping basic arrays of strings, a structure used in metadata to store conversion events for such integrations as Steelhouse:

@ndhoule

@ndhoule ndhoule self-assigned this Jun 17, 2015
@sperand-io
Copy link
Contributor Author

ping :)

if (type(events) === 'array') {
// If there's no key attached to this event mapping (unusual), skip this
// item.
if (!val.key) return matchingEvents;
Copy link
Contributor

Choose a reason for hiding this comment

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

This case no longer gets handled, which means if key is a non-string (easy way for this to happen is null or just missing) then we try to do string replacement on a non-string and get an uncaught exception.

Example case:

it('should handle non-string keys gracefully', function() {
  var obj = [{ key: null, value: '1121f10f' }];
  assert([], integration.map(obj, 'event'));
});

@ndhoule ndhoule changed the title Integration.prototype.map — fix regression: map arrays of strings Integration.prototype.map — add support for array type Jun 19, 2015
@ndhoule
Copy link
Contributor

ndhoule commented Jun 19, 2015

This isn't a regression, this method was never designed to support arrays of strings

// Extract the key and value from the `mixed` object.
key = val.key;
val = val.value;
switch (type(val)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

switches are rarely clearer than ifs and are more error prone, prefer if

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Per usual, just following precedent: https://github.com/segmentio/analytics.js-integration/blob/master/lib/protos.js#L244-L266

I'm all for clarity, but if we are going to start imposing rules going forward we need a style guide so that we have an opportunity to catch ourselves before asking for review.

@ndhoule ndhoule assigned sperand-io and unassigned ndhoule Jun 19, 2015
@@ -367,9 +367,9 @@ describe('integration', function(){
});

describe('when .options.events is an array', function(){
Copy link
Contributor

Choose a reason for hiding this comment

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

Restructure these tests more clearly around the different types we intend for this to handle, which will give clarity to exactly what map can handle and what it can't

Copy link
Contributor Author

Choose a reason for hiding this comment

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

definitely. good call.

@sperand-io sperand-io force-pushed the map/array branch 2 times, most recently from 61765ec to 1f781c1 Compare June 23, 2015 05:27
@sperand-io
Copy link
Contributor Author

Updated in line with comments (thanks!). You're right, looks like this never supported arrays in the first place, but it definitely should. The steelhouse integration is the first that really requires this functionality, and the faster we get that fix out the better.

if (type(mapping) === 'array' && every(isString, mapping)) return 'array';
if (type(mapping) === 'array' && every(isMixed, mapping)) return 'mixed';
return 'unknown';
}
Copy link
Contributor

Choose a reason for hiding this comment

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

These functions get unnecessarily redeclared every time we call #map; move them outside this function scope

Copy link
Contributor Author

Choose a reason for hiding this comment

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

check

@sperand-io sperand-io force-pushed the map/array branch 2 times, most recently from 2e149b9 to 838b9c4 Compare June 23, 2015 06:56
@sperand-io
Copy link
Contributor Author

think I got everything in latest pass. thanks for the careful eye and patient feedback

*
* @api private
* @param {Object} item
* @return {undefined}
Copy link
Contributor

Choose a reason for hiding this comment

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

Missing jsdoc return value


it('should return single matched values', function(){
var option = [{ key: 'bar', value: '4cff6219' }, { key: 'baz', value: '4426d54'} ];
assert(['4426d54'], integration.map(option, 'baz'));
Copy link
Contributor

Choose a reason for hiding this comment

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

should be assert.deepEqual

@ndhoule
Copy link
Contributor

ndhoule commented Jun 23, 2015

We should probably migrate Kenshoo sometime to use this new functionality, since it's been using an array of events for a while now, and this solution is improved in that it normalizes event names so they're not quite so strict. (We could have just used that solution in Steelhouse in the interim, but oh well)

I'm wrapping up the enterprise npm migration which is blocking deploys, so I'll let you fix this stuff while I wrap that up

@sperand-io
Copy link
Contributor Author

@ndhoule updated!

ndhoule pushed a commit that referenced this pull request Jun 24, 2015
Integration.prototype.map — add support for array type
@ndhoule ndhoule merged commit 198f785 into master Jun 24, 2015
ndhoule added a commit that referenced this pull request Jun 25, 2015
The refactors to prototype#map in [#45][] are a little too presumptuous
in that they assume the integration optons values stored in metadata are
always going to be strings, which is not the case

In the long run, trying to determine if something is an array or a map
or a mixed on the client is a pretty bad solution. We're essentially
reduced to duck typing metadata structures, which is not a good
solution.

Instead metadata should look like:

```js
{
  "type": "mixed",
  "data": [
    { key: "whatever", value: "whatever_value" },
    // ...
  ]
}
```

[#45]: #45
@hankim813 hankim813 deleted the map/array branch April 18, 2016 17:51
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.

2 participants