/*
 * Copyright 2018, TeamDev. All rights reserved.
 *
 * Redistribution and use in source and/or binary forms, with or without
 * modification, must retain the above copyright notice and the following
 * disclaimer.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package io.spine.model.verify;

import io.spine.tools.gradle.TaskName;
import io.spine.tools.gradle.given.GradleProject;
import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.BuildTask;
import org.gradle.testkit.runner.TaskOutcome;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import static io.spine.tools.gradle.TaskName.VERIFY_MODEL;
import static org.gradle.testkit.runner.TaskOutcome.FAILED;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

/**
 * @author Dmytro Dashenkov
 */
// TODO:2018-07-02:dmytro.kuzmin: Migrate to JUnit 5 when GradleProject class from
// spine-plugin-testlib will no longer require JUnit 4 TemporaryFolder class.
public class ModelVerifierPluginShould {

    private static final String PROJECT_NAME = "model-verifier-test";
    private static final String COMPILING_TEST_ENTITY_PATH =
            "io/spine/model/verify/ValidAggregate.java";

    @Rule
    public final TemporaryFolder testProjectDir = new TemporaryFolder();

    @Test
    void passValidModelClasses() {
        newProjectWithJava(COMPILING_TEST_ENTITY_PATH,
                           "io/spine/model/verify/ValidProcMan.java",
                           "io/spine/model/verify/ValidCommandHandler.java")
                .executeTask(VERIFY_MODEL);
    }

    @Test
    void haltBuildOnDuplicateCommandHandlingMethods() {
        final BuildResult result = newProjectWithJava(
                "io/spine/model/verify/DuplicateAggregate.java",
                "io/spine/model/verify/DuplicateCommandHandler.java")
                .executeAndFail(VERIFY_MODEL);
        final BuildTask task = result.task(toPath(VERIFY_MODEL));
        assertNotNull(task);
        final TaskOutcome generationResult = task.getOutcome();
        assertEquals(FAILED, generationResult);
    }

    @Test
    void ignoreDuplicateEntries() {
        final GradleProject project = newProjectWithJava(COMPILING_TEST_ENTITY_PATH);
        project.executeTask(VERIFY_MODEL);
        project.executeTask(VERIFY_MODEL);
    }

    @Ignore // TODO:2017-08-25:dmytro.dashenkov: Re-enable when Model is capable of
              // checking the handler methods.
              // https://github.com/SpineEventEngine/base/issues/49
    @Test
    void haltBuildOnMalformedCommandHandlingMethods() {
        final BuildResult result =
                newProjectWithJava("io/spine/model/verify/MalformedAggregate.java")
                .executeAndFail(VERIFY_MODEL);
        final BuildTask task = result.task(toPath(VERIFY_MODEL));
        assertNotNull(task);
        final TaskOutcome generationResult = task.getOutcome();
        assertEquals(FAILED, generationResult);
    }

    private GradleProject newProjectWithJava(String... fileNames) {
        return GradleProject.newBuilder()
                            .setProjectName(PROJECT_NAME)
                            .setProjectFolder(testProjectDir)
                            .addJavaFiles(fileNames)
                            .build();
    }

    private static String toPath(TaskName name) {
        return ':' + name.getValue();
    }
}

@@ -1707,16 +1707,23 @@
  from%0A//
+ %7B@code
  spine-p
@@ -1735,16 +1735,17 @@
 -testlib
+%7D
  will no
@@ -2116,24 +2116,31 @@
   @Test%0A    
+public 
 void passVal
@@ -2140,19 +2140,22 @@
 pass
-V
+_v
 alid
-M
+_m
 odel
-C
+_c
 lass
@@ -2420,32 +2420,39 @@
 %0A%0A    @Test%0A    
+public 
 void haltBuildOn
@@ -2448,24 +2448,27 @@
 halt
-B
+_b
 uild
-OnD
+_on_d
 uplicate
 Comm
@@ -2463,32 +2463,35 @@
 uplicate
-C
+_c
 ommand
-H
+_h
 andling
-M
+_m
 ethods()
@@ -2954,24 +2954,31 @@
   @Test%0A    
+public 
 void ignoreD
@@ -2976,25 +2976,26 @@
 d ignore
-D
+_d
 uplicate
 Entries(
@@ -2986,17 +2986,18 @@
 uplicate
-E
+_e
 ntries()
@@ -3262,26 +3262,16 @@
 able of%0A
-          
     // c
@@ -3299,26 +3299,16 @@
 ethods.%0A
-          
     // h
@@ -3371,16 +3371,23 @@
 est%0A    
+public 
 void hal
@@ -3391,24 +3391,27 @@
 halt
-B
+_b
 uild
-OnM
+_on_m
 alformed
 Comm
@@ -3410,24 +3410,27 @@
 rmed
-C
+_c
 ommand
-H
+_h
 andling
-M
+_m
 etho
@@ -3547,32 +3547,40 @@
 ggregate.java%22)%0A
+        
                 

Fix build