Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, 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
View
10 builders.dart
@@ -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();
View
18 main.dart
@@ -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;
View
1  qc.dart
@@ -3,3 +3,4 @@
#source("runner.dart");
#source("arbitrary.dart");
#source("builders.dart");
+#source("reports.dart");
View
33 reports.dart
@@ -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() {}
View
172 runner.dart
@@ -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()
-//}
View
14 tests.dart
@@ -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.