mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-31 04:50:34 -04:00 
			
		
		
		
	
		
			
	
	
		
			415 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			415 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
|  | #!/usr/bin/python | ||
|  | 
 | ||
|  | # Copyright (C) 2012. Jurko Gospodnetic | ||
|  | # Distributed under the Boost Software License, Version 1.0. | ||
|  | # (See accompanying file LICENSE_1_0.txt or copy at | ||
|  | # http://www.boost.org/LICENSE_1_0.txt) | ||
|  | 
 | ||
|  | # Tests Boost Build's project-id handling. | ||
|  | 
 | ||
|  | import BoostBuild | ||
|  | import sys | ||
|  | 
 | ||
|  | 
 | ||
|  | def test_assigning_project_ids(): | ||
|  |     t = BoostBuild.Tester(pass_toolset=False) | ||
|  |     t.write("jamroot.jam", """\
 | ||
|  | import assert ; | ||
|  | import modules ; | ||
|  | import notfile ; | ||
|  | import project ; | ||
|  | 
 | ||
|  | rule assert-project-id ( id ? : module-name ? ) | ||
|  | { | ||
|  |     module-name ?= [ CALLER_MODULE ] ; | ||
|  |     assert.result $(id) : project.attribute $(module-name) id ; | ||
|  | } | ||
|  | 
 | ||
|  | # Project rule modifies the main project id. | ||
|  | assert-project-id ;  # Initial project id is empty | ||
|  | project foo  ; assert-project-id /foo ; | ||
|  | project      ; assert-project-id /foo ; | ||
|  | project foo  ; assert-project-id /foo ; | ||
|  | project bar  ; assert-project-id /bar ; | ||
|  | project /foo ; assert-project-id /foo ; | ||
|  | project ""   ; assert-project-id /foo ; | ||
|  | 
 | ||
|  | # Calling the use-project rule does not modify the project's main id. | ||
|  | use-project id1 : a ; | ||
|  | # We need to load the 'a' Jamfile module manually as the use-project rule will | ||
|  | # only schedule the load to be done after the current module load finishes. | ||
|  | a-module = [ project.load a ] ; | ||
|  | assert-project-id : $(a-module) ; | ||
|  | use-project id2 : a ; | ||
|  | assert-project-id : $(a-module) ; | ||
|  | modules.call-in $(a-module) : project baz ; | ||
|  | assert-project-id /baz : $(a-module) ; | ||
|  | use-project id3 : a ; | ||
|  | assert-project-id /baz : $(a-module) ; | ||
|  | 
 | ||
|  | # Make sure the project id still holds after all the scheduled use-project loads | ||
|  | # complete. We do this by scheduling the assert for the Jam action scheduling | ||
|  | # phase. | ||
|  | notfile x : @assert-a-rule ; | ||
|  | rule assert-a-rule ( target : : properties * ) | ||
|  | { | ||
|  |     assert-project-id /baz : $(a-module) ; | ||
|  | } | ||
|  | """)
 | ||
|  |     t.write("a/jamfile.jam", """\
 | ||
|  | # Initial project id for this module is empty. | ||
|  | assert-project-id ; | ||
|  | """)
 | ||
|  |     t.run_build_system() | ||
|  |     t.cleanup() | ||
|  | 
 | ||
|  | 
 | ||
|  | def test_using_project_ids_in_target_references(): | ||
|  |     t = BoostBuild.Tester() | ||
|  |     __write_appender(t, "appender.jam") | ||
|  |     t.write("jamroot.jam", """\
 | ||
|  | import type ; | ||
|  | type.register AAA : _a ; | ||
|  | type.register BBB : _b ; | ||
|  | 
 | ||
|  | import appender ; | ||
|  | appender.register aaa-to-bbb : AAA : BBB ; | ||
|  | 
 | ||
|  | use-project id1 : a ; | ||
|  | use-project /id2 : a ; | ||
|  | 
 | ||
|  | bbb b1 : /id1//target ; | ||
|  | bbb b2 : /id2//target ; | ||
|  | bbb b3 : /id3//target ; | ||
|  | bbb b4 : a//target ; | ||
|  | bbb b5 : /project-a1//target ; | ||
|  | bbb b6 : /project-a2//target ; | ||
|  | bbb b7 : /project-a3//target ; | ||
|  | 
 | ||
|  | use-project id3 : a ; | ||
|  | """)
 | ||
