Files
freeCodeCamp/common/app/routes/Challenges/rechallenge/transformers.js
Berkeley Martinez b2b1426e22 Feat: react redux migration (#16200)
* feat: crudely enables test to run solution code against React challenge (and passes!)

* feat: Updates comment

* feat: Adds React 2 and 3, validates challenges in app

* feat: Adds React 4, validates tests

* feat: Adds Peter's migrated challenge seed files for all challenges

* feat: Adds redux, react-redux imports, adds tests for React 7,

* feat: Adds tests for React 08

* fix(challenges): wrap reserved words in <code> and add tests

* feat: complete first two tests for React 9

* feat: modifies tests in React 09

* feat: Adds working tests for React 37, including async setState tests

* feat: Escape hatch to avoid async tests in automated test suite

* feat: Updates React 15 with working tests

* feat: build passes, yay

* feat: Provisions original code string in challenges and adds tests for React Redux 01

* fix(tests): add self-closing tags challenge, other small fixes

* fix(challenge): add react_10, some other stuff

* fix(challenges): update react 22, add react 23

* fix(challenges): react 5 and react 8

* feat: removes dependencies that will break in browser, will replace later

* feat: fix build

* feat: add redux 1

* fix(challenge): add react 24 tests

* feat: partial implemented Redux 2

* feat: migrate redux 3

* feat: Adds React-Redux 04 with working tests under npm test

* feat: Updates automated test runner, just provide all the dependencies. Adds Redux-Thunk.

* feat: Adds working tests for React Redux 07

* feat: redux challenge 4

* feat: migrate redux 5

* feat: redux 6

* feat: migrate Redux test 7

* fix(challenge): add react 25 tests

* feat: Adds tests for React 48, npm test does not pass...

* feat: Migrate Redux test 8

* fix(challenges): skip 26, add react 27 tests

* fix(challenges): add react 28 tests, replace function w/ => throughout, fix linter warnings

* feat: fixes (patches) hard to understand problem with automated test suite

* feat: updates async tests patch

* feat: adds converted tests for React 47

* feat: adds converted tests for React 46

* feat: Partially adds tests for React 43

* docs: adds TO-DO tests for React 43

* feat: migrates tests for React 42

* feat: migrates tests for React 41

* feat: migrates tests for React 39

* feat: Migrates tests for React 38, automated test script fails again!

* feat: migrates tests for React 32

* feat: QAs more React Redux challenge in FCC UI

* feat: Updates tests for React 7

* feat: Migrates React-Redux 3 tests and hardcodes deep-freeze dependency

* feat: migrates React Redux 05 tests

* feat: migrates React Redux 06 tests

* feat: Migrates React Redux 10

* feat: Migrates tests for React 16

* feat: Migrates React 17 tests

* feat: Migrates React 18 tests

* feat: Migrates React 19 tests

* feat: Migrates React 19 tests

* feat: fixing usage of code, replace with editor.getOriginalCode

* feat: Migrates React 21 tests

* feat: Finishes migration of React 09

* fix(challenges): add react 45 tests 💀

* feat: Adds React 11 tests

* feat: Migrates React 50 tests

* feat: Re-enables original code in FCC editor, QAs challenges blocked by original code

* feat: hacks head tail code in editor test environment

* feat: updates React 20 head code

* feat: QAs React Redux 07 in UI

* fix(challenges): add React 29 tests

* fix(challenges): add React 30 tests

* feat: updates async tests

* feat: Migrates React 12, gets ReactDOM challenges working and QAs them

* feat: Migrates React 13 tests

* feat: Migrates tests for React 14 and updates challenge description formatting

* feat: Refactors 2nd test for Redux 02

* feat: Migrates React 33

* feat: Removes React 26 and 43

* feat: Adds React 34 from Kevin

* fix(challenges): add React 31 & 35 tests (thanks Kevin)

* feat: Migrate Redux challenge 10 - pass both UI QA and terminal test

* fix(challenge): add react 40 tests

* feat: Migrates React Redux 02 tests

* feat: Migrates React Redux 08 and fixes async syntax in React challenge

* fix(challenge): add react 49 tests with caveat

* feat: fixes React 49 tests and adds first tests for React Redux 09

* feat: Migrate Redux 11 - pass both terminal test and UI test

* feat: Migrate Redux 12 - passing both UI test and terminal test

* feat: Migrate Redux 13 - passing both terminal and UI tests

* feat: Adding in code tags for previous redux challenges - terminal and UI tests pass

* feat: Migrates React Redux 09 and React 44 (thanks Kevin)

* feat: fix code tag issues - passed UI and terminal tests

* feat: Migrates Redux 14 tests

* feat: Migrates Redux 14

* feat: Migrates Redux 15

* feat: Migrates Redux 17

* feat: Final migration and QA of Redux, except for Redux 9

* feat: migrates React 36 and QAs

* feat: Rewrites Redux 09 and migrates

* feat: refactors pull request and cleans up code

* style(challenges): QA React challenges

* style(challenges): QA react challenges

* fix(challenges): fix react 41 and 45 tests

* style(challenges): QA redux challenges

* style(challenges): QA react and redux challenges

* fix(seed/react): Move head/tail to files

* fix(seed/redux): Move head/tail to file level

* chore(packages): Move jsdom to dev deps

* fix(seed/react/redux): Async funcs

make async func defined

* fix(seed): %s/editor.getUserCode/getUserInput/gc

* fix(Challenges/build): Make sure head/tail is bundled and transformed

* feat(Challenges.react): Add tail to render component

* chore(seed): Disable modern challenge testing for now

We will put these on beta while we update the auto testing framework
2017-12-18 15:04:03 -06:00

108 lines
2.9 KiB
JavaScript

import _ from 'lodash';
import * as babel from 'babel-core';
import presetEs2015 from 'babel-preset-es2015';
import presetReact from 'babel-preset-react';
import { Observable } from 'rx';
import * as vinyl from '../../../../utils/polyvinyl.js';
import castToObservable from '../../../utils/cast-to-observable.js';
const babelOptions = { presets: [ presetEs2015, presetReact ] };
const babelTransformCode = code => babel.transform(code, babelOptions).code;
function loopProtectHit(line) {
var err = 'Exiting potential infinite loop at line ' +
line +
'. To disable loop protection, write: \n\/\/ noprotect\nas the first ' +
'line. Beware that if you do have an infinite loop in your code, ' +
'this will crash your browser.';
throw new Error(err);
}
// const sourceReg =
// /(<!-- fcc-start-source -->)([\s\S]*?)(?=<!-- fcc-end-source -->)/g;
const console$logReg = /(?:\b)console(\.log\S+)/g;
const NBSPReg = new RegExp(String.fromCharCode(160), 'g');
const isJS = _.matchesProperty('ext', 'js');
const testHTMLJS = _.overSome(isJS, _.matchesProperty('ext', 'html'));
const testJS$JSX = _.overSome(isJS, _.matchesProperty('ext', 'jsx'));
// if shouldProxyConsole then we change instances of console log
// to `window.__console.log`
// this let's us tap into logging into the console.
// currently we only do this to the main window and not the test window
export const proxyLoggerTransformer = _.partial(
vinyl.transformHeadTailAndContents,
source => (
source.replace(console$logReg, (match, methodCall) => {
return 'window.__console' + methodCall;
})),
);
const addLoopProtect = _.partial(
vinyl.transformContents,
contents => {
/* eslint-disable import/no-unresolved */
const loopProtect = require('loop-protect');
/* eslint-enable import/no-unresolved */
loopProtect.hit = loopProtectHit;
return loopProtect(contents);
}
);
export const addLoopProtectHtmlJsJsx = _.cond([
[
_.overEvery(
testHTMLJS,
_.partial(
vinyl.testContents,
contents => contents.toLowerCase().includes('<script>')
)
),
addLoopProtect
],
[ testJS$JSX, addLoopProtect ],
[ _.stubTrue, _.identity ]
]);
export const replaceNBSP = _.cond([
[
testHTMLJS,
_.partial(
vinyl.transformContents,
contents => contents.replace(NBSPReg, ' ')
)
],
[ _.stubTrue, _.identity ]
]);
export const babelTransformer = _.cond([
[
testJS$JSX,
_.flow(
_.partial(
vinyl.transformHeadTailAndContents,
babelTransformCode
),
_.partial(vinyl.setExt, 'js')
)
],
[ _.stubTrue, _.identity ]
]);
export const _transformers = [
addLoopProtectHtmlJsJsx,
replaceNBSP,
babelTransformer
];
export function applyTransformers(file, transformers = _transformers) {
return transformers.reduce(
(obs, transformer) => {
return obs.flatMap(file => castToObservable(transformer(file)));
},
Observable.of(file)
);
}