package com.tngtech.jgiven.examples.nested;

import static org.assertj.core.api.Assertions.assertThat;

import com.tngtech.jgiven.examples.tags.FailingOnPurpose;
import org.junit.Test;
import org.testng.Assert;

import com.tngtech.jgiven.Stage;
import com.tngtech.jgiven.annotation.ExtendedDescription;
import com.tngtech.jgiven.annotation.NestedSteps;
import com.tngtech.jgiven.annotation.ProvidedScenarioState;
import com.tngtech.jgiven.junit.SimpleScenarioTest;

public class NestedStepsTest extends SimpleScenarioTest<NestedStepsTest.NestedStage> {

    @Test
    @ExtendedDescription( "This scenario contains nested steps." )
    public void a_scenario_with_nested_steps() {

        given().I_fill_out_the_registration_form_with_valid_values();

        when().I_submit_the_form();

        then().the_password_matches();
    }

    @Test
    @FailingOnPurpose
    public void a_scenario_with_a_failing_nested_step_on_purpose() {

        given().I_fill_out_the_registration_form_with_invalid_values();

        when().I_submit_the_form();

        then().the_password_matches();
    }

    static class NestedStage extends Stage<NestedStage> {

        @ProvidedScenarioState
        String name;

        @ProvidedScenarioState
        String email;

        @ProvidedScenarioState
        String password;

        @ProvidedScenarioState
        String repeatedPassword;

        // tag::fillRegistrationForm[]
        @NestedSteps
        public NestedStage I_fill_out_the_registration_form_with_valid_values() {
            return I_enter_a_name( "Franky" )
                .and().I_enter_a_email_address( "franky@acme.com" )
                .and().I_enter_a_password( "password1234" )
                .and().I_enter_a_repeated_password( "password1234" );
        }
        // end::fillRegistrationForm[]

        @NestedSteps
        public NestedStage I_fill_out_the_registration_form_with_invalid_values() {
            return I_enter_a_name( "Franky" )
                .and().I_enter_a_email_address( "franky@acme.com" )
                .and().something_fails_for_demonstration_purposes();
        }

        public NestedStage something_fails_for_demonstration_purposes() {
            assertThat( true ).as( "Fails on purpose" ).isFalse();
            return self();
        }

        @NestedSteps
        public NestedStage I_enter_a_name( String name ) {
            return I_think_a_name( name )
                .and().I_write_the_name( name );
        }

        public NestedStage I_think_a_name( String name ) {
            return self();
        }

        public NestedStage I_write_the_name( String name ) {
            this.name = name;
            return self();
        }

        public NestedStage I_enter_a_email_address( String email ) {
            this.email = email;
            return self();
        }

        public NestedStage I_enter_a_password( String password ) {
            this.password = password;
            return self();
        }

        public NestedStage I_enter_a_repeated_password( String repeatedPassword ) {
            this.repeatedPassword = repeatedPassword;
            return self();
        }

        public NestedStage I_submit_the_form() {
            return self();
        }

        public NestedStage the_password_matches() {
            Assert.assertEquals( password, repeatedPassword );
            return self();
        }
    }
}

@@ -582,17 +582,16 @@
 ription(
- 
 %22This sc
@@ -620,17 +620,16 @@
  steps.%22
- 
 )%0A    pu
@@ -1544,33 +1544,32 @@
 nter_a_name(
- 
 %22Franky%22
  )%0A         
@@ -1548,33 +1548,32 @@
 _a_name(%22Franky%22
- 
 )%0A              
@@ -1597,33 +1597,32 @@
 a_email_address(
- 
 %22franky@acme.com
@@ -1614,33 +1614,32 @@
 franky@acme.com%22
- 
 )%0A              
@@ -1658,33 +1658,32 @@
 nter_a_password(
- 
 %22password1234%22 )
@@ -1680,17 +1680,16 @@
 ord1234%22
- 
 )%0A      
@@ -1733,17 +1733,16 @@
 assword(
- 
 %22passwor
@@ -1747,17 +1747,16 @@
 ord1234%22
- 
 );%0A     
@@ -1943,17 +1943,16 @@
 ame(
- 
 %22Franky%22
  )%0A 
@@ -1947,17 +1947,16 @@
 %22Franky%22
- 
 )%0A      
@@ -1996,17 +1996,16 @@
 address(
- 
 %22franky@
@@ -2013,17 +2013,16 @@
 cme.com%22
- 
 )%0A      
@@ -2087,32 +2087,33 @@
 s();%0A        %7D%0A%0A
+%0A
         public N
@@ -2197,20 +2197,17 @@
 hat(
- 
 true
- 
 ).as(
- 
 %22Fai
@@ -2220,17 +2220,16 @@
 purpose%22
- 
 ).isFals
@@ -2326,33 +2326,32 @@
  I_enter_a_name(
- 
 String name ) %7B%0A
@@ -2337,33 +2337,32 @@
 name(String name
- 
 ) %7B%0A            
@@ -2383,22 +2383,20 @@
 _a_name(
- 
 name
- 
 )%0A      
@@ -2429,22 +2429,20 @@
 he_name(
- 
 name
- 
 );%0A     
@@ -2485,25 +2485,24 @@
 hink_a_name(
- 
 String name 
@@ -2492,33 +2492,32 @@
 name(String name
- 
 ) %7B%0A            
@@ -2586,17 +2586,16 @@
 he_name(
- 
 String n
@@ -2597,17 +2597,16 @@
 ing name
- 
 ) %7B%0A    
@@ -2720,17 +2720,16 @@
 address(
- 
 String e
@@ -2732,17 +2732,16 @@
 ng email
- 
 ) %7B%0A    
@@ -2848,25 +2848,24 @@
 _a_password(
- 
 String passw
@@ -2863,25 +2863,24 @@
 ing password
- 
 ) %7B%0A        
@@ -3002,17 +3002,16 @@
 assword(
- 
 String r
@@ -3025,17 +3025,16 @@
 Password
- 
 ) %7B%0A    
@@ -3292,17 +3292,16 @@
 tEquals(
- 
 password
@@ -3318,17 +3318,16 @@
 Password
- 
 );%0A     

Format file according to checkstyle guidelines