|  |     t.write("a/source._a", "") | ||
|  |     t.write("a/jamfile.jam", """\
 | ||
|  | project project-a1 ; | ||
|  | project /project-a2 ; | ||
|  | import alias ; | ||
|  | alias target : source._a ; | ||
|  | project /project-a3 ; | ||
|  | """)
 | ||
|  | 
 | ||
|  |     t.run_build_system() | ||
|  |     t.expect_addition("bin/$toolset/b%d._b" % x for x in range(1, 8)) | ||
|  |     t.expect_nothing_more() | ||
|  | 
 | ||
|  |     t.cleanup() | ||
|  | 
 | ||
|  | 
 | ||
|  | def test_repeated_ids_for_different_projects(): | ||
|  |     t = BoostBuild.Tester() | ||
|  | 
 | ||
|  |     t.write("a/jamfile.jam", "") | ||
|  |     t.write("jamroot.jam", "project foo ; use-project foo : a ;") | ||
|  |     t.run_build_system(status=1) | ||
|  |     t.expect_output_lines("""\
 | ||
|  | error: Attempt to redeclare already registered project id '/foo'. | ||
|  | error: Original project: | ||
|  | error:     Name: Jamfile<*> | ||
|  | error:     Module: Jamfile<*> | ||
|  | error:     Main id: /foo | ||
|  | error:     File: jamroot.jam | ||
|  | error:     Location: . | ||
|  | error: New project: | ||
|  | error:     Module: Jamfile<*> | ||
|  | error:     File: a*jamfile.jam | ||
|  | error:     Location: a""")
 | ||
|  | 
 | ||
|  |     t.write("jamroot.jam", "use-project foo : a ; project foo ;") | ||
|  |     t.run_build_system(status=1) | ||
|  |     t.expect_output_lines("""\
 | ||
|  | error: Attempt to redeclare already registered project id '/foo'. | ||
|  | error: Original project: | ||
|  | error:     Name: Jamfile<*> | ||
|  | error:     Module: Jamfile<*> | ||
|  | error:     Main id: /foo | ||
|  | error:     File: jamroot.jam | ||
|  | error:     Location: . | ||
|  | error: New project: | ||
|  | error:     Module: Jamfile<*> | ||
|  | error:     File: a*jamfile.jam | ||
|  | error:     Location: a""")
 | ||
|  | 
 | ||
|  |     t.write("jamroot.jam", """\
 | ||
|  | import modules ; | ||
|  | import project ; | ||
|  | modules.call-in [ project.load a ] : project foo ; | ||
|  | project foo ; | ||
|  | """)
 | ||
|  |     t.run_build_system(status=1) | ||
|  |     t.expect_output_lines("""\
 | ||
|  | error: at jamroot.jam:4 | ||
|  | error: Attempt to redeclare already registered project id '/foo'. | ||
|  | error: Original project: | ||
|  | error:     Name: Jamfile<*> | ||
|  | error:     Module: Jamfile<*> | ||
|  | error:     Main id: /foo | ||
|  | error:     File: a*jamfile.jam | ||
|  | error:     Location: a | ||
|  | error: New project: | ||
|  | error:     Module: Jamfile<*> | ||
|  | error:     File: jamroot.jam | ||
|  | error:     Location: .""")
 | ||
|  | 
 | ||
|  |     t.cleanup() | ||
|  | 
 | ||
|  | 
 | ||
|  | def test_repeated_ids_for_same_project(): | ||
|  |     t = BoostBuild.Tester() | ||
|  | 
 | ||
|  |     t.write("jamroot.jam", "project foo ; project foo ;") | ||
|  |     t.run_build_system() | ||
|  | 
 | ||
|  |     t.write("jamroot.jam", "project foo ; use-project foo : . ;") | ||
|  |     t.run_build_system() | ||
|  | 
 | ||
|  |     t.write("jamroot.jam", "project foo ; use-project foo : ./. ;") | ||
|  |     t.run_build_system() | ||
|  | 
 | ||
