139 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			139 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /* eslint-disable no-eval, no-process-exit */
 | |
| import _ from 'lodash';
 | |
| import { Observable } from 'rx';
 | |
| import tape from 'tape';
 | |
| import getChallenges from './getChallenges';
 | |
| 
 | |
| 
 | |
| function createIsAssert(t, isThing) {
 | |
|   const { assert } = t;
 | |
|   return function() {
 | |
|     const args = [...arguments];
 | |
|     args[0] = isThing(args[0]);
 | |
|     assert.apply(t, args);
 | |
|   };
 | |
| }
 | |
| 
 | |
| function fillAssert(t) {
 | |
|   const assert = t.assert;
 | |
| 
 | |
|   assert.isArray = createIsAssert(t, _.isArray);
 | |
|   assert.isBoolean = createIsAssert(t, _.isBoolean);
 | |
|   assert.isString = createIsAssert(t, _.isString);
 | |
|   assert.isNumber = createIsAssert(t, _.isNumber);
 | |
|   assert.isUndefined = createIsAssert(t, _.isUndefined);
 | |
| 
 | |
|   assert.deepEqual = t.deepEqual;
 | |
|   assert.equal = t.equal;
 | |
|   assert.strictEqual = t.equal;
 | |
| 
 | |
|   assert.sameMembers = function sameMembers() {
 | |
|     const [ first, second, ...args] = arguments;
 | |
|     assert.apply(
 | |
|       t,
 | |
|       [
 | |
|         _.difference(first, second).length === 0 &&
 | |
|         _.difference(second, first).length === 0
 | |
|       ].concat(args)
 | |
|     );
 | |
|   };
 | |
| 
 | |
|   assert.includeMembers = function includeMembers() {
 | |
|     const [ first, second, ...args] = arguments;
 | |
|     assert.apply(t, [_.difference(second, first).length === 0].concat(args));
 | |
|   };
 | |
| 
 | |
|   assert.match = function match() {
 | |
|     const [value, regex, ...args] = arguments;
 | |
|     assert.apply(t, [regex.test(value)].concat(args));
 | |
|   };
 | |
| 
 | |
|   return assert;
 | |
| }
 | |
| 
 | |
| function createTest({
 | |
|   title,
 | |
|   tests = [],
 | |
|   solutions = [],
 | |
|   head = [],
 | |
|   tail = []
 | |
| }) {
 | |
|   solutions = solutions.filter(solution => !!solution);
 | |
|   tests = tests.filter(test => !!test);
 | |
|   head = head.join('\n');
 | |
|   tail = tail.join('\n');
 | |
|   const plan = tests.length;
 | |
|   if (!plan) {
 | |
|     return Observable.just({
 | |
|       title,
 | |
|       type: 'missing'
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   return Observable.fromCallback(tape)(title)
 | |
|     .doOnNext(t => solutions.length ? t.plan(plan) : t.end())
 | |
|     .flatMap(t => {
 | |
|       if (solutions.length <= 0) {
 | |
|         t.comment('No solutions for ' + title);
 | |
|         return Observable.just({
 | |
|           title,
 | |
|           type: 'missing'
 | |
|         });
 | |
|       }
 | |
| 
 | |
| 
 | |
|       return Observable.just(t)
 | |
|         .map(fillAssert)
 | |
|         /* eslint-disable no-unused-vars */
 | |
|         // assert and code used within the eval
 | |
|         .doOnNext(assert => {
 | |
|           solutions.forEach(solution => {
 | |
|             tests.forEach(test => {
 | |
|               const code = solution;
 | |
|               const editor = { getValue() { return code; } };
 | |
|               /* eslint-enable no-unused-vars */
 | |
|               try {
 | |
|                 (() => {
 | |
|                   return eval(
 | |
|                     head + '\n;;' +
 | |
|                     solution + '\n;;' +
 | |
|                     tail + '\n;;' +
 | |
|                     test);
 | |
|                 })();
 | |
|               } catch (e) {
 | |
|                 t.fail(e);
 | |
|               }
 | |
|             });
 | |
|           });
 | |
|         })
 | |
|         .map(() => ({ title }));
 | |
|     });
 | |
| }
 | |
| 
 | |
| Observable.from(getChallenges())
 | |
|   .flatMap(challengeSpec => {
 | |
|     return Observable.from(challengeSpec.challenges);
 | |
|   })
 | |
|   .flatMap(challenge => {
 | |
|     return createTest(challenge);
 | |
|   })
 | |
|   .map(({ title, type }) => {
 | |
|     if (type === 'missing') {
 | |
|       return title;
 | |
|     }
 | |
|     return false;
 | |
|   })
 | |
|   .filter(title => !!title)
 | |
|   .toArray()
 | |
|   .subscribe(
 | |
|     (noSolutions) => {
 | |
|       console.log(
 | |
|         '# These challenges have no solutions\n- [ ] ' +
 | |
|           noSolutions.join('\n- [ ] ')
 | |
|       );
 | |
|     },
 | |
|     err => { throw err; },
 | |
|     () => process.exit(0)
 | |
|   );
 | |
| 
 |