Browse Source

Merge topic 'test-properties-directory'

2ccb897d86 get_test_property(): Add DIRECTORY option
84e76fedb0 get_property(TEST): Add DIRECTORY option
efc8f19cc5 set_tests_properties(): Add DIRECTORY option
753999d4db set_property(TEST): Add DIRECTORY option

Acked-by: Kitware Robot <[email protected]>
Acked-by: buildbot <[email protected]>
Merge-request: !8709
Kyle Edwards 2 years ago
parent
commit
2eab65ca82
29 changed files with 333 additions and 30 deletions
  1. 12 1
      Help/command/get_property.rst
  2. 12 1
      Help/command/get_test_property.rst
  3. 13 1
      Help/command/set_property.rst
  4. 10 0
      Help/command/set_tests_properties.rst
  5. 15 0
      Help/release/dev/test-properties-directory.rst
  6. 25 7
      Source/cmGetPropertyCommand.cxx
  7. 24 3
      Source/cmGetTestPropertyCommand.cxx
  8. 79 7
      Source/cmSetPropertyCommand.cxx
  9. 12 0
      Source/cmSetPropertyCommand.h
  10. 28 2
      Source/cmSetTestsPropertiesCommand.cxx
  11. 1 0
      Tests/RunCMake/CMakeLists.txt
  12. 8 2
      Tests/RunCMake/get_property/test_properties-stderr.txt
  13. 13 6
      Tests/RunCMake/get_property/test_properties.cmake
  14. 4 0
      Tests/RunCMake/get_property/test_properties/CMakeLists.txt
  15. 6 0
      Tests/RunCMake/set_property/RunCMakeTest.cmake
  16. 1 0
      Tests/RunCMake/set_property/TEST-invalid-result.txt
  17. 11 0
      Tests/RunCMake/set_property/TEST-invalid-stderr.txt
  18. 4 0
      Tests/RunCMake/set_property/TEST-invalid.cmake
  19. 3 0
      Tests/RunCMake/set_property/TEST-subdir1/CMakeLists.txt
  20. 1 0
      Tests/RunCMake/set_property/TEST-subdir2/CMakeLists.txt
  21. 9 0
      Tests/RunCMake/set_property/TEST.cmake
  22. 3 0
      Tests/RunCMake/set_tests_properties/CMakeLists.txt
  23. 1 0
      Tests/RunCMake/set_tests_properties/DIRECTORY-invalid-result.txt
  24. 13 0
      Tests/RunCMake/set_tests_properties/DIRECTORY-invalid-stderr.txt
  25. 4 0
      Tests/RunCMake/set_tests_properties/DIRECTORY-invalid.cmake
  26. 3 0
      Tests/RunCMake/set_tests_properties/DIRECTORY-subdir1/CMakeLists.txt
  27. 1 0
      Tests/RunCMake/set_tests_properties/DIRECTORY-subdir2/CMakeLists.txt
  28. 9 0
      Tests/RunCMake/set_tests_properties/DIRECTORY.cmake
  29. 8 0
      Tests/RunCMake/set_tests_properties/RunCMakeTest.cmake

+ 12 - 1
Help/command/get_property.rst

@@ -12,7 +12,8 @@ Get a property.
                 SOURCE    <source>
                           [DIRECTORY <dir> | TARGET_DIRECTORY <target>] |
                 INSTALL   <file>   |
-                TEST      <test>   |
+                TEST      <test>
+                          [DIRECTORY <dir>] |
                 CACHE     <entry>  |
                 VARIABLE           >
                PROPERTY <name>
@@ -73,6 +74,16 @@ It must be one of the following:
   Scope must name one existing test.
   See also the :command:`get_test_property` command.
 
+  .. versionadded:: 3.28
+    Directory scope can be overridden with the following sub-option:
+
+    ``DIRECTORY <dir>``
+      The test property will be read from the ``<dir>`` directory's
+      scope.  CMake must already know about the directory, either by having added
+      it through a call to :command:`add_subdirectory` or ``<dir>`` being the top
+      level directory. Relative paths are treated as relative to the current
+      source directory. ``<dir>`` may reference a binary directory.
+
 ``CACHE``
   Scope must name one cache entry.
 

