Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

We’re showing branches in this repository, but you can also compare across forks.

base fork: rebbix/dart-quickcheck
base: fd6d711807
...
head fork: rebbix/dart-quickcheck
compare: 38435a5dde
  • 4 commits
  • 6 files changed
  • 0 commit comments
  • 1 contributor
10 builders.dart
View
@@ -15,7 +15,11 @@ Arbitrary<Object> Single(Object o) => Choice([o]);
Arbitrary<Object> CharRange(String a, String b) =>
Int(a.charCodeAt(0), b.charCodeAt(0)).passThrough((x) => new String.fromCharCodes([x]));
-class ArbitraryIntBuilder {
+interface ArbitraryBuilder<T> {
+ Arbitrary<T> toArbitrary();
+}
+
+class ArbitraryIntBuilder implements ArbitraryBuilder<int> {
int start = 0, end = 42;
var parent;
@@ -108,13 +112,13 @@ class ForAll {
integers.greaterThan(0);
static ArbitraryIntBuilder get negativeIntegers() =>
- integers.lessThan(0);
+ integers.lessThan(0).greaterThan(-42);
static ArbitraryIntBuilder get nonNegativeIntegers() =>
integers.greaterOrEqual(0);
static ArbitraryIntBuilder get nonPositiveIntegers() =>
- integers.lessOrEqual(0);
+ integers.lessOrEqual(0).greaterThan(-42);
static ArbitraryListBuilder get lists() =>
new ArbitraryListBuilder();
18 main.dart
View
@@ -1,18 +0,0 @@
-#import("qc.dart");
-
-main () {
- // forAll(Int(0, 1), (x) => id(x) === x);
- // forAll(ListOf(Int()), (List xs) => xs.isEmpty());
- // forAll(ListOf(Choice([0, 1, 2])), (List xs) => xs.indexOf(3) == -1);
- // forAll(ListOf(Single('A')), (List xs) => xs.indexOf('B') == -1);
- // forAll(ListOf(CharRange('c', 'a')), (List xs) => xs.indexOf('Z') == -1);
- // var g = ForAll.integers.between(10, 20).toArbitrary();
- // forAll(g, (x) => x >= 15 && x <= 20);
- // g = ForAll.integers.lessThan(5).toArbitrary();
- // forAll(g, (x) => x < 5);
-
- var lg = ForAll.lists.ofLength(5, 15).with.lists.ofLength(2, 4).with.strings.ofRange('a', 'Z').toArbitrary();
- forAll(lg, (List xs) => xs.length > 10);
-}
-
-id(x) => x;
1  qc.dart
View
@@ -3,3 +3,4 @@
#source("runner.dart");
#source("arbitrary.dart");
#source("builders.dart");
+#source("reports.dart");
33 reports.dart
View
@@ -0,0 +1,33 @@
+class Reporter {
+ final bool verbose;
+
+ Reporter(this.verbose);
+
+ void testStart(Property<Object> p) =>
+ print("Testing property: '${p.name}'");
+
+ void testSuccess(Property<Object> p, Results rs) {
+ // print("SUCCESS: '${p.name}' after ${rs.count()} checks.\n");
+ }
+
+ void testFail(Property<Object> p, Results rs) =>
+ print("FAIL: '${p.name}' after ${rs.count()} checks.\n");
+
+ void singleCheck(Result<Object> r) =>
+ r.result ? _success(r) : _fail(r);
+
+ void summary(List<bool> rs) {
+ var failed = rs.filter((r) => !r);
+ int numFailed = failed.length;
+ if (numFailed > 0)
+ print ("FAILURE: ${numFailed} tests failed!");
+ }
+
+ void _fail(Result<Object> r) =>
+ print("\tFAILED for '${r.input.toString()}'");
+
+ void _success(Result<Object> r) =>
+ verbose ? print ("\tSUCCESS for '${r.input.toString()}'") : _skip();
+}
+
+_skip() {}
172 runner.dart
View
@@ -1,13 +1,165 @@
-forAll(generator, callable) {
- final int NUM_RUNS = 100;
- for (int i = 0; i < NUM_RUNS; i++) {
- var next = generator.next();
- print("Next = $next");
- var result = callable(next);
- print ("Result = $result");
+prepareArbitrary(g) {
+ if (g is ArbitraryBuilder)
+ return g.toArbitrary();
+ else
+ return g;
+}
+
+check(name, generator, callable) {
+ return new Property(name, prepareArbitrary(generator), callable);
+}
+
+Property property(name, generator, callable) {
+ Property p = new Property(name, prepareArbitrary(generator), callable);
+ Property.registerProperty(p);
+ return p;
+}
+
+void checkAll() {
+ run(Property.declaredProperties);
+ Property.declaredProperties = null;
+}
+//checkFails(name, generator, callable) =>
+ //new Property.negative(name, prepareArbitrary(generator), callable);
+
+void run(List<Property<Object>> ps) {
+ final config = new Config();
+ (new Suite(ps, config)).run();
+}
+
+beVerbose() => Config.setVerbose(true);
+shutUp() => Config.setVerbose(false);
+
+class Config {
+ static int _numRuns = 100;
+ static bool _verbose = false;
+ Reporter report;
+
+ Config() {
+ report = new Reporter(_verbose);
+ }
+
+ int get numRuns() => _numRuns;
+ bool get verbose() => _verbose;
+
+ static bool setVerbose(bool flag) => _verbose = flag;
+}
+
+
+class Suite {
+ final List<Property<Object>> properties;
+ final Config config;
+
+ Suite(this.properties, this.config);
+
+ void run() {
+ var results = [];
+ properties.forEach((p) => results.add(_testOne(p)));
+ config.report.summary(results);
+ }
+
+ bool _testOne(Property<Object> p) {
+ config.report.testStart(p);
+ final Results rs = new Results();
+ for (int i = 0; i<config.numRuns; ++i) {
+ final Result<Object> r = p.check();
+ rs.add(r);
+ config.report.singleCheck(r);
+ if (! r.result) {
+ return _fail(p, rs);
+ }
+ }
+ return _success(p, rs);
+ }
+
+ bool _fail(Property p, Results rs) {
+ config.report.testFail(p, rs);
+ return false;
+ }
+
+ bool _success(Property p, Results rs) {
+ config.report.testSuccess(p, rs);
+ return true;
+ }
+}
+
+class Result<T> {
+ final Property<T> property;
+ final T input;
+ final bool result;
+ Result(this.property, this.input, this.result);
+}
+
+
+class Results {
+ List<Result<Object>> _results;
+
+ Results() {
+ _results = [];
+ }
+
+ void add(Result<Object> r) => _results.add(r);
+
+ int count() => _results.length;
+
+ Result<Object> latest() => _results.last();
+}
+
+class Property<T> {
+ final String name;
+ final Iterator<T> _generator;
+ final Function _callable;
+ Condition _condition;
+ Function _filter = null;
+ static List<Property> declaredProperties;
+
+ static registerProperty(p) {
+ if (declaredProperties == null)
+ declaredProperties = new List<Property>();
+ declaredProperties.add(p);
+ }
+
+ Property(this.name, this._generator, this._callable) {
+ _condition = new AcceptPositive();
+ }
+
+ Property.negative(this.name, this._generator, this._callable) {
+ _condition = new AcceptNegative();
}
+
+ Result<T> check() {
+ final T input = _takeWhile(_filter, _generator.next);
+
+ final bool checkResult = _callable(input);
+ final bool result = _condition.check(checkResult);
+ return new Result<T>(this, input, result);
+ }
+
+ Property<T> when(filter) {
+ _filter = filter;
+ return this;
+ }
+
+ _takeWhile(condition, f) {
+ // TODO: Report if too much tries.
+ var r = f();
+ if (condition == null) return r;
+ while (! condition(r)) {
+ r = f();
+ }
+ return r;
+ }
+}
+
+abstract class Condition {
+ abstract bool check(bool r);
+}
+
+class AcceptPositive extends Condition {
+ bool check(bool r) => r;
+}
+
+class AcceptNegative extends Condition {
+ bool check(bool r) => !r;
}
-//check(List property) {
-// property.forEach()
-//}
14 tests.dart
View
@@ -0,0 +1,14 @@
+#import("qc.dart");
+
+main () {
+ property("any int over 5", ForAll.positiveIntegers.greaterThan(5), (x) => x > 5);
+ property("any int under 5", ForAll.positiveIntegers.lessThan(5), (x) => x < 5);
+
+ property("positive ints", ForAll.positiveIntegers, (x) => x > 0);
+ property("negative ints", ForAll.negativeIntegers, (x) => x < 0);
+ property("non-negative ints", ForAll.nonNegativeIntegers, (x) => x >= 0);
+ property("non-positive ints", ForAll.nonPositiveIntegers, (x) => x <= 0);
+ property("integers", ForAll.integers, (x) => x is int);
+
+ checkAll();
+}

No commit comments for this range

Something went wrong with that request. Please try again.