Repository: ViacomInc/data-point (js)

Issue:
codemod for PathReducer change of $. to $
**Problem description**:

#52  deprecates `$.` in favor of `$` which adds a breaking change

**Suggested solution**:

Create a codemod under data-point-codemds that will refactor any instance of `$.` to `$`

`'$.'` to `'$'` 
`'$. |..'` to `'$ |..'` 

applies to strings and string literals


Pull request description:
feat(data-point-codemods): Add codemod for changing PathReducer from $. to $
<!--
Thanks for your interest in the project. We appreciate bugs filed and PRs submitted!

Please make sure that you are familiar with and follow the Code of Conduct for
this project (found in the CODE_OF_CONDUCT.md file).

Also, please make sure you're familiar with and follow the instructions in the
contributing guidelines (found in the CONTRIBUTING.md file).

Please fill out the information below to expedite the review and (hopefully)
merge of your pull request!

BREAKING CHANGES:

If your PR includes a breaking change, please submit it with a codemod under
data-point-codemods that will help users upgrade their codebase.

Breaking changes without a codemod will not be accepted unless a codemod is not
viable or does not apply to the specific situation.
-->

<!-- What changes are being made? (What feature/bug is being fixed here?) -->
**What**: Adds a codemod to change `$.` to `$` if found in a string or template literal

<!-- Why are these changes necessary? -->
**Why**: Closes #179

<!-- How were these changes implemented? -->
**How**: http://http://astexplorer.net

<!-- 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
- [X] Documentation
- [X] Tests
- [X] Ready to be merged <!-- In your opinion, is this ready to be merged as soon as it's reviewed? -->
- [ ] Added username to **all-contributors** list

<!-- feel free to add additional comments -->


Patch:
diff --git a/packages/data-point-codemods/README.md b/packages/data-point-codemods/README.md
index c609be6..2df8236 100644
--- a/packages/data-point-codemods/README.md
+++ b/packages/data-point-codemods/README.md
@@ -38,6 +38,7 @@ data-point-codemods --help
 
 - ([codemod](transforms/reducer-args-acc-to-val-acc.js)) Refactor ReducerFunctions for value as first parameter eg. `(acc)` &rarr; `(input, acc)`. For more info please look at the [input](transforms/__testfixtures__/reducer-args-acc-to-val-acc.input.js)/[output](transforms/__testfixtures__/reducer-args-acc-to-val-acc.output.js) tests.
 
+- ([codemod](transforms/change-path-reducer-accessing-root-path.js)) Refactor PathReducers that access the root with `$.` to use `$`. For more info please look at the [input](transforms/__testfixtures__/change-path-reducer-accessing-root-path.input.js)/[output](transforms/__testfixtures__/change-path-reducer-accessing-root-path.output.js) tests.
 
 ## WARNING
 
diff --git a/packages/data-point-codemods/transforms/change-path-reducer-accessing-root-path.js b/packages/data-point-codemods/transforms/change-path-reducer-accessing-root-path.js
new file mode 100644
index 0000000..d21c809
--- /dev/null
+++ b/packages/data-point-codemods/transforms/change-path-reducer-accessing-root-path.js
@@ -0,0 +1,62 @@
+module.exports = (file, api) => {
+  const j = api.jscodeshift
+  const rootPathWithDotRegex = /\$\.(\s|$)/g
+
+  const root = j(file.source)
+
+  function detectQuoteStyle (j, root) {
+    let detectedQuoting = 'single'
+
+    root
+      .find(j.Literal, {
+        value: v => typeof v === 'string',
+        raw: v => typeof v === 'string'
+      })
+      .forEach(p => {
+        // The raw value is from the original babel source
+        if (p.value.raw[0] === "'") {
+          detectedQuoting = 'single'
+        }
+
+        if (p.value.raw[0] === '"') {
+          detectedQuoting = 'double'
+        }
+      })
+
+    return detectedQuoting
+  }
+
+  // transforms a string from '$. | $. | $.' -> '$ | $ | $'
+  function transformLiteral (node) {
+    const originalValue = node.value.value
+    if (rootPathWithDotRegex.test(originalValue)) {
+      node.value.value = node.value.value.replace(rootPathWithDotRegex, '$$$1')
+    }
+  }
+
+  // transforms a template literal from `$. | $. | $.` -> `$ | $ | $`
+  function transformTemplateElement (node) {
+    const originalValue = node.value.value.raw
+    if (rootPathWithDotRegex.test(originalValue)) {
+      node.value.value.raw = node.value.value.raw.replace(
+        rootPathWithDotRegex,
+        '$$$1'
+      )
+    }
+  }
+
+  function refactorReducerMatches (nodeType, transform) {
+    root.find(nodeType).forEach(transform)
+  }
+
+  refactorReducerMatches(j.Literal, transformLiteral)
+  refactorReducerMatches(j.TemplateElement, transformTemplateElement)
+
+  // As Recast is not preserving original quoting, we try to detect it,
+  // and default to something sane.
+  // See https://github.com/benjamn/recast/issues/171
+  // and https://github.com/facebook/jscodeshift/issues/143
+  // credit to @skovhus: https://github.com/avajs/ava-codemods/pull/28
+  const quote = detectQuoteStyle(j, root)
+  return root.toSource({ quote })
+}


