Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: facebook/jscodeshift
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 11981ad8ad5e550a273c4194ea53c14b7806ac8a
Choose a base ref
...
head repository: facebook/jscodeshift
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 855f565b818b2c3a86de9084436f1ef6a9fad8b9
Choose a head ref
  • 13 commits
  • 15 files changed
  • 10 contributors

Commits on Mar 7, 2018

  1. Fix error handling for http (#242)

    The reject handler were always called no matter if there was an
    error or not.
    BridgeAR authored and fkling committed Mar 7, 2018
    Copy the full SHA
    ccab1fc View commit details
  2. Copy the full SHA
    b0925fb View commit details
  3. Copy the full SHA
    9bc0c04 View commit details
  4. Update README.md (#221)

    Capitalize API
    piperchester authored and fkling committed Mar 7, 2018
    Copy the full SHA
    72bb6be View commit details
  5. Add Code of Conduct (#231)

    * Add link to COC in `CONTRIBUTING.md`
    
    We are about to add a COC and it makes sense to surface it here.
    
    * Add `CODE_OF_CONDUCT.md`
    
    In the past Facebook didn't promote including a Code of Conduct when creating new projects, and many projects skipped this important document. Let's fix it. :)
    
    **why make this change?:**
    Facebook Open Source provides a Code of Conduct statement for all
    projects to follow, to promote a welcoming and safe open source community.
    
    Exposing the COC via a separate markdown file is a standard being
    promoted by Github via the Community Profile in order to meet their Open
    Source Guide's recommended community standards.
    
    As you can see, adding this file will improve [the jscodeshift community profile](https://github.com/facebook/jscodeshift/community)
    checklist and increase the visibility of our COC.
    
    **test plan:**
    Viewing it on my branch -
    (Flarnie will insert screenshots)
    
    **issue:**
    internal task t23481323
    flarnie authored and fkling committed Mar 7, 2018
    Copy the full SHA
    d69f700 View commit details
  6. Copy the full SHA
    2f062e1 View commit details
  7. Allow specifying a testName for inline tests (#218)

    * Allow specifying a testName for inline tests
    
    This is a small change that makes test output a bit nicer when writing
    multiple inline tests.
    
    * Update readme
    iancw authored and fkling committed Mar 7, 2018
    Copy the full SHA
    32cc779 View commit details
  8. Copy the full SHA
    e60662b View commit details
  9. Fix renameTo not taking property shorthands into account (#211)

    * Fix `renameTo` not taking property shorthands into account
    
    This fixes the `renameTo` helper method not properly renaming
    object properties that are shorthands.
    
    The previous version of the code would rename the property's
    `value` correctly, but since `shorthand` was still set as `true`,
    the output result would still be the old variable as a shorthand
    property.
    
    Now, if an identifier to be renamed is of type `Property` and
    is a shorthand (but not a method), we flip the `shorthand` value
    to be `false`.
    
    * babel -> getParser()
    
    * Add comment that explains why this works
    vitorbal authored and fkling committed Mar 7, 2018
    Copy the full SHA
    99aaae5 View commit details
  10. Copy the full SHA
    aada675 View commit details
  11. Copy the full SHA
    84d2efc View commit details
  12. Copy the full SHA
    1034253 View commit details
  13. Copy the full SHA
    855f565 View commit details
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -2,5 +2,6 @@ sudo: false
language: node_js
node_js:
- 4
- 5
- 6
- 8
- stable
3 changes: 3 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Code of Conduct

Facebook has adopted a Code of Conduct that we expect project participants to adhere to. Please [read the full text](https://code.facebook.com/codeofconduct) so that you can understand what actions will and will not be tolerated.
3 changes: 3 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -2,6 +2,9 @@
We want to make contributing to this project as easy and transparent as
possible.

## Code of Conduct
The code of conduct is described in [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md)

## Our Development Process
The majority of development on jscodeshift will occur through GitHub. Accordingly,
the process for contributing will follow standard GitHub protocol.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -100,7 +100,7 @@ module.exports = function(fileInfo, api) {
}
```

**Note:** This api is exposed for convenience, but you don't have to use it.
**Note:** This API is exposed for convenience, but you don't have to use it.
You can use any tool to modify the source.

`stats` is a function that only works when the `--dry` options is set. It accepts
@@ -360,7 +360,7 @@ This will run two tests: One for `__testfixtures__/FirstFixture.input.js` and on
#### `defineInlineTest`
```js
const transform = require('../myTransform');
defineInlineTest(transform, {}, 'input', 'expected output');
defineInlineTest(transform, {}, 'input', 'expected output', 'test name (optional)');
```

### Example Codemods
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "jscodeshift",
"version": "0.4.1",
"version": "0.5.0",
"description": "A toolkit for JavaScript codemods",
"repository": {
"type": "git",
@@ -26,19 +26,19 @@
"author": "Felix Kling",
"license": "BSD-3-Clause",
"dependencies": {
"async": "^1.5.0",
"babel-plugin-transform-flow-strip-types": "^6.8.0",
"babel-preset-es2015": "^6.9.0",
"babel-preset-stage-1": "^6.5.0",
"babel-register": "^6.9.0",
"babylon": "^6.17.3",
"babylon": "^7.0.0-beta.30",
"colors": "^1.1.2",
"flow-parser": "^0.*",
"lodash": "^4.13.1",
"micromatch": "^2.3.7",
"neo-async": "^2.5.0",
"node-dir": "0.1.8",
"nomnom": "^1.8.1",
"recast": "^0.12.5",
"recast": "^0.14.1",
"temp": "^0.8.1",
"write-file-atomic": "^1.2.0"
},
1 change: 1 addition & 0 deletions parser/babylon.js
Original file line number Diff line number Diff line change
@@ -31,6 +31,7 @@ const options = {
'asyncGenerators',
'functionBind',
'functionSent',
'dynamicImport',
],
};

5 changes: 5 additions & 0 deletions sample/__tests__/reverse-identifiers-test.js
Original file line number Diff line number Diff line change
@@ -33,4 +33,9 @@ var droWtsrif = 'Hello ';
var droWdnoces = 'world';
var egassem = droWtsrif + droWdnoces;
`);
defineInlineTest(transform, {},
'function aFunction() {};',
'function noitcnuFa() {};',
'Reverses function names'
);
});
24 changes: 24 additions & 0 deletions src/Collection.js
Original file line number Diff line number Diff line change
@@ -78,6 +78,30 @@ class Collection {
return this;
}

/**
* Tests whether at-least one path passes the test implemented by the provided callback.
*
* @param {function} callback
* @return {boolean}
*/
some(callback) {
return this.__paths.some(
(path, i, paths) => callback.call(path, path, i, paths)
);
}

/**
* Tests whether all paths pass the test implemented by the provided callback.
*
* @param {function} callback
* @return {boolean}
*/
every(callback) {
return this.__paths.every(
(path, i, paths) => callback.call(path, path, i, paths)
);
}

/**
* Executes the callback for every path in the collection and returns a new
* collection from the return values (which must be paths).
14 changes: 8 additions & 6 deletions src/Runner.js
Original file line number Diff line number Diff line change
@@ -157,17 +157,19 @@ function run(transformFile, paths, options) {
})
.on('end', () => {
temp.open('jscodeshift', (err, info) => {
reject(err);
fs.write(info.fd, contents);
fs.close(info.fd, function(err) {
reject(err);
transform(info.path).then(resolve, reject);
if (err) return reject(err);
fs.write(info.fd, contents, function (err) {
if (err) return reject(err);
fs.close(info.fd, function(err) {
if (err) return reject(err);
transform(info.path).then(resolve, reject);
});
});
});
})
})
.on('error', (e) => {
reject(e.message);
reject(e);
});
});
} else if (!fs.existsSync(transformFile)) {
2 changes: 1 addition & 1 deletion src/Worker.js
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@

const EventEmitter = require('events').EventEmitter;

const async = require('async');
const async = require('neo-async');
const fs = require('fs');
const writeFileAtomic = require('write-file-atomic');
const getParser = require('./getParser');
40 changes: 40 additions & 0 deletions src/__tests__/Collection-test.js
Original file line number Diff line number Diff line change
@@ -234,6 +234,46 @@ describe('Collection API', function() {
});
});

describe('some', function() {
it('lets you test each element of a collection and stops when one passes the test', function() {
const each = jest.genMockFunction().mockImplementation(() => true);
Collection.fromNodes(nodes).some(each);

expect(each.mock.calls.length).toBe(1);
expect(each.mock.calls[0][0].value).toBe(nodes[0]);
});

it('returns true if at least one element passes the test', function() {
const result = Collection.fromNodes(nodes).some((_, i) => i === 1);
expect(result).toBe(true);
});

it('returns false if no elements pass the test', function() {
const result = Collection.fromNodes(nodes).some(() => false);
expect(result).toBe(false);
});
});

describe('every', function() {
it('lets you test each element of a collection and stops when one fails the test', function() {
const each = jest.genMockFunction().mockImplementation(() => false);
Collection.fromNodes(nodes).every(each);

expect(each.mock.calls.length).toBe(1);
expect(each.mock.calls[0][0].value).toBe(nodes[0]);
});

it('returns true if all elements pass the test', function() {
const result = Collection.fromNodes(nodes).every(() => true);
expect(result).toBe(true);
});

it('returns false if at least one element does not pass the test', function() {
const result = Collection.fromNodes(nodes).every((_, i) => i === 1);
expect(result).toBe(false);
});
});

describe('map', function() {
it('returns a new collection with mapped values', function() {
const root = Collection.fromNodes(nodes);
24 changes: 24 additions & 0 deletions src/collections/VariableDeclarator.js
Original file line number Diff line number Diff line change
@@ -114,6 +114,15 @@ const transformMethods = {
return false;
}

if (
types.JSXAttribute.check(parent) &&
parent.name === path.node &&
!parent.computed
) {
// <Foo oldName={oldName} />
return false;
}

return true;
})
.forEach(function(path) {
@@ -125,6 +134,21 @@ const transformMethods = {
scope = scope.parent;
}
if (scope) { // identifier must refer to declared variable

// It may look like we filtered out properties,
// but the filter only ignored property "keys", not "value"s
// In shorthand properties, "key" and "value" both have an
// Identifier with the same structure.
const parent = path.parent.node;
if (
types.Property.check(parent) &&
parent.shorthand &&
!parent.method
) {

path.parent.get('shorthand').replace(false);
}

path.get('name').replace(newName);
}
});
43 changes: 43 additions & 0 deletions src/collections/__tests__/VariableDeclarator-test.js
Original file line number Diff line number Diff line change
@@ -53,6 +53,7 @@ describe('VariableDeclarators', function() {
' blah() {}',
' }',
'}',
'<Component foo={foo} />',
].join('\n'), {parser: getParser()}).program];
});

@@ -127,6 +128,48 @@ describe('VariableDeclarators', function() {

expect(identifiers.length).toBe(1);
});

it('properly renames a shorthand property that was using the old variable name', function() {
nodes = [recast.parse([
'var foo = 42;',
'var obj2 = {',
' foo,',
'};',
].join('\n'), {parser: getParser()}).program];

// Outputs:
// var newFoo = 42;
// var obj2 = {
// foo: newFoo,
// };
Collection.fromNodes(nodes)
.findVariableDeclarators('foo').renameTo('newFoo');

expect(
Collection.fromNodes(nodes).find(types.Identifier, { name: 'newFoo' }).length
).toBe(2);
expect(
Collection.fromNodes(nodes).find(types.Identifier, { name: 'foo' }).length
).toBe(1);

expect(
Collection.fromNodes(nodes).find(types.Property).filter(prop => !prop.value.shorthand).length
).toBe(1);
expect(
Collection.fromNodes(nodes).find(types.Property).filter(prop => prop.value.shorthand).length
).toBe(0);
});

it('does not rename React component prop name', function () {
const declarators = Collection.fromNodes(nodes)
.findVariableDeclarators('foo')
.renameTo('xyz');

const identifiers = Collection.fromNodes(nodes)
.find(types.JSXIdentifier, { name: 'foo' });

expect(identifiers.length).toBe(1);
});
});

});
4 changes: 2 additions & 2 deletions src/testUtils.js
Original file line number Diff line number Diff line change
@@ -93,8 +93,8 @@ function defineTest(dirName, transformName, options, testFilePrefix) {
}
exports.defineTest = defineTest;

function defineInlineTest(module, options, input, expectedOutput) {
it('transforms correctly', () => {
function defineInlineTest(module, options, input, expectedOutput, testName) {
it(testName || 'transforms correctly', () => {
runInlineTest(module, options, {
source: input
}, expectedOutput);
Loading