|  |     t.write("jamroot.jam", """\
 | ||
|  | project foo ; | ||
|  | use-project foo : . ; | ||
|  | use-project foo : ./aaa/.. ; | ||
|  | use-project foo : ./. ; | ||
|  | """)
 | ||
|  |     t.run_build_system() | ||
|  | 
 | ||
|  |     # On Windows we have a case-insensitive file system and we can use | ||
|  |     # backslashes as path separators. | ||
|  |     # FIXME: Make a similar test pass on Cygwin. | ||
|  |     if sys.platform in ['win32']: | ||
|  |         t.write("a/fOo bAr/b/jamfile.jam", "") | ||
|  |         t.write("jamroot.jam", r"""
 | ||
|  | use-project bar : "a/foo bar/b" ; | ||
|  | use-project bar : "a/foO Bar/b" ; | ||
|  | use-project bar : "a/foo BAR/b/" ; | ||
|  | use-project bar : "a\\.\\FOO bar\\b\\" ; | ||
|  | """)
 | ||
|  |         t.run_build_system() | ||
|  |         t.rm("a") | ||
|  | 
 | ||
|  |     t.write("bar/jamfile.jam", "") | ||
|  |     t.write("jamroot.jam", """\
 | ||
|  | use-project bar : bar ; | ||
|  | use-project bar : bar/ ; | ||
|  | use-project bar : bar// ; | ||
|  | use-project bar : bar/// ; | ||
|  | use-project bar : bar//// ; | ||
|  | use-project bar : bar/. ; | ||
|  | use-project bar : bar/./ ; | ||
|  | use-project bar : bar/////./ ; | ||
|  | use-project bar : bar/../bar/xxx/.. ; | ||
|  | use-project bar : bar/..///bar/xxx///////.. ; | ||
|  | use-project bar : bar/./../bar/xxx/.. ; | ||
|  | use-project bar : bar/.////../bar/xxx/.. ; | ||
|  | use-project bar : bar/././../bar/xxx/.. ; | ||
|  | use-project bar : bar/././//////////../bar/xxx/.. ; | ||
|  | use-project bar : bar/.///.////../bar/xxx/.. ; | ||
|  | use-project bar : bar/./././xxx/.. ; | ||
|  | use-project bar : bar/xxx////.. ; | ||
|  | use-project bar : bar/xxx/.. ; | ||
|  | use-project bar : bar///////xxx/.. ; | ||
|  | """)
 | ||
|  |     t.run_build_system() | ||
|  |     t.rm("bar") | ||
|  | 
 | ||
|  |     # On Windows we have a case-insensitive file system and we can use | ||
|  |     # backslashes as path separators. | ||
|  |     # FIXME: Make a similar test pass on Cygwin. | ||
|  |     if sys.platform in ['win32']: | ||
|  |         t.write("baR/jamfile.jam", "") | ||
|  |         t.write("jamroot.jam", r"""
 | ||
|  | use-project bar : bar ; | ||
|  | use-project bar : BAR ; | ||
|  | use-project bar : bAr ; | ||
|  | use-project bar : bAr/ ; | ||
|  | use-project bar : bAr\\ ; | ||
|  | use-project bar : bAr\\\\ ; | ||
|  | use-project bar : bAr\\\\///// ; | ||
|  | use-project bar : bAr/. ; | ||
|  | use-project bar : bAr/./././ ; | ||
|  | use-project bar : bAr\\.\\.\\.\\ ; | ||
|  | use-project bar : bAr\\./\\/.\\.\\ ; | ||
|  | use-project bar : bAr/.\\././ ; | ||
|  | use-project bar : Bar ; | ||
|  | use-project bar : BaR ; | ||
|  | use-project bar : BaR/./../bAr/xxx/.. ; | ||
|  | use-project bar : BaR/./..\\bAr\\xxx/.. ; | ||
|  | use-project bar : BaR/xxx/.. ; | ||
|  | use-project bar : BaR///\\\\\\//xxx/.. ; | ||
|  | use-project bar : Bar\\xxx/.. ; | ||
|  | use-project bar : BAR/xXx/.. ; | ||
|  | use-project bar : BAR/xXx\\\\/\\/\\//\\.. ; | ||
|  | """)
 | ||
