{"action":"created","comment":{"url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/pulls/comments/31896106","id":31896106,"diff_hunk":"@@ -105,37 +112,89 @@ class J2objcTestTask extends DefaultTask {\n         def binary = testBinaryFile.path\n         logger.debug \"Test Binary: $binary\"\n \n-        def outputStream = new ByteArrayOutputStream()\n-        project.exec {\n-            executable binary\n-            args \"org.junit.runner.JUnitCore\"\n+        def output = new ByteArrayOutputStream()\n+        try {\n+            project.exec {\n+                executable binary\n+                args \"org.junit.runner.JUnitCore\"\n \n-            args getTestFlags().split()\n+                args getTestFlags().split()\n \n-            testNames.each { testName ->\n-                args testName\n-            }\n+                testNames.each { testName ->\n+                    args testName\n+                }\n \n-            errorOutput outputStream\n-            standardOutput outputStream\n+                errorOutput output\n+                standardOutput output\n+            }\n+        } catch (Exception exception) {\n+            logger.error \"STDOUT and STDERR from failed j2objcTest task:\"\n+            logger.error output.toString()\n+            def message =\n+                    \"The j2objcTest task failed. Given that the java plugin 'test' task\\n\" +\n+                    \"completed successfully, this shows an error specific to the j2objc build.\\n\" +\n+                    \"It may be that the code will still perform correctly. If you can identify\\n\" +\n+                    \"the failing test, then it can be excluded in j2objcConfig:\\n\" +\n+                    \"\\n\" +\n+                    \"j2objcConfig {\\n\" +\n+                    \"    testPattern {\\n\" +\n+                    \"        exclude '**/FailingTest.java'\\n\" +\n+                    \"        exclude 'src/main/java/Package/FailingDirectory/**'\\n\" +\n+                    \"    }\\n\" +\n+                    \"}\\n\" +\n+                    \"\\n\" +\n+                    \"To identify the failing test, run with the --debug flag and look for:\\n\" +\n+                    \"    testJ2objc org.junit.runner.JUnitCore\\n\" +\n+                    \"Copy the command from \\\"Command:\\\" onwards, then try varying the command\\n\" +\n+                    \"to drop tests and figure out which ones are causing the failures.\\n\"\n+                    \"Then disable them as described above.\\n\"\n+            if (exception.getMessage().find(\"finished with non-zero exit value 139\")) {\n+                message +=\n+                        \"\\n\" +\n+                        \"\\\"non-zero exit value 139\\\" indicates a process crash, most likely\\n\" +\n+                        \"caused by a segmentation fault (SIGSEGV) in user space.\\n\" +\n+                        \"\\n\" +\n+                        \"Mockito.spy() is known to cause this issue, disable tests that use it:\\n\" +\n+                        \"    https://github.com/google/j2objc/issues/411\\n\"\n+            }\n+            logger.error message\n+            throw exception\n         }\n \n-        def output = outputStream.toString()\n-        reportFile.write(output)\n+        // Test Output Report\n+        def outputStr = output.toString()\n+        reportFile.write(outputStr)\n         logger.debug \"Test Output: ${reportFile.path}\"\n \n-        // 0 tests => warn by default\n-        if (getTestExecutedCheck()) {\n-            if (output.contains(\"OK (0 tests)\")) {\n-                def message =\n-                        \"Zero unit tests were run. Tests are strongly encouraged with J2objc:\\n\" +\n-                        \"\\n\" +\n-                        \"To disable this check (which is against best practice):\\n\" +\n-                        \"j2objcConfig {\\n\" +\n-                        \"    testExecutedCheck false\\n\" +\n-                        \"}\\n\"\n-                throw new InvalidUserDataException(message)\n-            }\n+        int testCount = J2objcUtils.matchNumberRegex(outputStr, /OK \\((\\d+) tests\\)/)\n+        if (getTestMinExpectedUnitTestsDisable()) {\n+            logger.info \"testExpectedCount is disabled\"\n+        } else if (testCount < getTestMinExpectedUnitTests()) {\n+            def message =\n+                    \"Number of unit tests run is less than expected\\n\" +\n+                    \"Actual Tests Run:    ${testCount}\\n\" +\n+                    \"Expected Tests Run:  ${getTestMinExpectedUnitTests()}\\n\" +\n+                    \"\\n\" +\n+                    \"If there are legitimately fewer tests then adjust as follow:\\n\" +\n+                    \"\\n\" +\n+                    \"j2objcConfig {\\n\" +\n+                    \"    testMinExpectedUnitTests ${testCount}\\n\" +\n+                    \"}\\n\"\n+                    \"\\n\" +\n+                    \"The check can also be disabled (not best practice):\\n\" +\n+                    \"\\n\" +\n+                    \"j2objcConfig {\\n\" +\n+                    \"    testMinExpectedUnitTestsDisable true}\\n\" +\n+                    \"}\\n\"\n+            throw new Exception(message)\n+        } else if (testCount != getTestMinExpectedUnitTests()) {\n+            def message =\n+                    \"testMinExpectedUnitTests can be increased:\\n\" +","path":"src/main/groovy/com/github/j2objccontrib/j2objcgradle/tasks/J2objcTestTask.groovy","position":128,"original_position":128,"commit_id":"e09d254df7764a15bcd3ca96028d59e115835740","original_commit_id":"e09d254df7764a15bcd3ca96028d59e115835740","user":{"login":"advayDev1","id":11729521,"avatar_url":"https://avatars.githubusercontent.com/u/11729521?v=3","gravatar_id":"","url":"https://api.github.com/users/advayDev1","html_url":"https://github.com/advayDev1","followers_url":"https://api.github.com/users/advayDev1/followers","following_url":"https://api.github.com/users/advayDev1/following{/other_user}","gists_url":"https://api.github.com/users/advayDev1/gists{/gist_id}","starred_url":"https://api.github.com/users/advayDev1/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/advayDev1/subscriptions","organizations_url":"https://api.github.com/users/advayDev1/orgs","repos_url":"https://api.github.com/users/advayDev1/repos","events_url":"https://api.github.com/users/advayDev1/events{/privacy}","received_events_url":"https://api.github.com/users/advayDev1/received_events","type":"User","site_admin":false},"body":"i don't think this is a best practice and therefore we shouldn't suggest it to users.  users should add tests whenever they add new code, but shouldn't have to (or think they should) keep changing a config to keep up.","created_at":"2015-06-08T08:53:33Z","updated_at":"2015-06-08T08:53:33Z","html_url":"https://github.com/j2objc-contrib/j2objc-gradle/pull/119#discussion_r31896106","pull_request_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/pulls/119","_links":{"self":{"href":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/pulls/comments/31896106"},"html":{"href":"https://github.com/j2objc-contrib/j2objc-gradle/pull/119#discussion_r31896106"},"pull_request":{"href":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/pulls/119"}}},"pull_request":{"url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/pulls/119","id":37130698,"html_url":"https://github.com/j2objc-contrib/j2objc-gradle/pull/119","diff_url":"https://github.com/j2objc-contrib/j2objc-gradle/pull/119.diff","patch_url":"https://github.com/j2objc-contrib/j2objc-gradle/pull/119.patch","issue_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/issues/119","number":119,"state":"open","locked":false,"title":"Working build: 0.2.0 version bump + add missing javax_inject library","user":{"login":"brunobowden","id":679339,"avatar_url":"https://avatars.githubusercontent.com/u/679339?v=3","gravatar_id":"","url":"https://api.github.com/users/brunobowden","html_url":"https://github.com/brunobowden","followers_url":"https://api.github.com/users/brunobowden/followers","following_url":"https://api.github.com/users/brunobowden/following{/other_user}","gists_url":"https://api.github.com/users/brunobowden/gists{/gist_id}","starred_url":"https://api.github.com/users/brunobowden/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/brunobowden/subscriptions","organizations_url":"https://api.github.com/users/brunobowden/orgs","repos_url":"https://api.github.com/users/brunobowden/repos","events_url":"https://api.github.com/users/brunobowden/events{/privacy}","received_events_url":"https://api.github.com/users/brunobowden/received_events","type":"User","site_admin":false},"body":"These changes allow a working build for my local project. The Xcode\r\ncompile and debugging haven’t been tested yet but it looks promising.\r\n\r\n- Bump version to 0.2.0-alpha\r\n- Fix missing javax_inject library for native compile + clear\r\norganization\r\n- added j2objcConfig for testMinExpectedUnitTests support and\r\ntestMinExpectedUnitTestsDisable\r\n- try catch block for ‘j2objcTest’, warns on known Mockito.spy() crash\r\n- J2objcUtils.matchNumberRegex(…) to extract int from proces.exec(…)\r\n\r\nMinor:\r\n- Removed indentation for “j2objConfig {“ to facilitate copy and paste\r\n- Consolidate naming for srcGenDir throughout tasks\r\n- Better command example for creating Podfile\r\n\r\nTESTED=yes","created_at":"2015-06-08T08:23:55Z","updated_at":"2015-06-08T08:53:33Z","closed_at":null,"merged_at":null,"merge_commit_sha":"2b82e6a5756be020577267c4348cb0f802443c7f","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/pulls/119/commits","review_comments_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/pulls/119/comments","review_comment_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/pulls/comments{/number}","comments_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/issues/119/comments","statuses_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/statuses/e09d254df7764a15bcd3ca96028d59e115835740","head":{"label":"brunobowden:fixup","ref":"fixup","sha":"e09d254df7764a15bcd3ca96028d59e115835740","user":{"login":"brunobowden","id":679339,"avatar_url":"https://avatars.githubusercontent.com/u/679339?v=3","gravatar_id":"","url":"https://api.github.com/users/brunobowden","html_url":"https://github.com/brunobowden","followers_url":"https://api.github.com/users/brunobowden/followers","following_url":"https://api.github.com/users/brunobowden/following{/other_user}","gists_url":"https://api.github.com/users/brunobowden/gists{/gist_id}","starred_url":"https://api.github.com/users/brunobowden/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/brunobowden/subscriptions","organizations_url":"https://api.github.com/users/brunobowden/orgs","repos_url":"https://api.github.com/users/brunobowden/repos","events_url":"https://api.github.com/users/brunobowden/events{/privacy}","received_events_url":"https://api.github.com/users/brunobowden/received_events","type":"User","site_admin":false},"repo":{"id":37033994,"name":"j2objc-gradle","full_name":"brunobowden/j2objc-gradle","owner":{"login":"brunobowden","id":679339,"avatar_url":"https://avatars.githubusercontent.com/u/679339?v=3","gravatar_id":"","url":"https://api.github.com/users/brunobowden","html_url":"https://github.com/brunobowden","followers_url":"https://api.github.com/users/brunobowden/followers","following_url":"https://api.github.com/users/brunobowden/following{/other_user}","gists_url":"https://api.github.com/users/brunobowden/gists{/gist_id}","starred_url":"https://api.github.com/users/brunobowden/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/brunobowden/subscriptions","organizations_url":"https://api.github.com/users/brunobowden/orgs","repos_url":"https://api.github.com/users/brunobowden/repos","events_url":"https://api.github.com/users/brunobowden/events{/privacy}","received_events_url":"https://api.github.com/users/brunobowden/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/brunobowden/j2objc-gradle","description":"Gradle plugin for j2objc (Java to Objective-C transpiler)","fork":true,"url":"https://api.github.com/repos/brunobowden/j2objc-gradle","forks_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/forks","keys_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/keys{/key_id}","collaborators_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/teams","hooks_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/hooks","issue_events_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/issues/events{/number}","events_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/events","assignees_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/assignees{/user}","branches_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/branches{/branch}","tags_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/tags","blobs_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/git/refs{/sha}","trees_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/git/trees{/sha}","statuses_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/statuses/{sha}","languages_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/languages","stargazers_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/stargazers","contributors_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/contributors","subscribers_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/subscribers","subscription_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/subscription","commits_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/commits{/sha}","git_commits_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/git/commits{/sha}","comments_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/comments{/number}","issue_comment_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/issues/comments{/number}","contents_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/contents/{+path}","compare_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/compare/{base}...{head}","merges_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/merges","archive_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/downloads","issues_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/issues{/number}","pulls_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/pulls{/number}","milestones_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/milestones{/number}","notifications_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/labels{/name}","releases_url":"https://api.github.com/repos/brunobowden/j2objc-gradle/releases{/id}","created_at":"2015-06-07T22:04:38Z","updated_at":"2015-06-07T22:04:40Z","pushed_at":"2015-06-08T08:22:45Z","git_url":"git://github.com/brunobowden/j2objc-gradle.git","ssh_url":"git@github.com:brunobowden/j2objc-gradle.git","clone_url":"https://github.com/brunobowden/j2objc-gradle.git","svn_url":"https://github.com/brunobowden/j2objc-gradle","homepage":null,"size":1247,"stargazers_count":0,"watchers_count":0,"language":"Groovy","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"j2objc-contrib:master","ref":"master","sha":"7d96bd7d05bbb17bfbbe94a0d40e12b7f3bf5e7f","user":{"login":"j2objc-contrib","id":12766207,"avatar_url":"https://avatars.githubusercontent.com/u/12766207?v=3","gravatar_id":"","url":"https://api.github.com/users/j2objc-contrib","html_url":"https://github.com/j2objc-contrib","followers_url":"https://api.github.com/users/j2objc-contrib/followers","following_url":"https://api.github.com/users/j2objc-contrib/following{/other_user}","gists_url":"https://api.github.com/users/j2objc-contrib/gists{/gist_id}","starred_url":"https://api.github.com/users/j2objc-contrib/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/j2objc-contrib/subscriptions","organizations_url":"https://api.github.com/users/j2objc-contrib/orgs","repos_url":"https://api.github.com/users/j2objc-contrib/repos","events_url":"https://api.github.com/users/j2objc-contrib/events{/privacy}","received_events_url":"https://api.github.com/users/j2objc-contrib/received_events","type":"Organization","site_admin":false},"repo":{"id":30206593,"name":"j2objc-gradle","full_name":"j2objc-contrib/j2objc-gradle","owner":{"login":"j2objc-contrib","id":12766207,"avatar_url":"https://avatars.githubusercontent.com/u/12766207?v=3","gravatar_id":"","url":"https://api.github.com/users/j2objc-contrib","html_url":"https://github.com/j2objc-contrib","followers_url":"https://api.github.com/users/j2objc-contrib/followers","following_url":"https://api.github.com/users/j2objc-contrib/following{/other_user}","gists_url":"https://api.github.com/users/j2objc-contrib/gists{/gist_id}","starred_url":"https://api.github.com/users/j2objc-contrib/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/j2objc-contrib/subscriptions","organizations_url":"https://api.github.com/users/j2objc-contrib/orgs","repos_url":"https://api.github.com/users/j2objc-contrib/repos","events_url":"https://api.github.com/users/j2objc-contrib/events{/privacy}","received_events_url":"https://api.github.com/users/j2objc-contrib/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/j2objc-contrib/j2objc-gradle","description":"Gradle plugin for j2objc (Java to Objective-C transpiler)","fork":false,"url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle","forks_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/forks","keys_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/keys{/key_id}","collaborators_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/teams","hooks_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/hooks","issue_events_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/issues/events{/number}","events_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/events","assignees_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/assignees{/user}","branches_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/branches{/branch}","tags_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/tags","blobs_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/git/refs{/sha}","trees_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/git/trees{/sha}","statuses_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/statuses/{sha}","languages_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/languages","stargazers_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/stargazers","contributors_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/contributors","subscribers_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/subscribers","subscription_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/subscription","commits_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/commits{/sha}","git_commits_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/git/commits{/sha}","comments_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/comments{/number}","issue_comment_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/issues/comments{/number}","contents_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/contents/{+path}","compare_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/compare/{base}...{head}","merges_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/merges","archive_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/downloads","issues_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/issues{/number}","pulls_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/pulls{/number}","milestones_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/milestones{/number}","notifications_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/labels{/name}","releases_url":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/releases{/id}","created_at":"2015-02-02T20:22:07Z","updated_at":"2015-06-07T21:55:20Z","pushed_at":"2015-06-08T08:23:56Z","git_url":"git://github.com/j2objc-contrib/j2objc-gradle.git","ssh_url":"git@github.com:j2objc-contrib/j2objc-gradle.git","clone_url":"https://github.com/j2objc-contrib/j2objc-gradle.git","svn_url":"https://github.com/j2objc-contrib/j2objc-gradle","homepage":null,"size":1247,"stargazers_count":30,"watchers_count":30,"language":"Groovy","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":8,"mirror_url":null,"open_issues_count":23,"forks":8,"open_issues":23,"watchers":30,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/pulls/119"},"html":{"href":"https://github.com/j2objc-contrib/j2objc-gradle/pull/119"},"issue":{"href":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/issues/119"},"comments":{"href":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/issues/119/comments"},"review_comments":{"href":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/pulls/119/comments"},"review_comment":{"href":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/pulls/119/commits"},"statuses":{"href":"https://api.github.com/repos/j2objc-contrib/j2objc-gradle/statuses/e09d254df7764a15bcd3ca96028d59e115835740"}}}}