+ 12 - 1
Help/command/get_test_property.rst

@@ -5,7 +5,7 @@ Get a property of the test.
 
 .. code-block:: cmake
 
-  get_test_property(test property VAR)
+  get_test_property(test property [DIRECTORY <dir>] VAR)
 
 Get a property from the test.  The value of the property is stored in
 the variable ``VAR``.  If the test property is not found, the behavior
@@ -19,6 +19,17 @@ an empty string.
 For a list of standard properties you can type
 :option:`cmake --help-property-list`.
 
+.. versionadded:: 3.28
+  Directory scope can be overridden with the following sub-option:
+
+  ``DIRECTORY <dir>``
+    The test property will be read from the ``<dir>`` directory's
+    scope.  CMake must already know about that source directory, either by
+    having added it through a call to :command:`add_subdirectory` or ``<dir>``
+    being the top level source directory.  Relative paths are treated as
+    relative to the current source directory. ``<dir>`` may reference a binary
+    directory.
+
 See Also
 ^^^^^^^^
 

+ 13 - 1
Help/command/set_property.rst

@@ -12,7 +12,8 @@ Set a named property in a given scope.
                           [DIRECTORY <dirs> ...]
                           [TARGET_DIRECTORY <targets> ...] |
                 INSTALL   [<file1> ...]     |
-                TEST      [<test1> ...]     |
+                TEST      [<test1> ...]
+                          [DIRECTORY <dir>] |
                 CACHE     [<entry1> ...]    >
                [APPEND] [APPEND_STRING]
                PROPERTY <name> [<value1> ...])
@@ -91,6 +92,17 @@ It must be one of the following:
   :manual:`generator expressions <cmake-generator-expressions(7)>`
   for tests created by the :command:`add_test(NAME)` signature.
 
+  .. versionadded:: 3.28
+
+    Visibility can be set in other directory scopes using the following sub-option:
+
+    ``DIRECTORY <dir>``
+      The test property will be set in the ``<dir>`` directory's scope. CMake must
+      already know about this directory, either by having added it through a call
+      to :command:`add_subdirectory` or it being the top level source directory.
+      Relative paths are treated as relative to the current source directory.
+      ``<dir>`` may reference a binary directory.
+
 ``CACHE``
   Scope must name zero or more existing cache entries.
 

+ 10 - 0
Help/command/set_tests_properties.rst

@@ -14,6 +14,16 @@ Test property values may be specified using
 :manual:`generator expressions <cmake-generator-expressions(7)>`
 for tests created by the :command:`add_test(NAME)` signature.
 
+.. versionadded:: 3.28
+  Visibility can be set in other directory scopes using the following option:
+
+  ``DIRECTORY <dir>``
+    The test properties will be set in the ``<dir>`` directory's scope.
+    CMake must already know about this directory, either by having added it
+    through a call to :command:`add_subdirectory` or it being the top level
+    source directory. Relative paths are treated as relative to the current
+    source directory. ``<dir>`` may reference a binary directory.
+
 See Also
 ^^^^^^^^
 

+ 15 - 0
Help/release/dev/test-properties-directory.rst

@@ -0,0 +1,15 @@
+test-properties-directory
+-------------------------
+
+* The ``TEST`` mode of the :command:`set_property` command gained a
+  ``DIRECTORY`` sub-option, which allows you to set properties on tests in
+  other directories.
+* The :command:`set_tests_properties` command gained a ``DIRECTORY``
+  sub-option, which allows you to set properties on tests in other
+  directories.
+* The ``TEST`` mode of the :command:`get_property` command gained a
+  ``DIRECTORY`` sub-option, which allows you to get properties on tests in
+  other directories.
+* The :command:`get_test_property` command gained a ``DIRECTORY``
+  sub-option, which allows you to get properties on tests in other
+  directories.

+ 25 - 7
Source/cmGetPropertyCommand.cxx

