001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License.
018 *
019 */
020package org.apache.mina.statemachine;
021
022import static org.junit.Assert.assertEquals;
023import static org.junit.Assert.assertSame;
024
025import org.apache.mina.statemachine.context.DefaultStateContext;
026import org.apache.mina.statemachine.context.StateContext;
027import org.apache.mina.statemachine.event.Event;
028import org.apache.mina.statemachine.transition.AbstractSelfTransition;
029import org.apache.mina.statemachine.transition.AbstractTransition;
030import org.junit.Test;
031
032/**
033 * Tests {@link StateMachine}.
034 *
035 * @author <a href="http://mina.apache.org">Apache MINA Project</a>
036 */
037public class StateMachineTest {
038
039    @Test
040    public void testBreakAndContinue() throws Exception {
041        State s1 = new State("s1");
042        s1.addTransition(new BreakAndContinueTransition("foo"));
043        s1.addTransition(new SuccessTransition("foo"));
044
045        StateContext context = new DefaultStateContext();
046        StateMachine sm = new StateMachine(new State[] { s1 }, "s1");
047        sm.handle(new Event("foo", context));
048        assertEquals(true, context.getAttribute("success"));
049    }
050
051    @Test
052    public void testBreakAndGotoNow() throws Exception {
053        State s1 = new State("s1");
054        State s2 = new State("s2");
055        s1.addTransition(new BreakAndGotoNowTransition("foo", "s2"));
056        s2.addTransition(new SuccessTransition("foo"));
057
058        StateContext context = new DefaultStateContext();
059        StateMachine sm = new StateMachine(new State[] { s1, s2 }, "s1");
060        sm.handle(new Event("foo", context));
061        assertEquals(true, context.getAttribute("success"));
062    }
063
064    @Test
065    public void testBreakAndGotoNext() throws Exception {
066        State s1 = new State("s1");
067        State s2 = new State("s2");
068        s1.addTransition(new BreakAndGotoNextTransition("foo", "s2"));
069        s2.addTransition(new SuccessTransition("foo"));
070
071        StateContext context = new DefaultStateContext();
072        StateMachine sm = new StateMachine(new State[] { s1, s2 }, "s1");
073        sm.handle(new Event("foo", context));
074        assertSame(s2, context.getCurrentState());
075        sm.handle(new Event("foo", context));
076        assertEquals(true, context.getAttribute("success"));
077    }
078
079    private static class SuccessTransition extends AbstractTransition {
080        public SuccessTransition(Object eventId) {
081            super(eventId);
082        }
083
084        public SuccessTransition(Object eventId, State nextState) {
085            super(eventId, nextState);
086        }
087
088        @Override
089        protected boolean doExecute(Event event) {
090            event.getContext().setAttribute("success", true);
091            return true;
092        }
093    }
094
095    private static class BreakAndContinueTransition extends AbstractTransition {
096        public BreakAndContinueTransition(Object eventId) {
097            super(eventId);
098        }
099
100        public BreakAndContinueTransition(Object eventId, State nextState) {
101            super(eventId, nextState);
102        }
103
104        @Override
105        protected boolean doExecute(Event event) {
106            StateControl.breakAndContinue();
107            return true;
108        }
109    }
110
111    private static class BreakAndGotoNowTransition extends AbstractTransition {
112        private final String stateId;
113
114        public BreakAndGotoNowTransition(Object eventId, String stateId) {
115            super(eventId);
116            this.stateId = stateId;
117        }
118
119        public BreakAndGotoNowTransition(Object eventId, State nextState, String stateId) {
120            super(eventId, nextState);
121            this.stateId = stateId;
122        }
123
124        @Override
125        protected boolean doExecute(Event event) {
126            StateControl.breakAndGotoNow(stateId);
127            return true;
128        }
129    }
130
131    private static class BreakAndGotoNextTransition extends AbstractTransition {
132        private final String stateId;
133
134        public BreakAndGotoNextTransition(Object eventId, String stateId) {
135            super(eventId);
136            this.stateId = stateId;
137        }
138
139        public BreakAndGotoNextTransition(Object eventId, State nextState, String stateId) {
140            super(eventId, nextState);
141            this.stateId = stateId;
142        }
143
144        @Override
145        protected boolean doExecute(Event event) {
146            StateControl.breakAndGotoNext(stateId);
147            return true;
148        }
149    }
150
151    private static class SampleSelfTransition extends AbstractSelfTransition {
152        public SampleSelfTransition() {
153            super();
154        }
155
156        @Override
157        protected boolean doExecute(StateContext stateContext, State state) {
158            stateContext.setAttribute("SelfSuccess" + state.getId(), true);
159            return true;
160        }
161
162    }
163
164    @Test
165    public void testOnEntry() throws Exception {
166        State s1 = new State("s1");
167        State s2 = new State("s2");
168
169        s1.addTransition(new SuccessTransition("foo", s2));
170        s1.addOnExitSelfTransaction(new SampleSelfTransition());
171        s2.addOnEntrySelfTransaction(new SampleSelfTransition());
172
173        StateContext context = new DefaultStateContext();
174        StateMachine sm = new StateMachine(new State[] { s1, s2 }, "s1");
175        sm.handle(new Event("foo", context));
176        assertEquals(true, context.getAttribute("success"));
177        assertEquals(true, context.getAttribute("SelfSuccess" + s1.getId()));
178        assertEquals(true, context.getAttribute("SelfSuccess" + s2.getId()));
179
180    }
181
182}