import alias ;
+import build-system ;
import "class" ;
import common ;
import errors ;
import feature ;
import generators ;
import os ;
+import param ;
import path ;
import project ;
import property ;
# to allow post-processing tools to work.
local t = [ targets.create-typed-target [ type.type-from-rule-name
$(target-type) ] : $(project) : $(real-name) : $(sources) :
- $(requirements) <location-prefix>$(real-name)$(.TEST-DIR-SUFFIX) ] ;
+ $(requirements) <location-prefix>$(real-name)$(.TEST-DIR-SUFFIX)
+ <relevant>toolset ] ;
# The alias to the real target, per period replacement above.
if $(real-name) != $(target-name)
#
rule compile ( sources + : requirements * : target-name ? )
{
+ param.handle-named-params sources requirements target-name ;
return [ make-test compile : $(sources) : $(requirements) : $(target-name) ]
;
}
rule compile-fail ( sources + : requirements * : target-name ? )
{
+ param.handle-named-params sources requirements target-name ;
return [ make-test compile-fail : $(sources) : $(requirements) :
$(target-name) ] ;
}
rule link ( sources + : requirements * : target-name ? )
{
+ param.handle-named-params sources requirements target-name ;
return [ make-test link : $(sources) : $(requirements) : $(target-name) ] ;
}
rule link-fail ( sources + : requirements * : target-name ? )
{
+ param.handle-named-params sources requirements target-name ;
return [ make-test link-fail : $(sources) : $(requirements) : $(target-name)
] ;
}
rule run ( sources + : args * : input-files * : requirements * : target-name ? :
default-build * )
{
+ param.handle-named-params sources args input-files requirements
+ target-name default-build ;
requirements += <testing.arg>$(args:J=" ") ;
requirements += [ handle-input-files $(input-files) ] ;
return [ make-test run : $(sources) : $(requirements) : $(target-name) ] ;
rule run-fail ( sources + : args * : input-files * : requirements * :
target-name ? : default-build * )
{
+ param.handle-named-params sources args input-files requirements
+ target-name default-build ;
requirements += <testing.arg>$(args:J=" ") ;
requirements += [ handle-input-files $(input-files) ] ;
return [ make-test run-fail : $(sources) : $(requirements) : $(target-name)
}
}
+if ( --dump-tests in [ modules.peek : ARGV ] )
+{
+ IMPORT testing : dump-tests : : testing.dump-tests ;
+ build-system.add-pre-build-hook testing.dump-tests ;
+}
# Given a project location in normalized form (slashes are forward), compute the
# name of the Boost library.
# Format them into a single string of quoted strings.
test-info = \"$(test-info:J=\"\ \")\" ;
- ECHO boost-test($(type)) \"$(name)\" [$(test-info)] ":"
+ ECHO boost-test($(type)) \"$(name)\" "[$(test-info)]" ":"
\"$(source-files)\" ;
}
}
+class testing.expect-failure-generator : generator
+{
+ rule generated-targets ( sources + : property-set : project name ? )
+ {
+ for local s in $(sources)
+ {
+ local a = [ $(s).action ] ;
+ if $(a)
+ {
+ for local t in [ $(a).targets ]
+ {
+ $(t).fail-expected ;
+ }
+ }
+ }
+ return [ generator.generated-targets $(sources)
+ : $(property-set) : $(project) $(name) ] ;
+ }
+}
+
+local rule register-fail-expected ( source-type : test-type )
+{
+ generators.register [ class.new testing.expect-failure-generator
+ testing.expect-failure : $(source-type) : $(test-type) ] ;
+}
# Register generators. Depending on target type, either 'expect-success' or
# 'expect-failure' rule will be used.
generators.register-standard testing.expect-success : OBJ : COMPILE ;
-generators.register-standard testing.expect-failure : OBJ : COMPILE_FAIL ;
+register-fail-expected OBJ : COMPILE_FAIL ;
generators.register-standard testing.expect-success : RUN_OUTPUT : RUN ;
-generators.register-standard testing.expect-failure : RUN_OUTPUT : RUN_FAIL ;
-generators.register-standard testing.expect-failure : EXE : LINK_FAIL ;
+register-fail-expected RUN_OUTPUT : RUN_FAIL ;
generators.register-standard testing.expect-success : EXE : LINK ;
+register-fail-expected EXE : LINK_FAIL ;
# Generator which runs an EXE and captures output.
generators.register-standard testing.capture-output : EXE : RUN_OUTPUT ;
# http://article.gmane.org/gmane.comp.lib.boost.build/6353).
generators.register-standard testing.unit-test : EXE : UNIT_TEST ;
+toolset.uses-features testing.expect-success : <preserve-test-targets> ;
+toolset.uses-features testing.expect-failure : <preserve-test-targets> ;
# The action rules called by generators.
#
rule expect-success ( target : dependency + : requirements * )
{
- **passed** $(target) : $(dependency) ;
+ **passed** $(target) : $(dependency) : $(requirements) ;
}
local grist = [ MATCH ^<(.*)> : $(dependency:G) ] ;
local marker = $(dependency:G=$(grist)*fail) ;
(failed-as-expected) $(marker) ;
- FAIL_EXPECTED $(dependency) ;
LOCATE on $(marker) = [ on $(dependency) return $(LOCATE) ] ;
RMOLD $(marker) ;
DEPENDS $(marker) : $(dependency) ;
DEPENDS $(target) : $(marker) ;
- **passed** $(target) : $(marker) ;
+ **passed** $(target) : $(marker) : $(properties) ;
}
# The rule/action combination used to report successful passing of a test.
#
-rule **passed**
+rule **passed** ( target : sources * : properties * )
{
- remove-test-targets $(<) ;
-
- # Dump all the tests, if needed. We do it here, since dump should happen
- # only after all Jamfiles have been read, and there is no such place
- # currently defined (but there should be).
- if ! $(.dumped-tests) && ( --dump-tests in [ modules.peek : ARGV ] )
+ if [ feature.get-values preserve-test-targets : $(properties) ] = off
{
- .dumped-tests = true ;
- dump-tests ;
+ remove-test-targets $(<) ;
}
-
# Force deletion of the target, in case any dependencies failed to build.
RMOLD $(<) ;
}
toolset.flags testing.capture-output INPUT_FILES <testing.input-file> ;
toolset.flags testing.capture-output LAUNCHER <testing.launcher> ;
-.preserve-test-targets = on ;
+toolset.uses-features testing.capture-output :
+ <testing.launcher> <testing.execute> <dll-path> <xdll-path> <target-os> ;
+
if --remove-test-targets in [ modules.peek : ARGV ]
{
- .preserve-test-targets = off ;
+ feature.set-default preserve-test-targets : off ;
}
# Runs executable 'sources' and stores stdout in file 'target'. Unless
# --preserve-test-targets command line option has been specified, removes the
-# executable. The 'target-to-remove' parameter controls what should be removed:
-# - if 'none', does not remove anything, ever
-# - if empty, removes 'source'
-# - if non-empty and not 'none', contains a list of sources to remove.
+# executable.
#
-rule capture-output ( target : source : properties * : targets-to-remove * )
+rule capture-output ( target : source : properties * )
{
output-file on $(target) = $(target:S=.output) ;
LOCATE on $(target:S=.output) = [ on $(target) return $(LOCATE) ] ;
# bug).
DEPENDS $(target) : [ on $(target) return $(INPUT_FILES) ] ;
- if $(targets-to-remove) = none
- {
- targets-to-remove = ;
- }
- else if ! $(targets-to-remove)
- {
- targets-to-remove = $(source) ;
- }
-
run-path-setup $(target) : $(source) : $(properties) ;
DISABLE_TEST_EXECUTION on $(target) = 0 ;
DISABLE_TEST_EXECUTION on $(target) = 1 ;
}
- if [ feature.get-values preserve-test-targets : $(properties) ] = off
- || $(.preserve-test-targets) = off
- {
- rmtemp-sources $(target) : $(targets-to-remove) ;
- for local to-remove in $(targets-to-remove)
- {
- rmtemp-all-sources $(to-remove) ;
- }
- }
-
if ! [ feature.get-values testing.launcher : $(properties) ]
{
## On VMS set default launcher to MCR
.types-to-remove = EXE OBJ ;
-local rule remove-test-targets ( targets + )
-{
- if $(.preserve-test-targets) = off
- {
- rmtemp-all-sources $(target) ;
- }
-}
-
-local rule rmtemp-all-sources ( target )
+local rule remove-test-targets ( target )
{
- local sources ;
local action = [ on $(target) return $(.action) ] ;
- if $(action)
+ local associated-targets = [ virtual-target.traverse [ $(action).targets ] ] ;
+ local targets-to-remove ;
+ for local t in [ sequence.unique $(associated-targets) ]
{
- local action-sources = [ $(action).sources ] ;
- for local source in $(action-sources)
- {
- local source-type = [ $(source).type ] ;
- if $(source-type) in $(.types-to-remove)
- {
- sources += [ $(source).actual-name ] ;
- }
- else
- {
- # ECHO IGNORED: $(source) :: $(source-type) ;
- }
- }
- if $(sources)
+ if [ $(t).type ] in $(.types-to-remove)
{
- rmtemp-sources $(target) : $(sources) ;
- for local source in $(sources)
- {
- rmtemp-all-sources $(source) ;
- }
+ targets-to-remove += [ $(t).actual-name ] ;
}
}
+ rmtemp-sources $(target) : $(targets-to-remove) ;
}
local rule rmtemp-sources ( target : sources * )
# with an embedded manifest file by a separate action.
rule record-time ( target : source : start end user system clock )
{
- local src-string = [$(source:G=:J=",")"] " ;
+ local src-string = "[$(source:G=:J=,)] " ;
USER_TIME on $(target) += $(src-string)$(user) ;
SYSTEM_TIME on $(target) += $(src-string)$(system) ;
CLOCK_TIME on $(target) += $(src-string)$(clock) ;