Repository: ViacomInc/data-point (js)
Issue: Add a name to ReducerPath#body functions
**Problem description**:

`ReducerPath#body` functions are named `getFromAccumulatorValue`, which is not very pretty:

```js
ReducerPath {
  type: 'ReducerPath',
  name: 'a.b',
  body: [Function: bound getFromAccumulatorValue],
  asCollection: false
}
```

**Suggested solution**:

The name for these functions should be the source string that was used to create the `ReducerPath`:

```js
ReducerPath {
  type: 'ReducerPath',
  name: 'a.b',
  body: [Function: $a.b],
  asCollection: false
}
```

**Why?**

Because it's prettier.

Pull request description: feat(data-point/reducer-path): Add a custom name to ReducerPath#body functions
**What**: closes #182, and slightly refactors the code for setting `ReducerPath` object properties.

**Why**: Looks better when logging reducers to the console, and makes it more obvious what the `ReducerPath#body` function is doing.

<!-- How were these changes implemented? -->
**How**: `Object.defineProperty`

<!-- Have you done all of these things?  -->
**Checklist**:
<!-- add "N/A" to the end of each line that's irrelevant to your changes -->
<!-- to check an item, place an "x" in the box like so: "- [x] Documentation" -->
- [ ] Has Breaking changes
- [ ] Documentation
- [x] Tests
- [x] Ready to be merged

Patch:
diff --git a/packages/data-point/lib/reducer-types/reducer-path/factory.js b/packages/data-point/lib/reducer-types/reducer-path/factory.js
index 13d75c4..5415734 100644
--- a/packages/data-point/lib/reducer-types/reducer-path/factory.js
+++ b/packages/data-point/lib/reducer-types/reducer-path/factory.js
@@ -82,7 +82,7 @@ module.exports.mapFromAccumulatorValue = mapFromAccumulatorValue
  * @returns {Function}
  */
 function getPathReducerFunction (jsonPath, asCollection) {
-  if (jsonPath === '$' || _.isEmpty(jsonPath)) {
+  if (jsonPath === '$') {
     return getAccumulatorValue
   }
 
@@ -101,15 +101,16 @@ module.exports.getPathReducerFunction = getPathReducerFunction
 
 /**
  * @param {Function} createReducer
- * @param {string} source
+ * @param {string} source - must begin with $
  * @return {reducer}
  */
 function create (createReducer, source) {
   const reducer = new ReducerPath()
-
-  reducer.asCollection = source.slice(-2) === '[]'
-  reducer.name = (source.substr(1) || '$').replace(/\[]$/, '')
+  const value = source.replace(/\[]$/, '')
+  reducer.name = value.substr(1) || '$'
+  reducer.asCollection = source.endsWith('[]')
   reducer.body = getPathReducerFunction(reducer.name, reducer.asCollection)
+  Object.defineProperty(reducer.body, 'name', { value })
 
   return reducer
 }


Test patch:
diff --git a/packages/data-point/lib/reducer-types/reducer-path/factory.test.js b/packages/data-point/lib/reducer-types/reducer-path/factory.test.js
index 23ac790..072f58a 100644
--- a/packages/data-point/lib/reducer-types/reducer-path/factory.test.js
+++ b/packages/data-point/lib/reducer-types/reducer-path/factory.test.js
@@ -53,7 +53,6 @@ describe('ReducerPath getters', () => {
 
 describe('reducer/reducer-path#getPathReducerFunction', () => {
   it('should always return a function', () => {
-    expect(factory.getPathReducerFunction()).toBeInstanceOf(Function)
     expect(factory.getPathReducerFunction('')).toBeInstanceOf(Function)
     expect(factory.getPathReducerFunction('.')).toBeInstanceOf(Function)
     expect(factory.getPathReducerFunction('..')).toBeInstanceOf(Function)
@@ -63,36 +62,46 @@ describe('reducer/reducer-path#getPathReducerFunction', () => {
 })
 
 describe('reducer/reducer-path#create', () => {
-  it('basic path', () => {
-    const reducer = factory.create(createReducer, '$a')
+  it('empty path', () => {
+    const reducer = factory.create(createReducer, '$')
     expect(reducer.type).toBe('ReducerPath')
-    expect(reducer.name).toBe('a')
+    expect(reducer.name).toBe('$')
     expect(reducer.asCollection).toBe(false)
+    expect(reducer.body).toBeInstanceOf(Function)
+    expect(reducer.body.name).toBe('$')
   })
 
-  it('empty path', () => {
-    const reducer = factory.create(createReducer, '$')
+  it('basic path', () => {
+    const reducer = factory.create(createReducer, '$a')
     expect(reducer.type).toBe('ReducerPath')
-    expect(reducer.name).toBe('$')
+    expect(reducer.name).toBe('a')
     expect(reducer.asCollection).toBe(false)
+    expect(reducer.body).toBeInstanceOf(Function)
+    expect(reducer.body.name).toBe('$a')
   })
 
   it('compound path', () => {
     const reducer = factory.create(createReducer, '$foo.bar')
     expect(reducer.name).toBe('foo.bar')
     expect(reducer.asCollection).toBe(false)
+    expect(reducer.body).toBeInstanceOf(Function)
+    expect(reducer.body.name).toBe('$foo.bar')
   })
 
   it('compound path', () => {
     const reducer = factory.create(createReducer, '$foo.bar[0]')
     expect(reducer.name).toBe('foo.bar[0]')
     expect(reducer.asCollection).toBe(false)
+    expect(reducer.body).toBeInstanceOf(Function)
+    expect(reducer.body.name).toBe('$foo.bar[0]')
   })
 
   it('path with asCollection', () => {
     const reducer = factory.create(createReducer, '$foo.bar[]')
     expect(reducer.name).toBe('foo.bar')
     expect(reducer.asCollection).toBe(true)
+    expect(reducer.body).toBeInstanceOf(Function)
+    expect(reducer.body.name).toBe('$foo.bar')
   })
 })