Skip to content
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

Symbols must be stringified explicitly #301

Merged
merged 2 commits into from
Jan 18, 2018
Merged

Conversation

jasonkarns
Copy link
Member

@jasonkarns jasonkarns commented Nov 17, 2017

Apparently (nodejs/node#927 (comment)),
Symbols cannot be implicitly coerced to string.

Template stringification leverages implicit coercion, so we must
stringify propKey before sending it to the template.

Options for explicitly stringifying:

  • String(propKey)
  • String.prototype.toString(propKey)

Differences:

> String(undefined)
'undefined'
> String.prototype.toString(undefined)
''

In this case, propKey represents the key for the stubbed function. If
the key is undefined, it would be implicitly coerced to "undefined"
as the property key. So String() is the explicit converstion we want.

fixes #300 and perhaps maybe fixes #124 ?

@searls
Copy link
Member

searls commented Nov 17, 2017

Is there a test you could add for this?

@jasonkarns
Copy link
Member Author

tests in progress. Also found 3 other places where this bug can manifest:

So there are 4 total instances in all. Two of which use . as a dot-notation prefix for the method, and one uses # ala ruby's "method" prefix. Do we care to switch to [Symbol(x)] style function name, as that's the common idiom when using or describing Symbols-as-method-names? Without special handling, a symbol name could end up with a tdFunction name as:

foo.Symbol(bar), or #Symbol(bar), or just .Symbol(bar)

@jasonkarns jasonkarns force-pushed the fix-symbol-to-string branch 2 times, most recently from af60601 to 8b2b9c3 Compare November 18, 2017 05:00
@jasonkarns
Copy link
Member Author

First commit is minimal change to fix the issue (just explicitly stringify the keynames)...

Second commit is an "improvement" to make the key names more idiomatic when stringified. (Symbol keys are wrapped in brackets). Not sure it's worth the extra code, though. Maybe something to revisit after the rewrite? I can nuke the second commit if we'd like to just do the minimal fix for now.

@searls
Copy link
Member

searls commented Dec 20, 2017

Is this done?

@jasonkarns
Copy link
Member Author

Yeah, it's ready if you're fine with the slight change to the stringified output of the function names (second commit)

@searls
Copy link
Member

searls commented Jan 16, 2018

Hey @jasonkarns, apologies that I just got around to reading this (mea culpa). My feeling is that since I'm still mid-rewrite (😭), I don't want to add any superfluous branching anywhere I can avoid it, so I'd really rather merge this fix in without any changes to the stringy output.

Could you update with changes that just make the fix without adding the […] wrapper to symbol func names?

@jasonkarns
Copy link
Member Author

@searls done. there were already separate commits, so i just removed the latter one from the PR

@@ -11,7 +11,7 @@ export default (original, names) => {
return original
} else {
// TODO: this will become src/function/create and include parent reference instead of name joining here
return tdFunction(names.join('') || '(anonymous function)')
return tdFunction(names.map(String).join('') || '(anonymous function)')
Copy link
Member

Choose a reason for hiding this comment

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

Can you please use _.map for this? We're using lodash for all of our enumerable methods everywhere else, and there's a tacit (but not explicit) support for ancient browsers / IE etc that won't have Array.prototype.map defined.

@jasonkarns
Copy link
Member Author

@searls _.map 👍

@searls
Copy link
Member

searls commented Jan 16, 2018

Travis is having some downtime so I'm not going to watch this all day. How about you merge & release yourself (once Travis finishes), using this new guide I just wrote? https://github.com/testdouble/testdouble.js/blob/master/RELEASE.md

@jasonkarns
Copy link
Member Author

Ugh. test:example tests are failing, but they also fail at the merge-base with master :(

Probably gonna rebase to latest master, if that's green...

@searls
Copy link
Member

searls commented Jan 17, 2018 via email

Apparently (nodejs/node#927 (comment)),
Symbols cannot be implicitly coerced to string.

Template stringification leverages implicit coercion, so we must
stringify propKey before sending it to the template.

Options for explicitly stringifying:

- `String(propKey)`
- `String.prototype.toString(propKey)`

Differences:

```
> String(undefined)
'undefined'
> String.prototype.toString(undefined)
''
```

In this case, `propKey` represents the key for the stubbed function. If
the key is `undefined`, it would be implicitly coerced to `"undefined"`
as the property key. So `String()` is the explicit converstion we want.

Four instances of this issue, each where tdFunction is invoked with a
dynamic name.
@jasonkarns jasonkarns merged commit f3e6f45 into master Jan 18, 2018
@jasonkarns jasonkarns deleted the fix-symbol-to-string branch January 18, 2018 15:06
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.

Cannot convert a Symbol value to a string td.callback, when given a td.object, raises a TypeError
2 participants