{"action":"created","comment":{"url":"https://api.github.com/repos/Codeception/Codeception/pulls/comments/176994081","pull_request_review_id":106788453,"id":176994081,"diff_hunk":"@@ -235,20 +275,79 @@ public function _after(TestInterface $test)\n             $this->loadedFixtures = [];\n         }\n \n-        if ($this->client) {\n-            $this->client->resetPersistentVars();\n+        if ($this->client->getApplication()->has('session', true)) {\n+            $this->client->getApplication()->session->close();\n         }\n \n-        if (isset(\\Yii::$app) && \\Yii::$app->has('session', true)) {\n-            \\Yii::$app->session->close();\n-        }\n+        parent::_after($test);\n+    }\n \n-        // Close connections if exists\n-        if (isset(\\Yii::$app) && \\Yii::$app->has('db', true)) {\n-            \\Yii::$app->db->close();\n+    protected function startTransactions()\n+    {\n+        if ($this->config['transaction']) {\n+            // This should register handlers that start a transaction whenever a connection opens and add it to the transactions array.\n+            Event::on(Connection::class, Connection::EVENT_AFTER_OPEN, function (Event $event) {\n+                if ($event->sender instanceof Connection) {\n+                    $connection = $event->sender;\n+                    /*\n+                     * We should check if the known PDO objects are the same, in which case we should reuse the PDO\n+                     * object so only 1 transaction is started and multiple connections to the same database see the\n+                     * same data (due to writes inside a transaction not being visible from the outside).\n+                     *\n+                     */\n+                    $key = md5(json_encode([\n+                        'dsn' => $connection->dsn,\n+                        'user' => $connection->username,\n+                        'pass' => $connection->password,\n+                        'attributes' => $connection->attributes,\n+                        'emulatePrepare' => $connection->emulatePrepare,\n+                        'charset' => $connection->charset\n+                    ]));\n+\n+                    /*\n+                     * If keys match we assume connections are \"similar enough\".\n+                     */\n+                    if (isset($this->pdoCache[$key])) {\n+                        $connection->pdo = $this->pdoCache[$key];\n+                    }\n+\n+                    if (isset($this->dsnCache[$connection->dsn])\n+                        && $this->dsnCache[$connection->dsn] !== $key\n+                        && !$this->config['ignoreCollidingDSN']\n+                    ) {\n+\n+                        $this->debugSection('WARNING', <<<TEXT\n+You use multiple connections to the same DSN ({$connection->dsn}) with different configuration.\n+These connections will not see the same database state since we cannot share a transaction between different PDO\n+instances.\n+You can remove this message by adding 'ignoreCollidingDSN = true' in the module configuration.\n+TEXT\n+                        );\n+                        Debug::pause();\n+                    }\n+\n+                    if (isset($this->transactions[$key])) {\n+                        $this->debugSection('Database', 'Reusing PDO, so no need for a new transaction');\n+                        return;\n+                    }\n+\n+                    $this->debugSection('Database', 'Transaction started');\n+                    $this->transactions[$key] = $event->sender->beginTransaction();\n+                }\n+            });\n         }\n+    }\n \n-        parent::_after($test);\n+    protected function rollbackTransactions()\n+    {\n+        /** @var Transaction $transaction */\n+        foreach($this->transactions as $transaction) {","path":"src/Codeception/Module/Yii2.php","position":259,"original_position":259,"commit_id":"3589d7711960233b05c5c61b0028c308ae7ce57a","original_commit_id":"3589d7711960233b05c5c61b0028c308ae7ce57a","user":{"login":"Nitpick-CI","id":12626182,"avatar_url":"https://avatars1.githubusercontent.com/u/12626182?v=4","gravatar_id":"","url":"https://api.github.com/users/Nitpick-CI","html_url":"https://github.com/Nitpick-CI","followers_url":"https://api.github.com/users/Nitpick-CI/followers","following_url":"https://api.github.com/users/Nitpick-CI/following{/other_user}","gists_url":"https://api.github.com/users/Nitpick-CI/gists{/gist_id}","starred_url":"https://api.github.com/users/Nitpick-CI/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Nitpick-CI/subscriptions","organizations_url":"https://api.github.com/users/Nitpick-CI/orgs","repos_url":"https://api.github.com/users/Nitpick-CI/repos","events_url":"https://api.github.com/users/Nitpick-CI/events{/privacy}","received_events_url":"https://api.github.com/users/Nitpick-CI/received_events","type":"User","site_admin":false},"body":"Expected 1 space after FOREACH keyword; 0 found","created_at":"2018-03-26T06:57:24Z","updated_at":"2018-03-26T06:57:24Z","html_url":"https://github.com/Codeception/Codeception/pull/4891#discussion_r176994081","pull_request_url":"https://api.github.com/repos/Codeception/Codeception/pulls/4891","author_association":"NONE","_links":{"self":{"href":"https://api.github.com/repos/Codeception/Codeception/pulls/comments/176994081"},"html":{"href":"https://github.com/Codeception/Codeception/pull/4891#discussion_r176994081"},"pull_request":{"href":"https://api.github.com/repos/Codeception/Codeception/pulls/4891"}}},"pull_request":{"url":"https://api.github.com/repos/Codeception/Codeception/pulls/4891","id":177357120,"html_url":"https://github.com/Codeception/Codeception/pull/4891","diff_url":"https://github.com/Codeception/Codeception/pull/4891.diff","patch_url":"https://github.com/Codeception/Codeception/pull/4891.patch","issue_url":"https://api.github.com/repos/Codeception/Codeception/issues/4891","number":4891,"state":"open","locked":false,"title":"[WIP] Clean up in Yii2 module","user":{"login":"SamMousa","id":547021,"avatar_url":"https://avatars1.githubusercontent.com/u/547021?v=4","gravatar_id":"","url":"https://api.github.com/users/SamMousa","html_url":"https://github.com/SamMousa","followers_url":"https://api.github.com/users/SamMousa/followers","following_url":"https://api.github.com/users/SamMousa/following{/other_user}","gists_url":"https://api.github.com/users/SamMousa/gists{/gist_id}","starred_url":"https://api.github.com/users/SamMousa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SamMousa/subscriptions","organizations_url":"https://api.github.com/users/SamMousa/orgs","repos_url":"https://api.github.com/users/SamMousa/repos","events_url":"https://api.github.com/users/SamMousa/events{/privacy}","received_events_url":"https://api.github.com/users/SamMousa/received_events","type":"User","site_admin":false},"body":"- No more static variables\r\n- No more database connection caching (that didn't actually work)\r\n- Support for multiple database connections / database services with names other than 'db'\r\n\r\nThis needs more testing; I've tested it in a few of my production apps.\r\n\r\nAlso somewhere in the docs we should update the \"contract\" about application state:\r\n\r\n1. When a test starts you get a fresh application.\r\n2. Just before a request is executed the `Request` and `Response` component are reloaded.\r\n3. Application state is persisted after the request and reused for the next request (as long as it is not in the `Request` or `Response` component.\r\n4. All PDO based connections are supported as long as they are subclasses of `yii\\db\\Connection` and fire the `AFTER_OPEN` event.\r\n\r\n\r\nDatabase handling (for transactions)\r\n\r\n1. All cached are cleared at the end of a test.\r\n2. At the start of a test we register an event handler for `AFTER_OPEN`.\r\n3. When the event is fired we generate a cache key based on connection settings.\r\n4. We store the PDO object in the cache.\r\n5. We store an entry in the dsn cache, this is used to identify unsupported cases (think connecting to the same database with different credentials, in which case the transaction creates 2 world views which could cause issues).\r\n6. If we detect a duplicate PDO object we replace the new PDO with the existing one, this causes the new connection to be closed immediately and guarantees us that the new `Connection` object uses the same PDO object and thus has the same world view.\r\n","created_at":"2018-03-26T06:57:13Z","updated_at":"2018-03-26T06:57:24Z","closed_at":null,"merged_at":null,"merge_commit_sha":"a3bdb44e692f34f826d0558a7758b4c5188d5b47","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/Codeception/Codeception/pulls/4891/commits","review_comments_url":"https://api.github.com/repos/Codeception/Codeception/pulls/4891/comments","review_comment_url":"https://api.github.com/repos/Codeception/Codeception/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Codeception/Codeception/issues/4891/comments","statuses_url":"https://api.github.com/repos/Codeception/Codeception/statuses/3589d7711960233b05c5c61b0028c308ae7ce57a","head":{"label":"SamMousa:yii2-rework","ref":"yii2-rework","sha":"3589d7711960233b05c5c61b0028c308ae7ce57a","user":{"login":"SamMousa","id":547021,"avatar_url":"https://avatars1.githubusercontent.com/u/547021?v=4","gravatar_id":"","url":"https://api.github.com/users/SamMousa","html_url":"https://github.com/SamMousa","followers_url":"https://api.github.com/users/SamMousa/followers","following_url":"https://api.github.com/users/SamMousa/following{/other_user}","gists_url":"https://api.github.com/users/SamMousa/gists{/gist_id}","starred_url":"https://api.github.com/users/SamMousa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SamMousa/subscriptions","organizations_url":"https://api.github.com/users/SamMousa/orgs","repos_url":"https://api.github.com/users/SamMousa/repos","events_url":"https://api.github.com/users/SamMousa/events{/privacy}","received_events_url":"https://api.github.com/users/SamMousa/received_events","type":"User","site_admin":false},"repo":{"id":102354379,"name":"Codeception","full_name":"SamMousa/Codeception","owner":{"login":"SamMousa","id":547021,"avatar_url":"https://avatars1.githubusercontent.com/u/547021?v=4","gravatar_id":"","url":"https://api.github.com/users/SamMousa","html_url":"https://github.com/SamMousa","followers_url":"https://api.github.com/users/SamMousa/followers","following_url":"https://api.github.com/users/SamMousa/following{/other_user}","gists_url":"https://api.github.com/users/SamMousa/gists{/gist_id}","starred_url":"https://api.github.com/users/SamMousa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SamMousa/subscriptions","organizations_url":"https://api.github.com/users/SamMousa/orgs","repos_url":"https://api.github.com/users/SamMousa/repos","events_url":"https://api.github.com/users/SamMousa/events{/privacy}","received_events_url":"https://api.github.com/users/SamMousa/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/SamMousa/Codeception","description":"Full-stack testing PHP framework","fork":true,"url":"https://api.github.com/repos/SamMousa/Codeception","forks_url":"https://api.github.com/repos/SamMousa/Codeception/forks","keys_url":"https://api.github.com/repos/SamMousa/Codeception/keys{/key_id}","collaborators_url":"https://api.github.com/repos/SamMousa/Codeception/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/SamMousa/Codeception/teams","hooks_url":"https://api.github.com/repos/SamMousa/Codeception/hooks","issue_events_url":"https://api.github.com/repos/SamMousa/Codeception/issues/events{/number}","events_url":"https://api.github.com/repos/SamMousa/Codeception/events","assignees_url":"https://api.github.com/repos/SamMousa/Codeception/assignees{/user}","branches_url":"https://api.github.com/repos/SamMousa/Codeception/branches{/branch}","tags_url":"https://api.github.com/repos/SamMousa/Codeception/tags","blobs_url":"https://api.github.com/repos/SamMousa/Codeception/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/SamMousa/Codeception/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/SamMousa/Codeception/git/refs{/sha}","trees_url":"https://api.github.com/repos/SamMousa/Codeception/git/trees{/sha}","statuses_url":"https://api.github.com/repos/SamMousa/Codeception/statuses/{sha}","languages_url":"https://api.github.com/repos/SamMousa/Codeception/languages","stargazers_url":"https://api.github.com/repos/SamMousa/Codeception/stargazers","contributors_url":"https://api.github.com/repos/SamMousa/Codeception/contributors","subscribers_url":"https://api.github.com/repos/SamMousa/Codeception/subscribers","subscription_url":"https://api.github.com/repos/SamMousa/Codeception/subscription","commits_url":"https://api.github.com/repos/SamMousa/Codeception/commits{/sha}","git_commits_url":"https://api.github.com/repos/SamMousa/Codeception/git/commits{/sha}","comments_url":"https://api.github.com/repos/SamMousa/Codeception/comments{/number}","issue_comment_url":"https://api.github.com/repos/SamMousa/Codeception/issues/comments{/number}","contents_url":"https://api.github.com/repos/SamMousa/Codeception/contents/{+path}","compare_url":"https://api.github.com/repos/SamMousa/Codeception/compare/{base}...{head}","merges_url":"https://api.github.com/repos/SamMousa/Codeception/merges","archive_url":"https://api.github.com/repos/SamMousa/Codeception/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/SamMousa/Codeception/downloads","issues_url":"https://api.github.com/repos/SamMousa/Codeception/issues{/number}","pulls_url":"https://api.github.com/repos/SamMousa/Codeception/pulls{/number}","milestones_url":"https://api.github.com/repos/SamMousa/Codeception/milestones{/number}","notifications_url":"https://api.github.com/repos/SamMousa/Codeception/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/SamMousa/Codeception/labels{/name}","releases_url":"https://api.github.com/repos/SamMousa/Codeception/releases{/id}","deployments_url":"https://api.github.com/repos/SamMousa/Codeception/deployments","created_at":"2017-09-04T11:30:29Z","updated_at":"2017-09-04T11:30:33Z","pushed_at":"2018-03-26T06:47:52Z","git_url":"git://github.com/SamMousa/Codeception.git","ssh_url":"git@github.com:SamMousa/Codeception.git","clone_url":"https://github.com/SamMousa/Codeception.git","svn_url":"https://github.com/SamMousa/Codeception","homepage":"http://codeception.com","size":70109,"stargazers_count":0,"watchers_count":0,"language":"PHP","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":null,"forks":0,"open_issues":0,"watchers":0,"default_branch":"2.3"}},"base":{"label":"Codeception:2.4","ref":"2.4","sha":"69150097f19bb408b79cda0c1364e1a18316276b","user":{"login":"Codeception","id":1288753,"avatar_url":"https://avatars2.githubusercontent.com/u/1288753?v=4","gravatar_id":"","url":"https://api.github.com/users/Codeception","html_url":"https://github.com/Codeception","followers_url":"https://api.github.com/users/Codeception/followers","following_url":"https://api.github.com/users/Codeception/following{/other_user}","gists_url":"https://api.github.com/users/Codeception/gists{/gist_id}","starred_url":"https://api.github.com/users/Codeception/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Codeception/subscriptions","organizations_url":"https://api.github.com/users/Codeception/orgs","repos_url":"https://api.github.com/users/Codeception/repos","events_url":"https://api.github.com/users/Codeception/events{/privacy}","received_events_url":"https://api.github.com/users/Codeception/received_events","type":"Organization","site_admin":false},"repo":{"id":2880469,"name":"Codeception","full_name":"Codeception/Codeception","owner":{"login":"Codeception","id":1288753,"avatar_url":"https://avatars2.githubusercontent.com/u/1288753?v=4","gravatar_id":"","url":"https://api.github.com/users/Codeception","html_url":"https://github.com/Codeception","followers_url":"https://api.github.com/users/Codeception/followers","following_url":"https://api.github.com/users/Codeception/following{/other_user}","gists_url":"https://api.github.com/users/Codeception/gists{/gist_id}","starred_url":"https://api.github.com/users/Codeception/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Codeception/subscriptions","organizations_url":"https://api.github.com/users/Codeception/orgs","repos_url":"https://api.github.com/users/Codeception/repos","events_url":"https://api.github.com/users/Codeception/events{/privacy}","received_events_url":"https://api.github.com/users/Codeception/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Codeception/Codeception","description":"Full-stack testing PHP framework","fork":false,"url":"https://api.github.com/repos/Codeception/Codeception","forks_url":"https://api.github.com/repos/Codeception/Codeception/forks","keys_url":"https://api.github.com/repos/Codeception/Codeception/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Codeception/Codeception/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Codeception/Codeception/teams","hooks_url":"https://api.github.com/repos/Codeception/Codeception/hooks","issue_events_url":"https://api.github.com/repos/Codeception/Codeception/issues/events{/number}","events_url":"https://api.github.com/repos/Codeception/Codeception/events","assignees_url":"https://api.github.com/repos/Codeception/Codeception/assignees{/user}","branches_url":"https://api.github.com/repos/Codeception/Codeception/branches{/branch}","tags_url":"https://api.github.com/repos/Codeception/Codeception/tags","blobs_url":"https://api.github.com/repos/Codeception/Codeception/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Codeception/Codeception/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Codeception/Codeception/git/refs{/sha}","trees_url":"https://api.github.com/repos/Codeception/Codeception/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Codeception/Codeception/statuses/{sha}","languages_url":"https://api.github.com/repos/Codeception/Codeception/languages","stargazers_url":"https://api.github.com/repos/Codeception/Codeception/stargazers","contributors_url":"https://api.github.com/repos/Codeception/Codeception/contributors","subscribers_url":"https://api.github.com/repos/Codeception/Codeception/subscribers","subscription_url":"https://api.github.com/repos/Codeception/Codeception/subscription","commits_url":"https://api.github.com/repos/Codeception/Codeception/commits{/sha}","git_commits_url":"https://api.github.com/repos/Codeception/Codeception/git/commits{/sha}","comments_url":"https://api.github.com/repos/Codeception/Codeception/comments{/number}","issue_comment_url":"https://api.github.com/repos/Codeception/Codeception/issues/comments{/number}","contents_url":"https://api.github.com/repos/Codeception/Codeception/contents/{+path}","compare_url":"https://api.github.com/repos/Codeception/Codeception/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Codeception/Codeception/merges","archive_url":"https://api.github.com/repos/Codeception/Codeception/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Codeception/Codeception/downloads","issues_url":"https://api.github.com/repos/Codeception/Codeception/issues{/number}","pulls_url":"https://api.github.com/repos/Codeception/Codeception/pulls{/number}","milestones_url":"https://api.github.com/repos/Codeception/Codeception/milestones{/number}","notifications_url":"https://api.github.com/repos/Codeception/Codeception/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Codeception/Codeception/labels{/name}","releases_url":"https://api.github.com/repos/Codeception/Codeception/releases{/id}","deployments_url":"https://api.github.com/repos/Codeception/Codeception/deployments","created_at":"2011-11-30T04:06:44Z","updated_at":"2018-03-23T07:57:45Z","pushed_at":"2018-03-26T06:57:14Z","git_url":"git://github.com/Codeception/Codeception.git","ssh_url":"git@github.com:Codeception/Codeception.git","clone_url":"https://github.com/Codeception/Codeception.git","svn_url":"https://github.com/Codeception/Codeception","homepage":"http://codeception.com","size":70407,"stargazers_count":3250,"watchers_count":3250,"language":"PHP","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1138,"mirror_url":null,"archived":false,"open_issues_count":372,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":1138,"open_issues":372,"watchers":3250,"default_branch":"2.4"}},"_links":{"self":{"href":"https://api.github.com/repos/Codeception/Codeception/pulls/4891"},"html":{"href":"https://github.com/Codeception/Codeception/pull/4891"},"issue":{"href":"https://api.github.com/repos/Codeception/Codeception/issues/4891"},"comments":{"href":"https://api.github.com/repos/Codeception/Codeception/issues/4891/comments"},"review_comments":{"href":"https://api.github.com/repos/Codeception/Codeception/pulls/4891/comments"},"review_comment":{"href":"https://api.github.com/repos/Codeception/Codeception/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Codeception/Codeception/pulls/4891/commits"},"statuses":{"href":"https://api.github.com/repos/Codeception/Codeception/statuses/3589d7711960233b05c5c61b0028c308ae7ce57a"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"Nitpick-CI"}}