diff --git a/src/xPDO/xPDO.php b/src/xPDO/xPDO.php
index 9567b3d..bbf14f4 100644
--- a/src/xPDO/xPDO.php
+++ b/src/xPDO/xPDO.php
@@ -369,6 +369,8 @@ protected function initConfig($data) {
$this->services = $data;
if ($this->services->has('config')) {
$data = $this->services->get('config');
+ } else {
+ throw new xPDOException('A ContainerInterface passed to xPDO must provide a \'config\' entry containing the xPDO configuration array.');
}
}
if (!is_array($data)) {
diff --git a/test/complete.phpunit.xml b/test/complete.phpunit.xml
index 2514653..157888c 100644
--- a/test/complete.phpunit.xml
+++ b/test/complete.phpunit.xml
@@ -34,6 +34,7 @@
./xPDO/Test/Transport/xPDOTransportTest.php
./xPDO/Test/Transport/xPDOVehicleTest.php
./xPDO/Test/PSR4/xPDOTest.php
+ ./xPDO/Test/xPDOPsr11InitTest.php
./xPDO/Test/TearDownTest.php
diff --git a/test/mysql.phpunit.xml b/test/mysql.phpunit.xml
index 2514653..157888c 100644
--- a/test/mysql.phpunit.xml
+++ b/test/mysql.phpunit.xml
@@ -34,6 +34,7 @@
./xPDO/Test/Transport/xPDOTransportTest.php
./xPDO/Test/Transport/xPDOVehicleTest.php
./xPDO/Test/PSR4/xPDOTest.php
+ ./xPDO/Test/xPDOPsr11InitTest.php
./xPDO/Test/TearDownTest.php
diff --git a/test/pgsql.phpunit.xml b/test/pgsql.phpunit.xml
index 2cd17e5..fbb12fa 100644
--- a/test/pgsql.phpunit.xml
+++ b/test/pgsql.phpunit.xml
@@ -34,6 +34,7 @@
./xPDO/Test/Transport/xPDOTransportTest.php
./xPDO/Test/Transport/xPDOVehicleTest.php
./xPDO/Test/PSR4/xPDOTest.php
+ ./xPDO/Test/xPDOPsr11InitTest.php
./xPDO/Test/TearDownTest.php
diff --git a/test/sqlite.phpunit.xml b/test/sqlite.phpunit.xml
index fa81718..7f89e66 100644
--- a/test/sqlite.phpunit.xml
+++ b/test/sqlite.phpunit.xml
@@ -34,6 +34,7 @@
./xPDO/Test/Transport/xPDOTransportTest.php
./xPDO/Test/Transport/xPDOVehicleTest.php
./xPDO/Test/PSR4/xPDOTest.php
+ ./xPDO/Test/xPDOPsr11InitTest.php
./xPDO/Test/TearDownTest.php
diff --git a/test/xPDO/Test/xPDOPsr11InitTest.php b/test/xPDO/Test/xPDOPsr11InitTest.php
new file mode 100644
index 0000000..8666667
--- /dev/null
+++ b/test/xPDO/Test/xPDOPsr11InitTest.php
@@ -0,0 +1,68 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace xPDO\Test;
+
+use PHPUnit\Framework\TestCase;
+use xPDO\xPDO;
+use xPDO\xPDOContainer;
+use xPDO\xPDOException;
+
+/**
+ * Tests for PSR-11 container initialization contract (issue #269).
+ *
+ * These tests verify that passing a ContainerInterface to xPDO makes the
+ * required 'config' entry contract explicit rather than silently falling back
+ * to default values when it is missing.
+ *
+ * @package xPDO\Test
+ */
+class xPDOPsr11InitTest extends TestCase
+{
+ /**
+ * Passing a container without a 'config' entry must throw xPDOException.
+ *
+ * Before the fix, xPDO would silently fall back to an empty config array
+ * when the container did not provide a 'config' entry, hiding the broken
+ * API contract from the caller.
+ */
+ public function testContainerWithoutConfigEntryThrowsException(): void
+ {
+ $container = new xPDOContainer();
+ // Deliberately do NOT add a 'config' entry
+
+ $this->expectException(xPDOException::class);
+ $this->expectExceptionMessage('config');
+
+ new xPDO(null, '', '', $container);
+ }
+
+ /**
+ * Passing a container WITH a valid 'config' entry must initialize normally.
+ *
+ * This is the positive-path contract test: a container that provides the
+ * required 'config' entry must result in a fully initialised xPDO instance
+ * without throwing.
+ */
+ public function testContainerWithConfigEntryInitializesSuccessfully(): void
+ {
+ $properties = include __DIR__ . '/../../properties.inc.php';
+ $driver = getenv('TEST_DRIVER') ?: 'sqlite';
+ $config = $properties["{$driver}_array_options"];
+
+ $container = new xPDOContainer();
+ $container->add('config', $config);
+
+ $xpdo = new xPDO(null, '', '', $container);
+
+ $this->assertInstanceOf(xPDO::class, $xpdo);
+ $this->assertSame($container, $xpdo->services);
+ }
+}