@@ -49,7 +49,8 @@ bool HandleSourceMode(cmExecutionStatus& status, const std::string& name,
                       bool source_file_paths_should_be_absolute);
 bool HandleTestMode(cmExecutionStatus& status, const std::string& name,
                     OutType infoType, const std::string& variable,
-                    const std::string& propertyName);
+                    const std::string& propertyName,
+                    cmMakefile& directory_makefile);
 bool HandleVariableMode(cmExecutionStatus& status, const std::string& name,
                         OutType infoType, const std::string& variable,
                         const std::string& propertyName);
@@ -81,6 +82,9 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
   bool source_file_directory_option_enabled = false;
   bool source_file_target_option_enabled = false;
 
+  std::string test_directory;
+  bool test_directory_option_enabled = false;
+
   // Get the scope from which to get the property.
   cmProperty::ScopeType scope;
   if (args[1] == "GLOBAL") {
@@ -116,7 +120,8 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
     DoingProperty,
     DoingType,
     DoingSourceDirectory,
-    DoingSourceTargetDirectory
+    DoingSourceTargetDirectory,
+    DoingTestDirectory,
   };
   Doing doing = DoingName;
   for (unsigned int i = 2; i < args.size(); ++i) {
@@ -145,12 +150,19 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
                args[i] == "TARGET_DIRECTORY") {
       doing = DoingSourceTargetDirectory;
       source_file_target_option_enabled = true;
+    } else if (doing == DoingNone && scope == cmProperty::TEST &&
+               args[i] == "DIRECTORY") {
+      doing = DoingTestDirectory;
+      test_directory_option_enabled = true;
     } else if (doing == DoingSourceDirectory) {
       source_file_directories.push_back(args[i]);
       doing = DoingNone;
     } else if (doing == DoingSourceTargetDirectory) {
       source_file_target_directories.push_back(args[i]);
       doing = DoingNone;
+    } else if (doing == DoingTestDirectory) {
+      test_directory = args[i];
+      doing = DoingNone;
     } else if (doing == DoingProperty) {
       doing = DoingNone;
       propertyName = args[i];
@@ -167,12 +179,17 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
   }
 
   std::vector<cmMakefile*> source_file_directory_makefiles;
-  bool file_scopes_handled =
+  bool source_file_scopes_handled =
     SetPropertyCommand::HandleAndValidateSourceFileDirectoryScopes(
       status, source_file_directory_option_enabled,
       source_file_target_option_enabled, source_file_directories,
       source_file_target_directories, source_file_directory_makefiles);
-  if (!file_scopes_handled) {
+  cmMakefile* test_directory_makefile;
+  bool test_scopes_handled =
+    SetPropertyCommand::HandleAndValidateTestDirectoryScopes(
+      status, test_directory_option_enabled, test_directory,
+      test_directory_makefile);
+  if (!(source_file_scopes_handled && test_scopes_handled)) {
     return false;
   }
 
@@ -231,7 +248,8 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
                                 directory_scope_mf,
                                 source_file_paths_should_be_absolute);
       case cmProperty::TEST:
-        return HandleTestMode(status, name, infoType, variable, propertyName);
+        return HandleTestMode(status, name, infoType, variable, propertyName,
+                              *test_directory_makefile);
       case cmProperty::VARIABLE:
         return HandleVariableMode(status, name, infoType, variable,
                                   propertyName);