|  |         t.run_build_system() | ||
|  |         t.rm("baR") | ||
|  | 
 | ||
|  |     t.cleanup() | ||
|  | 
 | ||
|  | 
 | ||
|  | def test_unresolved_project_references(): | ||
|  |     t = BoostBuild.Tester() | ||
|  | 
 | ||
|  |     __write_appender(t, "appender.jam") | ||
|  |     t.write("a/source._a", "") | ||
|  |     t.write("a/jamfile.jam", "import alias ; alias target : source._a ;") | ||
|  |     t.write("jamroot.jam", """\
 | ||
|  | import type ; | ||
|  | type.register AAA : _a ; | ||
|  | type.register BBB : _b ; | ||
|  | 
 | ||
|  | import appender ; | ||
|  | appender.register aaa-to-bbb : AAA : BBB ; | ||
|  | 
 | ||
|  | use-project foo : a ; | ||
|  | 
 | ||
|  | bbb b1 : a//target ; | ||
|  | bbb b2 : /foo//target ; | ||
|  | bbb b-invalid : invalid//target ; | ||
|  | bbb b-root-invalid : /invalid//target ; | ||
|  | bbb b-missing-root : foo//target ; | ||
|  | bbb b-invalid-target : /foo//invalid ; | ||
|  | """)
 | ||
|  | 
 | ||
|  |     t.run_build_system(["b1", "b2"]) | ||
|  |     t.expect_addition("bin/$toolset/debug/b%d._b" % x for x in range(1, 3)) | ||
|  |     t.expect_nothing_more() | ||
|  | 
 | ||
|  |     t.run_build_system(["b-invalid"], status=1) | ||
|  |     t.expect_output_lines("""\
 | ||
|  | error: Unable to find file or target named | ||
|  | error:     'invalid//target' | ||
|  | error: referred to from project at | ||
|  | error:     '.' | ||
|  | error: could not resolve project reference 'invalid'""")
 | ||
|  | 
 | ||
|  |     t.run_build_system(["b-root-invalid"], status=1) | ||
|  |     t.expect_output_lines("""\
 | ||
|  | error: Unable to find file or target named | ||
|  | error:     '/invalid//target' | ||
|  | error: referred to from project at | ||
|  | error:     '.' | ||
|  | error: could not resolve project reference '/invalid'""")
 | ||
|  | 
 | ||
|  |     t.run_build_system(["b-missing-root"], status=1) | ||
|  |     t.expect_output_lines("""\
 | ||
|  | error: Unable to find file or target named | ||
|  | error:     'foo//target' | ||
|  | error: referred to from project at | ||
|  | error:     '.' | ||
|  | error: could not resolve project reference 'foo' - possibly missing a """
 | ||
|  |     "leading slash ('/') character.") | ||
|  | 
 | ||
|  |     t.run_build_system(["b-invalid-target"], status=1) | ||
|  |     t.expect_output_lines("""\
 | ||
|  | error: Unable to find file or target named | ||
|  | error:     '/foo//invalid' | ||
|  | error: referred to from project at | ||
|  | error:     '.'""")
 | ||
|  |     t.expect_output_lines("*could not resolve project reference*", False) | ||
|  | 
 | ||
|  |     t.cleanup() | ||
|  | 
 | ||
|  | 
 | ||