Test patch:
diff --git a/packages/data-point-codemods/transforms/__testfixtures__/change-path-reducer-accessing-root-path-double-quote.input.js b/packages/data-point-codemods/transforms/__testfixtures__/change-path-reducer-accessing-root-path-double-quote.input.js
new file mode 100644
index 0000000..125d409
--- /dev/null
+++ b/packages/data-point-codemods/transforms/__testfixtures__/change-path-reducer-accessing-root-path-double-quote.input.js
@@ -0,0 +1,22 @@
+/* eslint-disable */
+/* eslint-disable prettier */
+
+// prettier-ignore
+const entities = {
+  'transform:a': `$.`,
+  'transform:b': `$. | foo | $.`,
+  'transform:c': `foo | bar | baz`,
+  'transform:d': "$.",
+  'transform:e': "$. | foo",
+  'transform:f': "$. | $. | $.",
+  'transform:g': "foo | bar | baz",
+  nested: {
+    object: {
+      a: "$. | $."
+    },
+    array: ["$.", "'$.", "$."]
+  }
+}
+
+// prettier-ignore
+dataPoint.transform("foo | $. | baz | $.")
diff --git a/packages/data-point-codemods/transforms/__testfixtures__/change-path-reducer-accessing-root-path-double-quote.output.js b/packages/data-point-codemods/transforms/__testfixtures__/change-path-reducer-accessing-root-path-double-quote.output.js
new file mode 100644
index 0000000..12624ba
--- /dev/null
+++ b/packages/data-point-codemods/transforms/__testfixtures__/change-path-reducer-accessing-root-path-double-quote.output.js
@@ -0,0 +1,22 @@
+/* eslint-disable */
+/* eslint-disable prettier */
+
+// prettier-ignore
+const entities = {
+  'transform:a': `$`,
+  'transform:b': `$ | foo | $`,
+  'transform:c': `foo | bar | baz`,
+  'transform:d': "$",
+  'transform:e': "$ | foo",
+  'transform:f': "$ | $ | $",
+  'transform:g': "foo | bar | baz",
+  nested: {
+    object: {
+      a: "$ | $"
+    },
+    array: ["$", "'$", "$"]
+  }
+}
+
+// prettier-ignore
+dataPoint.transform("foo | $ | baz | $")
diff --git a/packages/data-point-codemods/transforms/__testfixtures__/change-path-reducer-accessing-root-path-single-quote.input.js b/packages/data-point-codemods/transforms/__testfixtures__/change-path-reducer-accessing-root-path-single-quote.input.js
new file mode 100644
index 0000000..bbe8274
--- /dev/null
+++ b/packages/data-point-codemods/transforms/__testfixtures__/change-path-reducer-accessing-root-path-single-quote.input.js
@@ -0,0 +1,21 @@
+/* eslint-disable */
+/* eslint-disable prettier */
+
+// prettier-ignore
+const entities = {
+  'transform:a': `$.`,
+  'transform:b': `$. | foo | $.`,
+  'transform:c': `foo | bar | baz`,
+  'transform:d': '$.',
+  'transform:e': '$. | foo',
+  'transform:f': '$. | $. | $.',
+  'transform:g': 'foo | bar | baz',
+  nested: {
+    object: {
+      a: '$. | $.'
+    },
+    array: ['$.', '$.', '$.']
+  }
+}
+
+dataPoint.transform('foo | $. | baz | $.')
diff --git a/packages/data-point-codemods/transforms/__testfixtures__/change-path-reducer-accessing-root-path-single-quote.output.js b/packages/data-point-codemods/transforms/__testfixtures__/change-path-reducer-accessing-root-path-single-quote.output.js
new file mode 100644
index 0000000..d56ce5a
--- /dev/null
+++ b/packages/data-point-codemods/transforms/__testfixtures__/change-path-reducer-accessing-root-path-single-quote.output.js
@@ -0,0 +1,21 @@
+/* eslint-disable */
+/* eslint-disable prettier */
+
+// prettier-ignore
+const entities = {
+  'transform:a': `$`,
+  'transform:b': `$ | foo | $`,
+  'transform:c': `foo | bar | baz`,
+  'transform:d': '$',
+  'transform:e': '$ | foo',
+  'transform:f': '$ | $ | $',
+  'transform:g': 'foo | bar | baz',
+  nested: {
+    object: {
+      a: '$ | $'
+    },
+    array: ['$', '$', '$']
+  }
+}
+
+dataPoint.transform('foo | $ | baz | $')
diff --git a/packages/data-point-codemods/transforms/__tests__/change-path-reducer-accessing-root-path.test.js b/packages/data-point-codemods/transforms/__tests__/change-path-reducer-accessing-root-path.test.js
new file mode 100644
index 0000000..551f84b
--- /dev/null
+++ b/packages/data-point-codemods/transforms/__tests__/change-path-reducer-accessing-root-path.test.js
@@ -0,0 +1,21 @@
+/* eslint-env jest */
+
+'use strict'
+
+const { defineTest } = require('jscodeshift/dist/testUtils')
+
+// single quote
+defineTest(
+  __dirname,
+  'change-path-reducer-accessing-root-path',
+  null,
+  'change-path-reducer-accessing-root-path-single-quote'
+)
+
+// double quote
+defineTest(
+  __dirname,
+  'change-path-reducer-accessing-root-path',
+  null,
+  'change-path-reducer-accessing-root-path-double-quote'
+)