Skip to content

Instantly share code, notes, and snippets.

@krishnadey30
Last active June 17, 2019 23:11
Show Gist options
  • Save krishnadey30/45dfc521b02f7b6012aa20be9eea33ce to your computer and use it in GitHub Desktop.
Save krishnadey30/45dfc521b02f7b6012aa20be9eea33ce to your computer and use it in GitHub Desktop.
This gist contains the initial draft of the UnitTest Framework - Chapel
module UnitTest {
  use Reflection;
  use TestError;

  config const skipId: int = 0;
  // This is a dummy test so that we get capture the function signature
  private
  proc testSignature(test: Test) throws { }
  var tempFcf = testSignature;
  type argType = tempFcf.type;  //Type of First Class Test Functions

  /*A test result class that can print formatted text results to a stream.*/
  class TextTestResult {
    var separator1 = "="* 70,
        separator2 = "-"* 70;
    
    proc startTest(test, indx) throws {
      stdout.write(test: string,"(",indx: string,"): ");
    }

    proc addError(test, errMsg) throws {
      stdout.writeln("ERROR");
      PrintError(errMsg);
    }

    proc addFailure(test, errMsg) throws {
      stdout.writeln("FAIL");
      PrintError(errMsg);
    }

    proc addSuccess(test) throws {
      stdout.writeln("OK");
    }

    proc addSkip(test, reason) throws {
      stdout.writeln("SKIPPED");
      PrintError(reason);
    }

    proc PrintError(err) throws {
      stdout.writeln(this.separator1);
      stdout.writeln(err);
      stdout.writeln(this.separator2);
    }
    
  }

  /*Runs the tests*/
  proc runTest(tests: argType ...?n) throws {

    // Assuming 1 global test suite for now
    // Per-module or per-class is possible too
    var testSuite = new TestSuite();
    testSuite.addTests(tests);
    var testResult = new TextTestResult();
    // if skipId == 0 then
    //   stdout.writeln("Found "+testSuite.testCount+" "+printTest(testSuite.testCount));
    for indx in (skipId+1)..testSuite.testCount {
      var test = testSuite[indx];
      try {
        // Create a test object per test
        var testObject = new Test();
        //test is a FCF:
        testResult.startTest(test: string, indx);
        test(testObject);
        testResult.addSuccess(test: string);
      }
      // A variety of catch statements will handle errors thrown
      catch e: AssertionError {
        testResult.addFailure(test:string, e:string);
        // print info of the assertion error
      }
      catch e: TestSkipped {
        testResult.addSkip(test:string, e:string);
        // Print info on test skipped
      }
      catch e: TestDependencyNotMet {
        // Pop test out of array and append to end
      }
      catch e { 
        testResult.addError(test:string, e:string);
      }
    }
    // testResult.printErrors();
    // stdout.writeln(testResult.separator2);
    // testResult.PrintResult();
  }

  class TestSuite {
    var testCount = 0;
    var _tests: [1..0] argType;
    
    proc addTest(test) lifetime this < test {
      // var tempTest = new Test();
      // param test_name = test: string;
      // if !canResolve(test_name,tempTest) then
      //   compilerError(test + " is not callable");
      this._tests.push_back(test);
      this.testCount += 1;
    }

    proc addTests(tests) lifetime this < tests {
      /*if isString(tests) then
        compilerError("tests must be an iterable, not a string");*/
      for test in tests do
        this.addTest(test);
    }

    proc this(i : int) ref: argType {
      return this._tests[i];
    }

    iter these() {
      for i in this._tests do
        yield i;
    }
  }
  
}

Example

use UnitTest;

proc test1(test: Test) throws {
  test.assertTrue(false);
}

proc test2(test: Test) throws {
  test.assertTrue(false);
}

proc test3(test: Test) throws {
  test.skip("Skipping Test 3");
}
UnitTest.runTest(test1,test2,test3);

Current Output

Run 3 test
FAILED
failures= 2
skipped= 1
@ben-albrecht
Copy link

I think we can remove use LinkedLists; now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment