diff --git a/circle.yml b/circle.yml index 79460e78e09..b2f9fb0a9b6 100644 --- a/circle.yml +++ b/circle.yml @@ -8,6 +8,7 @@ test: override: - ./circleci.sh style - ./circleci.sh setup-repos + - ./circleci.sh publictests - ./circleci.sh coverage: parallel: true diff --git a/circleci.sh b/circleci.sh index 11021f2f8b7..e6719921060 100755 --- a/circleci.sh +++ b/circleci.sh @@ -5,6 +5,7 @@ set -uexo pipefail HOST_DMD_VER=2.068.2 # same as in dmd/src/posix.mak DSCANNER_DMD_VER=2.071.2 # dscanner needs a more up-to-date version CURL_USER_AGENT="CirleCI $(curl --version | head -n 1)" +DUB=${DUB:-$HOME/dlang/dub/dub} N=2 case $CIRCLE_NODE_INDEX in @@ -97,9 +98,19 @@ coverage() make -f posix.mak $(find std etc -name "*.d" | sed "s/[.]d$/.test/" | grep -vE '(std.algorithm.sorting|std.encoding|net.curl)' ) } +# compile all public unittests separately +publictests() +{ + clone https://github.com/dlang/tools.git ../tools master + # fix to a specific version of https://github.com/dlang/tools/blob/master/phobos_tests_extractor.d + git -C ../tools checkout 184f5e60372d6dd36d3451b75fb6f21e23f7275b + make -f posix.mak publictests DUB=$DUB +} + case $1 in install-deps) install_deps ;; - coverage) coverage ;; setup-repos) setup_repos ;; + coverage) coverage ;; style) style ;; + publictests) publictests ;; esac diff --git a/posix.mak b/posix.mak index 5bdab44fdf3..db01a4046e4 100644 --- a/posix.mak +++ b/posix.mak @@ -56,6 +56,7 @@ DRUNTIME_PATH = ../druntime ZIPFILE = phobos.zip ROOT_OF_THEM_ALL = generated ROOT = $(ROOT_OF_THEM_ALL)/$(OS)/$(BUILD)/$(MODEL) +DUB=dub # Documentation-related stuff DOCSRC = ../dlang.org WEBSITE_DIR = ../web @@ -516,6 +517,13 @@ style: ../dscanner/dsc @echo "Running DScanner" ../dscanner/dsc --config .dscanner.ini --styleCheck $$(find etc std -type f -name '*.d' | grep -vE 'std/traits.d|std/typecons.d') -I. +publictests: $(LIB) + # parse all public unittests from Phobos, for now some modules are excluded + rm -rf ./out + DFLAGS="$(DFLAGS) $(LIB) -defaultlib= -debuglib= $(LINKDL)" $(DUB) --compiler=$${PWD}/$(DMD) --single ../tools/phobos_tests_extractor.d -- --inputdir . --ignore "allocator/allocator_list.d,allocator/building_blocks/allocator_list.d,allocator/building_blocks/free_list.d,allocator/building_blocks/quantizer,allocator/building_blocks/quantizer,allocator/building_blocks/stats_collector.d,base64.d,bitmanip.d,concurrency.d,conv.d,csv.d,datetime.d,digest/hmac.d,digest/sha.d,file.d,index.d,isemail.d,logger/core.d,logger/nulllogger.d,math.d,ndslice/selection.d,ndslice/slice.d,numeric.d,stdio.d,traits.d,typecons.d,uni.d,utf.d,uuid.d" --outputdir ./out + # execute all parsed tests + for file in $$(find out -name '*.d'); do echo "executing $${file}" && $(DMD) $(DFLAGS) -defaultlib= -debuglib= $(LIB) -main -unittest -run $$file || exit 1 ; done + .PHONY : auto-tester-build auto-tester-build: all checkwhitespace diff --git a/std/algorithm/comparison.d b/std/algorithm/comparison.d index 48596c21caa..2afbd009e78 100644 --- a/std/algorithm/comparison.d +++ b/std/algorithm/comparison.d @@ -1991,6 +1991,8 @@ bool isPermutation(alias pred = "a == b", Range1, Range2) /// @safe pure unittest { + import std.typecons : Yes; + assert(isPermutation([1, 2, 3], [3, 2, 1])); assert(isPermutation([1.1, 2.3, 3.5], [2.3, 3.5, 1.1])); assert(isPermutation("abc", "bca")); diff --git a/std/algorithm/iteration.d b/std/algorithm/iteration.d index 95620a63dbe..0e5167e4cc2 100644 --- a/std/algorithm/iteration.d +++ b/std/algorithm/iteration.d @@ -4086,6 +4086,7 @@ if (isForwardRange!Range && is(typeof(unaryFun!isTerminator(input.front)))) @safe unittest { import std.algorithm.comparison : equal; + import std.range.primitives : front; assert(equal(splitter!(a => a == ' ')("hello world"), [ "hello", "", "world" ])); int[] a = [ 1, 2, 0, 0, 3, 0, 4, 5, 0 ]; diff --git a/std/algorithm/mutation.d b/std/algorithm/mutation.d index 9fd60d9b00c..c18bda1c1c3 100644 --- a/std/algorithm/mutation.d +++ b/std/algorithm/mutation.d @@ -2588,6 +2588,7 @@ swapRanges(InputRange1, InputRange2)(InputRange1 r1, InputRange2 r2) /// @safe unittest { + import std.range : empty; int[] a = [ 100, 101, 102, 103 ]; int[] b = [ 0, 1, 2, 3 ]; auto c = swapRanges(a[1 .. 3], b[2 .. 4]); diff --git a/std/algorithm/searching.d b/std/algorithm/searching.d index 4926334bcee..526399cabcf 100644 --- a/std/algorithm/searching.d +++ b/std/algorithm/searching.d @@ -4177,6 +4177,7 @@ struct Until(alias pred, Range, Sentinel) if (isInputRange!Range) @safe unittest { import std.algorithm.comparison : equal; + import std.typecons : No; int[] a = [ 1, 2, 4, 7, 7, 2, 4, 7, 3, 5]; assert(equal(a.until(7), [1, 2, 4][])); assert(equal(a.until(7, No.openRight), [1, 2, 4, 7][])); diff --git a/std/algorithm/sorting.d b/std/algorithm/sorting.d index a25cc5225cb..d94a9aab29b 100644 --- a/std/algorithm/sorting.d +++ b/std/algorithm/sorting.d @@ -3558,6 +3558,8 @@ TRange topNCopy(alias less = "a < b", SRange, TRange) /// unittest { + import std.typecons : Yes; + int[] a = [ 10, 16, 2, 3, 1, 5, 0 ]; int[] b = new int[3]; topNCopy(a, b, Yes.sortOutput); @@ -3567,6 +3569,7 @@ unittest unittest { import std.random : Random, unpredictableSeed, uniform, randomShuffle; + import std.typecons : Yes; debug(std_algorithm) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " done."); @@ -3679,6 +3682,8 @@ void topNIndex(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, /// unittest { + import std.typecons : Yes; + // Construct index to top 3 elements using numerical indices: int[] a = [ 10, 2, 7, 5, 8, 1 ]; int[] index = new int[3]; @@ -3862,7 +3867,6 @@ if (isRandomAccessRange!Range && hasLength!Range && } } -/// unittest { // Verify medianOf for all permutations of [1, 2, 2, 3, 4]. diff --git a/std/exception.d b/std/exception.d index d36856f3968..a526e70f817 100644 --- a/std/exception.d +++ b/std/exception.d @@ -1196,6 +1196,8 @@ bool mayPointTo(S, T)(auto ref const shared S source, ref const shared T target) //To check the class payload itself, iterate on its members: () { + import std.traits : Fields; + foreach (index, _; Fields!C) if (doesPointTo(a.tupleof[index], i)) return; diff --git a/std/experimental/ndslice/slice.d b/std/experimental/ndslice/slice.d index 4fe04898989..bafa4bad7d8 100644 --- a/std/experimental/ndslice/slice.d +++ b/std/experimental/ndslice/slice.d @@ -498,6 +498,8 @@ pure nothrow unittest import std.algorithm.iteration : map, sum, reduce; import std.algorithm.comparison : max; import std.experimental.ndslice.iteration : transposed; + import std.typecons : No; + /// Returns maximal column average. auto maxAvg(S)(S matrix) { return matrix.transposed.map!sum.reduce!max @@ -515,6 +517,8 @@ pure nothrow unittest import std.algorithm.iteration : map, sum, reduce; import std.algorithm.comparison : max; import std.experimental.ndslice.iteration : transposed; + import std.typecons : No; + /// Returns maximal column average. auto maxAvg(S)(S matrix) { return matrix.transposed.map!sum.reduce!max diff --git a/std/experimental/typecons.d b/std/experimental/typecons.d index 7ff02875310..61b9feb70d1 100644 --- a/std/experimental/typecons.d +++ b/std/experimental/typecons.d @@ -512,6 +512,7 @@ unittest /// unittest { + import std.traits : functionAttributes, FunctionAttribute; interface A { int run(); } interface B { int stop(); @property int status(); } class X diff --git a/std/format.d b/std/format.d index 4218f0cdfb9..5b409b92289 100644 --- a/std/format.d +++ b/std/format.d @@ -1295,6 +1295,7 @@ FormatSpec!Char singleSpec(Char)(Char[] fmt) /// @safe unittest { + import std.exception : assertThrown; auto spec = singleSpec("%2.3e"); assert(spec.trailing == ""); diff --git a/std/json.d b/std/json.d index 408a8fca306..9ec251118e2 100644 --- a/std/json.d +++ b/std/json.d @@ -25,6 +25,8 @@ import std.traits; /// @system unittest { + import std.conv : to; + // parse a file or string of json into a usable structure string s = `{ "language": "D", "rating": 3.5, "code": "42" }`; JSONValue j = parseJSON(s); diff --git a/std/path.d b/std/path.d index 00c0d79a96c..88b817d4588 100644 --- a/std/path.d +++ b/std/path.d @@ -734,6 +734,7 @@ auto driveName(R)(R path) /// @safe unittest { + import std.range : empty; version (Posix) assert (driveName("c:/foo").empty); version (Windows) { @@ -929,6 +930,7 @@ auto extension(R)(R path) /// @safe unittest { + import std.range : empty; assert (extension("file").empty); assert (extension("file.") == "."); assert (extension("file.ext"w) == ".ext"); diff --git a/std/range/primitives.d b/std/range/primitives.d index ba8b50f22f9..41502c5822f 100644 --- a/std/range/primitives.d +++ b/std/range/primitives.d @@ -698,7 +698,6 @@ package(std) template isNativeOutputRange(R, E) })); } -/// @safe unittest { int[] r = new int[](4); @@ -935,6 +934,8 @@ template isRandomAccessRange(R) /// unittest { + import std.traits : isNarrowString; + alias R = int[]; // range is finite and bidirectional or infinite and forward. diff --git a/std/regex/package.d b/std/regex/package.d index b7258dce899..1665133abbf 100644 --- a/std/regex/package.d +++ b/std/regex/package.d @@ -594,10 +594,9 @@ public: assert(matchFirst("abc", "[0-9]+", "[a-z]+").whichPattern == 2); } - /++ - Lookup named submatch. - - --- + /// Lookup named submatch. + unittest + { import std.regex; import std.range; @@ -608,8 +607,8 @@ public: //named groups are unaffected by range primitives assert(c["var"] =="a"); assert(c.front == "42"); - ---- - +/ + } + R opIndex(String)(String i) /*const*/ //@@@BUG@@@ if (isSomeString!String) { @@ -627,6 +626,8 @@ public: /// unittest { + import std.range : popFrontN; + auto c = matchFirst("@abc#", regex(`(\w)(\w)(\w)`)); assert(c.pre == "@"); // Part of input preceding match assert(c.post == "#"); // Immediately after match @@ -1592,6 +1593,7 @@ unittest unittest { import std.algorithm.comparison : equal; + import std.typecons : Yes; const pattern = regex(`([\.,])`); diff --git a/std/string.d b/std/string.d index 2b86ba789bd..bf73f4f6d3e 100644 --- a/std/string.d +++ b/std/string.d @@ -545,6 +545,8 @@ ptrdiff_t indexOf(Range)(Range s, in dchar c, in size_t startIdx, /// @safe pure unittest { + import std.typecons : No; + string s = "Hello World"; assert(indexOf(s, 'W') == 6); assert(indexOf(s, 'Z') == -1); @@ -554,6 +556,8 @@ ptrdiff_t indexOf(Range)(Range s, in dchar c, in size_t startIdx, /// @safe pure unittest { + import std.typecons : No; + string s = "Hello World"; assert(indexOf(s, 'W', 4) == 6); assert(indexOf(s, 'Z', 100) == -1); @@ -801,6 +805,8 @@ ptrdiff_t indexOf(Char1, Char2)(const(Char1)[] s, const(Char2)[] sub, /// @safe pure unittest { + import std.typecons : No; + string s = "Hello World"; assert(indexOf(s, "Wo", 4) == 6); assert(indexOf(s, "Zo", 100) == -1); @@ -810,6 +816,8 @@ ptrdiff_t indexOf(Char1, Char2)(const(Char1)[] s, const(Char2)[] sub, /// @safe pure unittest { + import std.typecons : No; + string s = "Hello World"; assert(indexOf(s, "Wo") == 6); assert(indexOf(s, "Zo") == -1); @@ -1059,6 +1067,8 @@ ptrdiff_t lastIndexOf(Char)(const(Char)[] s, in dchar c, in size_t startIdx, /// @safe pure unittest { + import std.typecons : No; + string s = "Hello World"; assert(lastIndexOf(s, 'l') == 9); assert(lastIndexOf(s, 'Z') == -1); @@ -1068,6 +1078,8 @@ ptrdiff_t lastIndexOf(Char)(const(Char)[] s, in dchar c, in size_t startIdx, /// @safe pure unittest { + import std.typecons : No; + string s = "Hello World"; assert(lastIndexOf(s, 'l', 4) == 3); assert(lastIndexOf(s, 'Z', 1337) == -1); @@ -1264,6 +1276,8 @@ ptrdiff_t lastIndexOf(Char1, Char2)(const(Char1)[] s, const(Char2)[] sub, /// @safe pure unittest { + import std.typecons : No; + string s = "Hello World"; assert(lastIndexOf(s, "ll") == 2); assert(lastIndexOf(s, "Zo") == -1); @@ -1273,6 +1287,8 @@ ptrdiff_t lastIndexOf(Char1, Char2)(const(Char1)[] s, const(Char2)[] sub, /// @safe pure unittest { + import std.typecons : No; + string s = "Hello World"; assert(lastIndexOf(s, "ll", 4) == 2); assert(lastIndexOf(s, "Zo", 128) == -1); diff --git a/std/uni.d b/std/uni.d index fa140f39d96..563ebe3d5fd 100644 --- a/std/uni.d +++ b/std/uni.d @@ -6851,6 +6851,7 @@ static assert(Grapheme.sizeof == size_t.sizeof*4); { import std.algorithm.comparison : equal; import std.algorithm.iteration : filter; + import std.range : isRandomAccessRange; string bold = "ku\u0308hn";