<commit_before><?php
/* This class is part of the XP framework
 *
 * $Id$ 
 */

  uses('unittest.TestCase', 'lang.FileSystemClassLoader', 'io.File', 'io.FileUtil', 'io.Folder', 'lang.System');

  /**
   * TestCase for classloading
   */
  class FileSystemClassLoaderTest extends TestCase {
    protected static $temp;
    protected $fixture;

    /**
     * Creates a new file (in the temporary directory)
     *
     * @param  string $name
     * @param  string $contents
     */
    protected static function newFile($name, $contents) {
      FileUtil::setContents(new File(self::$temp, $name), $contents);
    }

    /**
     * Defines a type
     *
     * @param  string $type class type, either "interface" or "class"
     * @param  string $name fully qualified class name
     */
    protected static function newType($type, $name) {
      if (FALSE === ($p= strrpos($name, '.'))) {
        $class= $name;
        $path= $name;
        $ns= '';
      } else {
        $class= substr($name, $p);
        $path= strtr($name, '.', DIRECTORY_SEPARATOR);
        $ns= 'namespace '.strtr(substr($name, 0, $p), '.', '\\').';';
      }

      self::newFile($path.xp::CLASS_FILE_EXT, sprintf(
        '<?php %s %s %s extends \lang\Object { }',
        $ns,
        $type,
        $name
      ));
    }

    /**
     * Defines fixture classes in a temp dir
     */
    #[@beforeClass]
    public static function defineClasses() {
      self::$temp= new Folder(System::tempDir(), 'fsclt');
      self::$temp->create();

      self::newType('class', 'FSCLT1');
      self::newFile('FSCLT1.txt', 'This is not a class');
    }

    /**
     * Creates fixture.
     */
    public function setUp() {
      $this->fixture= new FileSystemClassLoader(self::$temp->getURI());
    }

    /**
     * Removes temp dir created in `defineClasses()`.
     */
    #[@afterClass]
    public static function removeTempDir() {
      self::$temp->unlink();
    }

    #[@test]
    public function from_a_relative_path() {
      $this->assertEquals(
        $this->fixture->loadClass('FSCLT1'),
        $this->fixture->classFromUri('FSCLT1.class.php')
      );
    }

    #[@test]
    public function from_an_absolute_path() {
      $this->assertEquals(
        $this->fixture->loadClass('FSCLT1'),
        $this->fixture->classFromUri(self::$temp->getURI().'FSCLT1.class.php')
      );
    }

    #[@test]<commit_msg>- Verify classes in subpaths work<commit_after><?php
/* This class is part of the XP framework
 *
 * $Id$ 
 */

  uses('unittest.TestCase', 'lang.FileSystemClassLoader', 'io.File', 'io.FileUtil', 'io.Folder', 'lang.System');

  /**
   * TestCase for classloading
   */
  class FileSystemClassLoaderTest extends TestCase {
    protected static $temp;
    protected $fixture;

    /**
     * Creates a new file (in the temporary directory)
     *
     * @param  string $name
     * @param  string $contents
     */
    protected static function newFile($name, $contents) {
      $file= new File(self::$temp, $name);
      $path= new Folder($file->getPath());
      $path->exists() || $path->create();

      FileUtil::setContents($file, $contents);
    }

    /**
     * Defines a type
     *
     * @param  string $type class type, either "interface" or "class"
     * @param  string $name fully qualified class name
     */
    protected static function newType($type, $name) {
      if (FALSE === ($p= strrpos($name, '.'))) {
        $class= $name;
        $path= $name;
        $ns= '';
      } else {
        $class= substr($name, $p + 1);
        $path= strtr($name, '.', DIRECTORY_SEPARATOR);
        $ns= 'namespace '.strtr(substr($name, 0, $p), '.', '\\').';';
      }

      self::newFile($path.xp::CLASS_FILE_EXT, sprintf(
        '<?php %s %s %s extends \lang\Object { }',
        $ns,
        $type,
        $class
      ));
    }

    /**
     * Defines fixture classes in a temp dir
     */
    #[@beforeClass]
    public static function defineClasses() {
      self::$temp= new Folder(System::tempDir(), 'fsclt');
      self::$temp->create();

      self::newType('class', 'FSCLT1');
      self::newType('class', 'net.xp_framework.unittest.reflection.FSCLT2');
      self::newFile('FSCLT1.txt', 'This is not a class');
    }

    /**
     * Creates fixture.
     */
    public function setUp() {
      $this->fixture= new FileSystemClassLoader(self::$temp->getURI());
    }

    /**
     * Removes temp dir created in `defineClasses()`.
     */
    #[@afterClass]
    public static function removeTempDir() {
      self::$temp->unlink();
    }

    /**
     * Compose a path from a list of elements
     *
     * @param  string... args
     * @return string
     */
    protected function compose() {
      return implode(DIRECTORY_SEPARATOR, array_map(
        function($e) { return rtrim($e, DIRECTORY_SEPARATOR); },
        func_get_args()
      ));
    }

    #[@test]
    public function from_a_relative_path_in_root() {
      $this->assertEquals(
        $this->fixture->loadClass('FSCLT1'),
        $this->fixture->classFromUri('FSCLT1.class.php')
      );
    }

    #[@test]
    public function from_a_relative_path() {
      $this->assertEquals(
        $this->fixture->loadClass('net.xp_framework.unittest.reflection.FSCLT2'),
        $this->fixture->classFromUri($this->compose('net', 'xp_framework', 'unittest', 'reflection', 'FSCLT2.class.php'))
      );
    }

    #[@test]
    public function from_an_absolute_path_in_root() {
      $this->assertEquals(
        $this->fixture->loadClass('FSCLT1'),
        $this->fixture->classFromUri($this->compose(self::$temp->getURI(), 'FSCLT1.class.php'))
      );
    }

    #[@test]
    public function from_an_absolute_path() {
      $this->assertEquals(
        $this->fixture->loadClass('net.xp_framework.unittest.reflection.FSCLT2'),
        $this->fixture->classFromUri($this->compose(self::$temp->getURI(), 'net', 'xp_framework', 'unittest', 'reflection', 'FSCLT2.class.php'))
      );
    }

    #[@test]
{'fraction_non_alphanumeric': 0.17157683294275192, 'fraction_numerical': 0.0033478406427854034, 'mean_word_length': 2.5209192692987625, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 50, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '22110', 'n_tokens_mistral': 1942, 'n_tokens_neox': 1919, 'n_words': 396}