phpnamespacesphpspecpsr-4

How, if possible, to configure PHPSpec with no namespace and psr-4


I'm adding composer and PHPSpec to an established proprietary framework but I am unable to get PHPSpec to work with the global namespace when the classes to be tested reside in a non-standard directory which must be defined using psr-4. The file structure you need to be aware of in the project is as follows:

/root
    /spec
         /classnameSpec.php
    /classes
         /autoload
               /classname.php

The autoload directory is filled with the core classes for the app and they must stay here for now, they must not be in the default /src directory that PHPSpec uses.

I've got it working using a namespace with this (part) composer file

{
"require": {
    "phpspec/phpspec": "3.2.2"
  },
  "autoload": {
    "psr-4": {
      "Core\\": "classes/autoload"
    }
  }
}

and this phpspec.yml file:

suites:
  autoload_suite:
    namespace: 'Core'
    spec_prefix: ''
    spec_path: ./spec
    psr4_prefix: 'Core'
    src_path: classes/autoload

but that will necessitate adding namespaces to all the existing classes if I ever want to create tests to run against them.

The PHPSpec docs suggest it is possible to have a null namespace by leaving out the namespace property in the yml file, but any combination I try results in an error.

When I do

phpspec desc classname

it happily creates the test class in the spec folder, but when I run phpspec I get:

[InvalidArgumentException]                        
  PSR4 prefix doesn't match given class namespace.  

I've tried leaving both properties as null, '', \\, "\\", '\\', \ and removing them both but none of them work. Is there a specific combination of properties that I can use that will work or am I resigned to having to add namespaces to everything first?

(I should note that I have changed the psr-4 property in composer to "\": classes/autoload)


Solution

  • I got the answer I sought from Unfunco over on the PHPSpec Github issues page. Turns out you have to omit the properties from the yml file entirely, not merely set them to null strings.

    So the composer file looks like this:

      {
          "require": {
          "phpspec/phpspec": "3.2.2"
          },
          "autoload": {
              "psr-4": {
                  "": "classes/autoload"
          }
      }
    

    And the yml file, this:

    suites:
      autoload_suite:
        src_path: classes/autoload