|  | def __write_appender(t, name): | ||
|  |     t.write(name, | ||
|  | r"""# Copyright 2012 Jurko Gospodnetic
 | ||
|  | # Distributed under the Boost Software License, Version 1.0. | ||
|  | # (See accompanying file LICENSE_1_0.txt or copy at | ||
|  | # http://www.boost.org/LICENSE_1_0.txt) | ||
|  | 
 | ||
|  | #   Support for registering test generators that construct their targets by | ||
|  | # simply appending their given input data, e.g. list of sources & targets. | ||
|  | 
 | ||
|  | import "class" : new ; | ||
|  | import generators ; | ||
|  | import modules ; | ||
|  | import sequence ; | ||
|  | 
 | ||
|  | rule register ( id composing ? : source-types + : target-types + ) | ||
|  | { | ||
|  |     local caller-module = [ CALLER_MODULE ] ; | ||
|  |     id = $(caller-module).$(id) ; | ||
|  |     local g = [ new generator $(id) $(composing) : $(source-types) : | ||
|  |         $(target-types) ] ; | ||
|  |     $(g).set-rule-name $(__name__).appender ; | ||
|  |     generators.register $(g) ; | ||
|  |     return $(id) ; | ||
|  | } | ||
|  | 
 | ||
|  | if [ modules.peek : NT ] | ||
|  | { | ||
|  |     X = ")" ; | ||
|  |     ECHO_CMD = (echo. ; | ||
|  | } | ||
|  | else | ||
|  | { | ||
|  |     X = \" ; | ||
|  |     ECHO_CMD = "echo $(X)" ; | ||
|  | } | ||
|  | 
 | ||
|  | local appender-runs ; | ||
|  | 
 | ||
|  | # We set up separate actions for building each target in order to avoid having | ||
|  | # to iterate over them in action (i.e. shell) code. We have to be extra careful | ||
|  | # though to achieve the exact same effect as if doing all the work in just one | ||
|  | # action. Otherwise Boost Jam might, under some circumstances, run only some of | ||
|  | # our actions. To achieve this we register a series of actions for all the | ||
|  | # targets (since they all have the same target list - either all or none of them | ||
|  | # get run independent of which target actually needs to get built), each | ||
|  | # building only a single target. Since all our actions use the same targets, we | ||
|  | # can not use 'on-target' parameters to pass data to a specific action so we | ||
|  | # pass them using the second 'sources' parameter which our actions then know how | ||
|  | # to interpret correctly. This works well since Boost Jam does not automatically | ||
|  | # add dependency relations between specified action targets & sources and so the | ||
|  | # second argument, even though most often used to pass in a list of sources, can | ||
|  | # actually be used for passing in any type of information. | ||
|  | rule appender ( targets + : sources + : properties * ) | ||
|  | { | ||
|  |     appender-runs = [ CALC $(appender-runs:E=0) + 1 ] ; | ||
|  |     local target-index = 0 ; | ||
|  |     local target-count = [ sequence.length $(targets) ] ; | ||
|  |     local original-targets ; | ||
|  |     for t in $(targets) | ||
|  |     { | ||
|  |         target-index = [ CALC $(target-index) + 1 ] ; | ||
|  |         local appender-run = $(appender-runs) ; | ||
|  |         if $(targets[2])-defined | ||
|  |         { | ||
|  |             appender-run += [$(target-index)/$(target-count)] ; | ||
|  |         } | ||
|  |         append $(targets) : $(appender-run:J=" ") $(t) $(sources) ; | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | actions append | ||
|  | { | ||
|  |     $(ECHO_CMD)-------------------------------------------------$(X) | ||
|  |     $(ECHO_CMD)Appender run: $(>[1])$(X) | ||
|  |     $(ECHO_CMD)Appender run: $(>[1])$(X)>> "$(>[2])" | ||
|  |     $(ECHO_CMD)Target group: $(<:J=' ')$(X) | ||
|  |     $(ECHO_CMD)Target group: $(<:J=' ')$(X)>> "$(>[2])" | ||
|  |     $(ECHO_CMD)      Target: '$(>[2])'$(X) | ||
|  |     $(ECHO_CMD)      Target: '$(>[2])'$(X)>> "$(>[2])" | ||
|  |     $(ECHO_CMD)     Sources: '$(>[3-]:J=' ')'$(X) | ||
|  |     $(ECHO_CMD)     Sources: '$(>[3-]:J=' ')'$(X)>> "$(>[2])" | ||
|  |     $(ECHO_CMD)=================================================$(X) | ||
|  |     $(ECHO_CMD)-------------------------------------------------$(X)>> "$(>[2])" | ||
|  | } | ||
|  | """)
 | ||
|  | 
 | ||
|  | 
 | ||
|  | test_assigning_project_ids() | ||
|  | test_using_project_ids_in_target_references() | ||
|  | test_repeated_ids_for_same_project() | ||
|  | test_repeated_ids_for_different_projects() | ||
|  | test_unresolved_project_references() |