diff --git a/configure b/configure index 329ac38afd9..5d94b854ea2 100755 --- a/configure +++ b/configure @@ -460,6 +460,7 @@ do make_dir $h/test/bench make_dir $h/test/perf make_dir $h/test/pretty + make_dir $h/test/doc-tutorial done # Configure submodules diff --git a/doc/tutorial.md b/doc/tutorial.md index 28a9667dea6..e2fbe7653e9 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -642,6 +642,7 @@ you use the matching to get at the contents of data types. Remember that `(float, float)` is a tuple of two floats: ~~~~ +## xfail-test fn angle(vec: (float, float)) -> float { alt vec { (0f, y) if y < 0f { 1.5 * float::consts::pi } @@ -895,6 +896,7 @@ should almost always specify the type of that argument as `fn()`, so that callers have the flexibility to pass whatever they want. ~~~~ +## xfail-test fn call_twice(f: fn()) { f(); f(); } call_twice({|| "I am a stack closure; }); call_twice(fn@() { "I am a boxed closure"; }); @@ -1154,6 +1156,7 @@ get at their contents. All variant constructors can be used as patterns, as in this definition of `area`: ~~~~ +## xfail-test # type point = {x: float, y: float}; # enum shape { circle(point, float), rectangle(point, point) } fn area(sh: shape) -> float { @@ -2152,6 +2155,7 @@ hexadecimal string and prints to standard output. If you have the OpenSSL libraries installed, it should 'just work'. ~~~~ +## xfail-test use std; native mod crypto { @@ -2182,6 +2186,7 @@ Before we can call `SHA1`, we have to declare it. That is what this part of the program is responsible for: ~~~~ +## xfail-test native mod crypto { fn SHA1(src: *u8, sz: uint, out: *u8) -> *u8; } @@ -2197,6 +2202,7 @@ link that in. If you want the module to have a different name from the actual library, you can use the `"link_name"` attribute, like: ~~~~ +## xfail-test #[link_name = "crypto"] native mod something { fn SHA1(src: *u8, sz: uint, out: *u8) -> *u8; @@ -2229,6 +2235,7 @@ The native `SHA1` function is declared to take three arguments, and return a pointer. ~~~~ +## xfail-test # native mod crypto { fn SHA1(src: *u8, sz: uint, out: *u8) -> *u8; # } @@ -2407,6 +2414,7 @@ For example, imagine we wish to perform two expensive computations in parallel. We might write something like: ~~~~ +## xfail-test # fn some_expensive_computation() -> int { 42 } # fn some_other_expensive_computation() {} let port = comm::port::(); @@ -2454,6 +2462,7 @@ some other expensive computation and then waiting for the child's result to arrive on the port: ~~~~ +## xfail-test # fn some_other_expensive_computation() {} # let port = comm::port::(); some_other_expensive_computation(); @@ -2492,7 +2501,7 @@ strified version of the received value, `uint::to_str(value)`. Here is the code for the parent task: ~~~~ - +## xfail-test # fn stringifier(from_par: comm::port, # to_par: comm::chan) {} fn main() { diff --git a/mk/tests.mk b/mk/tests.mk index 7cf57c5d7c3..4bc72c35fd2 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -99,6 +99,24 @@ tidy: | xargs -n 10 python $(S)src/etc/tidy.py endif + +###################################################################### +# Extracting tests for docs +###################################################################### + +EXTRACT_TESTS := $(CFG_PYTHON) $(S)src/etc/extract-tests.py + +define DEF_DOC_TEST_HOST + +doc-tutorial-extract$(1): + @$$(call E, extract: tutorial tests) + $$(Q)$$(EXTRACT_TESTS) $$(S)doc/tutorial.md $(1)/test/doc-tutorial + +endef + +$(foreach host,$(CFG_TARGET_TRIPLES), \ + $(eval $(call DEF_DOC_TEST_HOST,$(host)))) + ###################################################################### # Rules for the test runners ###################################################################### @@ -121,7 +139,8 @@ check-stage$(1)-T-$(2)-H-$(3): tidy \ check-stage$(1)-T-$(2)-H-$(3)-cfail \ check-stage$(1)-T-$(2)-H-$(3)-bench \ check-stage$(1)-T-$(2)-H-$(3)-pretty \ - check-stage$(1)-T-$(2)-H-$(3)-rustdoc + check-stage$(1)-T-$(2)-H-$(3)-rustdoc \ + check-stage$(1)-T-$(2)-H-$(3)-doc-tutorial check-stage$(1)-T-$(2)-H-$(3)-core: \ check-stage$(1)-T-$(2)-H-$(3)-core-dummy @@ -168,6 +187,9 @@ check-stage$(1)-T-$(2)-H-$(3)-pretty-pretty: \ check-stage$(1)-T-$(2)-H-$(3)-rustdoc: \ check-stage$(1)-T-$(2)-H-$(3)-rustdoc-dummy +check-stage$(1)-T-$(2)-H-$(3)-doc-tutorial: \ + check-stage$(1)-T-$(2)-H-$(3)-doc-tutorial-dummy + # Rules for the core library test runner $(3)/test/coretest.stage$(1)-$(2)$$(X): \ @@ -293,6 +315,12 @@ PRETTY_PRETTY_ARGS$(1)-T-$(2)-H-$(3) := \ --build-base $(3)/test/pretty/ \ --mode pretty +DOC_TUTORIAL_ARGS$(1)-T-$(2)-H-$(3) := \ + $$(CTEST_COMMON_ARGS$(1)-T-$(2)-H-$(3)) \ + --src-base $(3)/test/doc-tutorial/ \ + --build-base $(3)/test/doc-tutorial/ \ + --mode run-pass + check-stage$(1)-T-$(2)-H-$(3)-cfail-dummy: \ $$(HBIN$(1)_H_$(3))/compiletest$$(X) \ $$(SREQ$(1)_T_$(2)_H_$(3)) \ @@ -365,6 +393,14 @@ check-stage$(1)-T-$(2)-H-$(3)-pretty-pretty-dummy: \ $$(Q)$$(call CFG_RUN_CTEST,$(1),$$<,$(3)) \ $$(PRETTY_PRETTY_ARGS$(1)-T-$(2)-H-$(3)) +check-stage$(1)-T-$(2)-H-$(3)-doc-tutorial-dummy: \ + $$(HBIN$(1)_H_$(3))/compiletest$$(X) \ + $$(SREQ$(1)_T_$(2)_H_$(3)) \ + doc-tutorial-extract$(3) + @$$(call E, run doc-tutorial: $$<) + $$(Q)$$(call CFG_RUN_CTEST,$(1),$$<,$(3)) \ + $$(DOC_TUTORIAL_ARGS$(1)-T-$(2)-H-$(3)) + endef # Instantiate the template for stage 0, 1, 2, 3 @@ -471,6 +507,9 @@ check-stage$(1)-H-$(2)-pretty-pretty: \ check-stage$(1)-H-$(2)-rustdoc: \ $$(foreach target,$$(CFG_TARGET_TRIPLES), \ check-stage$(1)-T-$$(target)-H-$(2)-rustdoc) +check-stage$(1)-H-$(2)-doc-tutorial: \ + $$(foreach target,$$(CFG_TARGET_TRIPLES), \ + check-stage$(1)-T-$$(target)-H-$(2)-doc-tutorial) endef @@ -534,6 +573,9 @@ check-stage$(1)-H-all-pretty-pretty: \ check-stage$(1)-H-all-rustdoc: \ $$(foreach target,$$(CFG_TARGET_TRIPLES), \ check-stage$(1)-H-$$(target)-rustdoc) +check-stage$(1)-H-all-doc-tutorial: \ + $$(foreach target,$$(CFG_TARGET_TRIPLES), \ + check-stage$(1)-H-$$(target)-doc-tutorial) endef @@ -557,6 +599,7 @@ check-stage$(1)-pretty-rfail: check-stage$(1)-H-$$(CFG_HOST_TRIPLE)-pretty-rfail check-stage$(1)-pretty-bench: check-stage$(1)-H-$$(CFG_HOST_TRIPLE)-pretty-bench check-stage$(1)-pretty-pretty: check-stage$(1)-H-$$(CFG_HOST_TRIPLE)-pretty-pretty check-stage$(1)-rustdoc: check-stage$(1)-H-$$(CFG_HOST_TRIPLE)-rustdoc +check-stage$(1)-doc-tutorial: check-stage$(1)-H-$$(CFG_HOST_TRIPLE)-doc-tutorial endef diff --git a/doc/extract-tests.py b/src/etc/extract-tests.py similarity index 77% rename from doc/extract-tests.py rename to src/etc/extract-tests.py index 4d253cf906c..32fc25a685a 100644 --- a/doc/extract-tests.py +++ b/src/etc/extract-tests.py @@ -6,11 +6,12 @@ import sys, re; -if len(sys.argv) < 2: +if len(sys.argv) < 3: print("Please provide an input filename") sys.exit(1) filename = sys.argv[1] +dest = sys.argv[2] f = open(filename) lines = f.readlines() f.close() @@ -30,24 +31,31 @@ while cur < len(lines): elif re.match("~~~", line): block = "" ignore = False + xfail = False while cur < len(lines): line = lines[cur] cur += 1 if re.match(r"\s*## (notrust|ignore)", line): ignore = True + elif re.match(r"\s*## xfail-test", line): + xfail = True elif re.match("~~~", line): break else: block += re.sub("^# ", "", line) if not ignore: if not re.search(r"\bfn main\b", block): - if re.search(r"(^|\n) *(native|use|mod|import|export)\b", block): + if re.search( + r"(^|\n) *(native|use|mod|import|export)\b", block): block += "\nfn main() {}\n" else: block = "fn main() {\n" + block + "\n}\n" if not re.search(r"\buse std\b", block): block = "use std;\n" + block; - filename = "fragments/" + str(chapter) + "_" + str(chapter_n) + ".rs" + if xfail: + block = "// xfail-test\n" + block + filename = (dest + "/" + str(chapter) + + "_" + str(chapter_n) + ".rs") chapter_n += 1 f = open(filename, 'w') f.write(block)