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)
 | 
						|
  );
 | 
						|
 |