@@ -404,7 +422,7 @@ bool HandleSourceMode(cmExecutionStatus& status, const std::string& name,
 
 bool HandleTestMode(cmExecutionStatus& status, const std::string& name,
                     OutType infoType, const std::string& variable,
-                    const std::string& propertyName)
+                    const std::string& propertyName, cmMakefile& test_makefile)
 {
   if (name.empty()) {
     status.SetError("not given name for TEST scope.");
@@ -412,7 +430,7 @@ bool HandleTestMode(cmExecutionStatus& status, const std::string& name,
   }
 
   // Loop over all tests looking for matching names.
-  if (cmTest* test = status.GetMakefile().GetTest(name)) {
+  if (cmTest* test = test_makefile.GetTest(name)) {
     return StoreResult(infoType, status.GetMakefile(), variable,
                        test->GetProperty(propertyName));
   }

+ 24 - 3
Source/cmGetTestPropertyCommand.cxx

@@ -4,21 +4,42 @@
 
 #include "cmExecutionStatus.h"
 #include "cmMakefile.h"
+#include "cmSetPropertyCommand.h"
 #include "cmTest.h"
 #include "cmValue.h"
 
 bool cmGetTestPropertyCommand(std::vector<std::string> const& args,
                               cmExecutionStatus& status)
 {
-  if (args.size() < 3) {
+  std::vector<std::string>::size_type args_size = args.size();
+  if (args_size != 3 && args_size != 5) {
     status.SetError("called with incorrect number of arguments");
     return false;
   }
 
+  std::string test_directory;
+  bool test_directory_option_enabled = false;
+
+  int var_arg_index = 2;
+  if (args[2] == "DIRECTORY" && args_size == 5) {
+    var_arg_index = 4;
+    test_directory_option_enabled = true;
+    test_directory = args[3];
+  }
+
+  cmMakefile* test_directory_makefile = &status.GetMakefile();
+  bool file_scopes_handled =
+    SetPropertyCommand::HandleAndValidateTestDirectoryScopes(
+      status, test_directory_option_enabled, test_directory,
+      test_directory_makefile);
+  if (!file_scopes_handled) {
+    return false;
+  }
+
   std::string const& testName = args[0];
-  std::string const& var = args[2];
+  std::string const& var = args[var_arg_index];
   cmMakefile& mf = status.GetMakefile();
-  cmTest* test = mf.GetTest(testName);
+  cmTest* test = test_directory_makefile->GetTest(testName);
   if (test) {
     cmValue prop;
     if (!args[1].empty()) {

+ 79 - 7
Source/cmSetPropertyCommand.cxx

@@ -58,7 +58,8 @@ bool HandleSource(cmSourceFile* sf, const std::string& propertyName,
 bool HandleTestMode(cmExecutionStatus& status, std::set<std::string>& names,
                     const std::string& propertyName,
                     const std::string& propertyValue, bool appendAsString,
-                    bool appendMode, bool remove);
+                    bool appendMode, bool remove,
+                    cmMakefile* test_directory_makefile);
 bool HandleTest(cmTest* test, const std::string& propertyName,
                 const std::string& propertyValue, bool appendAsString,
                 bool appendMode, bool remove);
@@ -184,6 +185,60 @@ bool HandleAndValidateSourceFileDirectoryScopes(
   return scope_options_valid;
 }
 
+bool HandleTestDirectoryScopes(cmExecutionStatus& status,
+                               std::string& test_directory,
+                               cmMakefile*& directory_makefile)
+{
+  cmMakefile* current_dir_mf = &status.GetMakefile();
+  if (!test_directory.empty()) {
+    const std::string absolute_dir_path = cmSystemTools::CollapseFullPath(
+      test_directory, current_dir_mf->GetCurrentSourceDirectory());
+    cmMakefile* dir_mf =
+      status.GetMakefile().GetGlobalGenerator()->FindMakefile(
+        absolute_dir_path);
+    if (!dir_mf) {
+      status.SetError(
+        cmStrCat("given non-existent DIRECTORY ", test_directory));
+      return false;
+    }
+    directory_makefile = dir_mf;
+  } else {
+    directory_makefile = current_dir_mf;
+  }
+  return true;
+}
+
+bool HandleTestDirectoryScopeValidation(cmExecutionStatus& status,
+                                        bool test_directory_option_enabled,
+                                        std::string& test_directory)
+{
+  // Validate source file directory scopes.
+  if (test_directory_option_enabled && test_directory.empty()) {
+    std::string errors = "called with incorrect number of arguments "
+                         "no value provided to the DIRECTORY option";
+    status.SetError(errors);
+    return false;
+  }
+  return true;
+}
+
+bool HandleAndValidateTestDirectoryScopes(cmExecutionStatus& status,
+                                          bool test_directory_option_enabled,
+                                          std::string& test_directory,
+                                          cmMakefile*& test_directory_makefile)
+{
+  bool scope_options_valid =
+    SetPropertyCommand::HandleTestDirectoryScopeValidation(
+      status, test_directory_option_enabled, test_directory);
+  if (!scope_options_valid) {
+    return false;
+  }
+
+  scope_options_valid = SetPropertyCommand::HandleTestDirectoryScopes(
+    status, test_directory, test_directory_makefile);
+  return scope_options_valid;
+}
+
 std::string MakeSourceFilePathAbsoluteIfNeeded(
   cmExecutionStatus& status, const std::string& source_file_path,
   const bool needed)
@@ -352,6 +407,9 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
   bool source_file_directory_option_enabled = false;
   bool source_file_target_option_enabled = false;
 
+  std::string test_directory;
+  bool test_directory_option_enabled = false;
+
   // Parse the rest of the arguments up to the values.
   enum Doing
   {
@@ -360,7 +418,8 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
     DoingProperty,
     DoingValues,
     DoingSourceDirectory,
-    DoingSourceTargetDirectory
+    DoingSourceTargetDirectory,
+    DoingTestDirectory,
   };
   Doing doing = DoingNames;
   const char* sep = "";
@@ -385,12 +444,19 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
                scope == cmProperty::SOURCE_FILE && arg == "TARGET_DIRECTORY") {
       doing = DoingSourceTargetDirectory;
       source_file_target_option_enabled = true;
+    } else if (doing != DoingProperty && doing != DoingValues &&
+               scope == cmProperty::TEST && arg == "DIRECTORY") {
+      doing = DoingTestDirectory;
+      test_directory_option_enabled = true;
     } else if (doing == DoingNames) {
       names.insert(arg);
     } else if (doing == DoingSourceDirectory) {
       source_file_directories.push_back(arg);
     } else if (doing == DoingSourceTargetDirectory) {
       source_file_target_directories.push_back(arg);
+    } else if (doing == DoingTestDirectory) {
+      test_directory = arg;
+      doing = DoingNone;
     } else if (doing == DoingProperty) {
       propertyName = arg;
       doing = DoingValues;
@@ -412,12 +478,17 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
   }
 
   std::vector<cmMakefile*> source_file_directory_makefiles;
-  bool file_scopes_handled =
+  bool source_file_scopes_handled =
     SetPropertyCommand::HandleAndValidateSourceFileDirectoryScopes(
       status, source_file_directory_option_enabled,
       source_file_target_option_enabled, source_file_directories,
       source_file_target_directories, source_file_directory_makefiles);
-  if (!file_scopes_handled) {
+  cmMakefile* test_directory_makefile;
+  bool test_scopes_handled =
+    SetPropertyCommand::HandleAndValidateTestDirectoryScopes(
+      status, test_directory_option_enabled, test_directory,
+      test_directory_makefile);
+  if (!(source_file_scopes_handled && test_scopes_handled)) {
     return false;
   }
   bool source_file_paths_should_be_absolute =
@@ -441,7 +512,8 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
                               source_file_paths_should_be_absolute);
     case cmProperty::TEST:
       return HandleTestMode(status, names, propertyName, propertyValue,
-                            appendAsString, appendMode, remove);
+                            appendAsString, appendMode, remove,
+                            test_directory_makefile);
     case cmProperty::CACHE:
       return HandleCacheMode(status, names, propertyName, propertyValue,
                              appendAsString, appendMode, remove);
@@ -642,14 +714,14 @@ bool HandleSource(cmSourceFile* sf, const std::string& propertyName,
 bool HandleTestMode(cmExecutionStatus& status, std::set<std::string>& names,
                     const std::string& propertyName,
                     const std::string& propertyValue, bool appendAsString,
-                    bool appendMode, bool remove)
+                    bool appendMode, bool remove, cmMakefile* test_makefile)
 {
   // Look for tests with all names given.
   std::set<std::string>::iterator next;
   for (auto ni = names.begin(); ni != names.end(); ni = next) {
     next = ni;
     ++next;
-    if (cmTest* test = status.GetMakefile().GetTest(*ni)) {
+    if (cmTest* test = test_makefile->GetTest(*ni)) {
       if (HandleTest(test, propertyName, propertyValue, appendAsString,
                      appendMode, remove)) {
         names.erase(ni);

+ 12 - 0
Source/cmSetPropertyCommand.h

@@ -33,6 +33,18 @@ bool HandleAndValidateSourceFileDirectoryScopes(
   std::vector<std::string>& source_target_directories,
   std::vector<cmMakefile*>& source_file_directory_makefiles);
 
+bool HandleTestDirectoryScopes(cmExecutionStatus& status,
+                               std::string& test_directory,
+                               cmMakefile*& directory_makefile);
+
+bool HandleTestDirectoryScopeValidation(cmExecutionStatus& status,
+                                        bool test_directory_option_enabled,
+                                        std::string& test_directory);
+
+bool HandleAndValidateTestDirectoryScopes(
+  cmExecutionStatus& status, bool test_directory_option_encountered,
+  std::string& test_directory, cmMakefile*& test_directory_makefile);
+
 std::string MakeSourceFilePathAbsoluteIfNeeded(
   cmExecutionStatus& status, const std::string& source_file_path, bool needed);
 void MakeSourceFilePathsAbsoluteIfNeeded(

+ 28 - 2
Source/cmSetTestsPropertiesCommand.cxx

@@ -5,9 +5,15 @@
 #include <algorithm>
 #include <iterator>
 
+#include <cmext/string_view>
+
+#include "cmArgumentParser.h"
 #include "cmExecutionStatus.h"
+#include "cmGlobalGenerator.h"
 #include "cmMakefile.h"
+#include "cmRange.h"
 #include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
 #include "cmTest.h"
 
 bool cmSetTestsPropertiesCommand(std::vector<std::string> const& args,
@@ -31,9 +37,29 @@ bool cmSetTestsPropertiesCommand(std::vector<std::string> const& args,
     return false;
   }
 
+  std::vector<std::string> tests;
+  std::string directory;
+  cmArgumentParser<void> parser;
+  parser.Bind("DIRECTORY"_s, directory);
+  auto result = parser.Parse(cmStringRange{ args.begin(), propsIter }, &tests);
+
+  cmMakefile* mf = &status.GetMakefile();
+  if (result.MaybeReportError(*mf)) {
+    return false;
+  }
+  if (!directory.empty()) {
+    std::string absDirectory = cmSystemTools::CollapseFullPath(
+      directory, mf->GetCurrentSourceDirectory());
+    mf = mf->GetGlobalGenerator()->FindMakefile(absDirectory);
+    if (!mf) {
+      status.SetError(cmStrCat("given non-existent DIRECTORY ", directory));
+      return false;
+    }
+  }
+
   // loop over all the tests
-  for (const std::string& tname : cmStringRange{ args.begin(), propsIter }) {
-    if (cmTest* test = status.GetMakefile().GetTest(tname)) {
+  for (const std::string& tname : tests) {
+    if (cmTest* test = mf->GetTest(tname)) {
       // loop through all the props and set them
       for (auto k = propsIter + 1; k != args.end(); k += 2) {
         if (!k->empty()) {

+ 1 - 0
Tests/RunCMake/CMakeLists.txt

@@ -1064,6 +1064,7 @@ add_RunCMake_test(CMakePresetsWorkflow
   )
 
 add_RunCMake_test(VerifyHeaderSets)
+add_RunCMake_test(set_tests_properties)
 
 if(${CMAKE_GENERATOR} MATCHES "Make|Ninja")
   add_RunCMake_test(TransformDepfile)

+ 8 - 2
Tests/RunCMake/get_property/test_properties-stderr.txt

@@ -1,6 +1,12 @@
-^get_test_property: --><--
+^get_test_property: -->value<--
+get_property: -->value<--
+get_test_property: --><--
 get_property: --><--
 get_test_property: -->value<--
 get_property: -->value<--
 get_test_property: -->NOTFOUND<--
-get_property: --><--$
+get_property: --><--
+get_test_property: -->anotherValue<--
+get_property: -->anotherValue<--
+get_test_property: -->anotherValue<--
+get_property: -->anotherValue<--$

+ 13 - 6
Tests/RunCMake/get_property/test_properties.cmake

@@ -1,7 +1,11 @@
-function (check_test_property test prop)
-  get_test_property("${test}" "${prop}" gtp_val)
+function (check_test_property test prop dir)
+  set(dir_args)
+  if(dir)
+    set(dir_args DIRECTORY ${dir})
+  endif()
+  get_test_property("${test}" "${prop}" ${dir_args} gtp_val)
   get_property(gp_val
-    TEST "${test}"
+    TEST "${test}" ${dir_args}
     PROPERTY "${prop}")
 
   message("get_test_property: -->${gtp_val}<--")
@@ -11,7 +15,10 @@ endfunction ()
 include(CTest)
 add_test(NAME test COMMAND "${CMAKE_COMMAND}" --help)
 set_tests_properties(test PROPERTIES empty "" custom value)
+add_subdirectory(test_properties)
 
-check_test_property(test empty)
-check_test_property(test custom)
-check_test_property(test noexist)
+check_test_property(test empty "")
+check_test_property(test custom "")
+check_test_property(test noexist "")
+check_test_property(test custom test_properties)
+check_test_property(test custom ${CMAKE_BINARY_DIR}/test_properties)

+ 4 - 0
Tests/RunCMake/get_property/test_properties/CMakeLists.txt

@@ -0,0 +1,4 @@
+add_test(NAME test COMMAND "${CMAKE_COMMAND}" --help)
+set_tests_properties(test PROPERTIES empty "" custom anotherValue)
+
+check_test_property(test custom ..)

+ 6 - 0
Tests/RunCMake/set_property/RunCMakeTest.cmake

@@ -10,6 +10,12 @@ run_cmake(LINK_DIRECTORIES)
 run_cmake(LINK_LIBRARIES)
 run_cmake(SOURCES)
 run_cmake(SOURCE_FILE)
+run_cmake(TEST-invalid)
 run_cmake(TYPE)
 run_cmake(USER_PROP)
 run_cmake(USER_PROP_INHERITED)
+
+set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/TEST-build")
+run_cmake(TEST)
+set(RunCMake_TEST_NO_CLEAN 1)
+run_cmake_command(TEST-test ${CMAKE_CTEST_COMMAND} -C Debug)

+ 1 - 0
Tests/RunCMake/set_property/TEST-invalid-result.txt

@@ -0,0 +1 @@
+1

+ 11 - 0
Tests/RunCMake/set_property/TEST-invalid-stderr.txt

@@ -0,0 +1,11 @@
+^CMake Error at TEST-invalid\.cmake:[0-9]+ \(set_property\):
+  set_property called with incorrect number of arguments no value provided to
+  the DIRECTORY option
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Error at TEST-invalid\.cmake:[0-9]+ \(set_property\):
+  set_property given non-existent DIRECTORY nonexistent
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)$

+ 4 - 0
Tests/RunCMake/set_property/TEST-invalid.cmake

@@ -0,0 +1,4 @@
+enable_testing()
+
+set_property(TEST t DIRECTORY PROPERTY PASS_REGULAR_EXPRESSION "Invalid")
+set_property(TEST t DIRECTORY nonexistent PROPERTY PASS_REGULAR_EXPRESSION "Invalid")

+ 3 - 0
Tests/RunCMake/set_property/TEST-subdir1/CMakeLists.txt

@@ -0,0 +1,3 @@
+add_test(NAME t COMMAND ${CMAKE_COMMAND} -E echo "Subdirectory")
+add_test(NAME t2 COMMAND ${CMAKE_COMMAND} -E echo "Subdirectory")
+add_test(NAME t3 COMMAND ${CMAKE_COMMAND} -E echo "Subdirectory")

+ 1 - 0
Tests/RunCMake/set_property/TEST-subdir2/CMakeLists.txt

@@ -0,0 +1 @@
+set_property(TEST t3 DIRECTORY ../TEST-subdir1 PROPERTY PASS_REGULAR_EXPRESSION "Subdirectory")

+ 9 - 0
Tests/RunCMake/set_property/TEST.cmake

@@ -0,0 +1,9 @@
+enable_testing()
+
+add_test(NAME t COMMAND ${CMAKE_COMMAND} -E echo "Top directory")
+add_subdirectory(TEST-subdir1)
+add_subdirectory(TEST-subdir2)
+
+set_property(TEST t PROPERTY PASS_REGULAR_EXPRESSION "Top directory")
+set_property(TEST t DIRECTORY TEST-subdir1 PROPERTY PASS_REGULAR_EXPRESSION "Subdirectory")
+set_property(TEST t2 DIRECTORY "${CMAKE_BINARY_DIR}/TEST-subdir1" PROPERTY PASS_REGULAR_EXPRESSION "Subdirectory")

+ 3 - 0
Tests/RunCMake/set_tests_properties/CMakeLists.txt

@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.27)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)

+ 1 - 0
Tests/RunCMake/set_tests_properties/DIRECTORY-invalid-result.txt

@@ -0,0 +1 @@
+1

+ 13 - 0
Tests/RunCMake/set_tests_properties/DIRECTORY-invalid-stderr.txt

@@ -0,0 +1,13 @@
+^CMake Error at DIRECTORY-invalid\.cmake:[0-9]+ \(set_tests_properties\):
+  Error after keyword "DIRECTORY":
+
+    missing required value
+
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Error at DIRECTORY-invalid\.cmake:[0-9]+ \(set_tests_properties\):
+  set_tests_properties given non-existent DIRECTORY nonexistent
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)$

+ 4 - 0
Tests/RunCMake/set_tests_properties/DIRECTORY-invalid.cmake

@@ -0,0 +1,4 @@
+enable_testing()
+
+set_tests_properties(t DIRECTORY PROPERTIES PASS_REGULAR_EXPRESSION "Top directory")
+set_tests_properties(t DIRECTORY nonexistent PROPERTIES PASS_REGULAR_EXPRESSION "Top directory")

+ 3 - 0
Tests/RunCMake/set_tests_properties/DIRECTORY-subdir1/CMakeLists.txt

@@ -0,0 +1,3 @@
+add_test(NAME t COMMAND ${CMAKE_COMMAND} -E echo "Subdirectory")
+add_test(NAME t2 COMMAND ${CMAKE_COMMAND} -E echo "Subdirectory")
+add_test(NAME t3 COMMAND ${CMAKE_COMMAND} -E echo "Subdirectory")

+ 1 - 0
Tests/RunCMake/set_tests_properties/DIRECTORY-subdir2/CMakeLists.txt

@@ -0,0 +1 @@
+set_tests_properties(t3 DIRECTORY ../DIRECTORY-subdir1 PROPERTIES PASS_REGULAR_EXPRESSION "Subdirectory")

+ 9 - 0
Tests/RunCMake/set_tests_properties/DIRECTORY.cmake

@@ -0,0 +1,9 @@
+enable_testing()
+
+add_test(NAME t COMMAND ${CMAKE_COMMAND} -E echo "Top directory")
+add_subdirectory(DIRECTORY-subdir1)
+add_subdirectory(DIRECTORY-subdir2)
+
+set_tests_properties(t PROPERTIES PASS_REGULAR_EXPRESSION "Top directory")
+set_tests_properties(t DIRECTORY DIRECTORY-subdir1 PROPERTIES PASS_REGULAR_EXPRESSION "Subdirectory")
+set_tests_properties(t2 DIRECTORY "${CMAKE_BINARY_DIR}/DIRECTORY-subdir1" PROPERTIES PASS_REGULAR_EXPRESSION "Subdirectory")

+ 8 - 0
Tests/RunCMake/set_tests_properties/RunCMakeTest.cmake

@@ -0,0 +1,8 @@
+include(RunCMake)
+
+run_cmake(DIRECTORY-invalid)
+
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/DIRECTORY-build)
+run_cmake(DIRECTORY)
+set(RunCMake_TEST_NO_CLEAN 1)
+run_cmake_command(DIRECTORY-test ${CMAKE_CTEST_COMMAND} -C Debug)