Fix Redis/Mongo entity states
- Fix RedisRepositoryState and MongoDbStateRepository not to use null for machineid in any case as contract is that empty machineid is always empty not null. - This issue was found when adding initial tck config tests, thus this commit also adds initial tck tests. - Fixes #279 - Relates to #278
This commit is contained in:
@@ -305,6 +305,13 @@ project('spring-statemachine-build-tests') {
|
||||
dependencies {
|
||||
testCompile project(":spring-statemachine-uml")
|
||||
testCompile project(":spring-statemachine-test")
|
||||
testCompile project(":spring-statemachine-data-common:spring-statemachine-data-jpa")
|
||||
testCompile project(":spring-statemachine-data-common:spring-statemachine-data-redis")
|
||||
testCompile project(":spring-statemachine-data-common:spring-statemachine-data-mongodb")
|
||||
testRuntime "org.springframework.boot:spring-boot-starter-data-redis:$springBootVersion"
|
||||
testCompile "org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion"
|
||||
testCompile "com.h2database:h2:$h2Version"
|
||||
testCompile "org.springframework.boot:spring-boot-starter:$springBootVersion"
|
||||
testCompile "org.springframework:spring-test:$springVersion"
|
||||
testCompile "org.hamcrest:hamcrest-core:$hamcrestVersion"
|
||||
testCompile "org.hamcrest:hamcrest-library:$hamcrestVersion"
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.statemachine.buildtests.tck;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.statemachine.StateMachine;
|
||||
import org.springframework.statemachine.config.StateMachineFactory;
|
||||
import org.springframework.statemachine.test.StateMachineTestPlan;
|
||||
import org.springframework.statemachine.test.StateMachineTestPlanBuilder;
|
||||
|
||||
/**
|
||||
* Base tck test class for defining various machine tests
|
||||
* which different config implementations can implement to
|
||||
* test that same machine behaviour.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractTckTests {
|
||||
|
||||
protected AnnotationConfigApplicationContext context;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
cleanInternal();
|
||||
context = buildContext();
|
||||
}
|
||||
|
||||
@After
|
||||
public void clean() {
|
||||
if (context != null) {
|
||||
context.close();
|
||||
}
|
||||
context = null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected StateMachine<String, String> getStateMachineFromContext() {
|
||||
return context.getBean(StateMachine.class);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected StateMachineFactory<String, String> getStateMachineFactoryFromContext() {
|
||||
return context.getBean(StateMachineFactory.class);
|
||||
}
|
||||
|
||||
protected void cleanInternal() {
|
||||
}
|
||||
|
||||
protected AnnotationConfigApplicationContext buildContext() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleMachine() throws Exception {
|
||||
StateMachine<String,String> stateMachine = getSimpleMachine();
|
||||
StateMachineTestPlan<String, String> plan =
|
||||
StateMachineTestPlanBuilder.<String, String>builder()
|
||||
.stateMachine(stateMachine)
|
||||
.step().expectStates("S1").and()
|
||||
.step().sendEvent("E1").expectStates("S2").and()
|
||||
.step().sendEvent("E2").expectStates("S3").and()
|
||||
.build();
|
||||
plan.test();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return state machine for {@link #testSimpleMachine()}.
|
||||
*
|
||||
* @return StateMachine for SimpleMachine
|
||||
*/
|
||||
protected abstract StateMachine<String, String> getSimpleMachine();
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.statemachine.buildtests.tck.javaconfig;
|
||||
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.statemachine.StateMachine;
|
||||
import org.springframework.statemachine.buildtests.tck.AbstractTckTests;
|
||||
import org.springframework.statemachine.config.EnableStateMachine;
|
||||
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
|
||||
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
|
||||
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
|
||||
|
||||
/**
|
||||
* Tck tests for annotation based javaconfig.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*
|
||||
*/
|
||||
public class AnnotationTckTests extends AbstractTckTests {
|
||||
|
||||
@Override
|
||||
protected AnnotationConfigApplicationContext buildContext() {
|
||||
return new AnnotationConfigApplicationContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StateMachine<String, String> getSimpleMachine() {
|
||||
context.register(SimpleMachineConfig.class);
|
||||
context.refresh();
|
||||
return getStateMachineFromContext();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableStateMachine
|
||||
static class SimpleMachineConfig extends StateMachineConfigurerAdapter<String, String> {
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineStateConfigurer<String, String> states) throws Exception {
|
||||
states
|
||||
.withStates()
|
||||
.initial("S1")
|
||||
.state("S2")
|
||||
.state("S3");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineTransitionConfigurer<String, String> transitions) throws Exception {
|
||||
transitions
|
||||
.withExternal()
|
||||
.source("S1").target("S2")
|
||||
.event("E1")
|
||||
.and()
|
||||
.withExternal()
|
||||
.source("S2").target("S3")
|
||||
.event("E2");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.statemachine.buildtests.tck.jpa;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
import org.springframework.statemachine.StateMachine;
|
||||
import org.springframework.statemachine.buildtests.tck.AbstractTckTests;
|
||||
import org.springframework.statemachine.config.EnableStateMachineFactory;
|
||||
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
|
||||
import org.springframework.statemachine.config.builders.StateMachineModelConfigurer;
|
||||
import org.springframework.statemachine.config.model.StateMachineModelFactory;
|
||||
import org.springframework.statemachine.data.RepositoryState;
|
||||
import org.springframework.statemachine.data.RepositoryStateMachineModelFactory;
|
||||
import org.springframework.statemachine.data.RepositoryTransition;
|
||||
import org.springframework.statemachine.data.StateRepository;
|
||||
import org.springframework.statemachine.data.TransitionRepository;
|
||||
import org.springframework.statemachine.data.support.StateMachineJackson2RepositoryPopulatorFactoryBean;
|
||||
|
||||
/**
|
||||
* Tck tests for machine configs imported from json entity definitions.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*
|
||||
*/
|
||||
public class JpaJsonTckTests extends AbstractTckTests {
|
||||
|
||||
@Override
|
||||
protected AnnotationConfigApplicationContext buildContext() {
|
||||
return new AnnotationConfigApplicationContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StateMachine<String, String> getSimpleMachine() {
|
||||
context.register(TestConfig.class, SimpleMachineConfig.class, StateMachineFactoryConfig.class);
|
||||
context.refresh();
|
||||
return getStateMachineFactoryFromContext().getStateMachine();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class SimpleMachineConfig {
|
||||
|
||||
@Bean
|
||||
public StateMachineJackson2RepositoryPopulatorFactoryBean jackson2RepositoryPopulatorFactoryBean() {
|
||||
StateMachineJackson2RepositoryPopulatorFactoryBean factoryBean = new StateMachineJackson2RepositoryPopulatorFactoryBean();
|
||||
factoryBean.setResources(new Resource[]{new ClassPathResource("org/springframework/statemachine/buildtests/tck/jpa/SimpleMachine.json")});
|
||||
return factoryBean;
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableStateMachineFactory
|
||||
public static class StateMachineFactoryConfig extends StateMachineConfigurerAdapter<String, String> {
|
||||
|
||||
@Autowired
|
||||
private StateRepository<? extends RepositoryState> stateRepository;
|
||||
|
||||
@Autowired
|
||||
private TransitionRepository<? extends RepositoryTransition> transitionRepository;
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
|
||||
model
|
||||
.withModel()
|
||||
.factory(modelFactory());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public StateMachineModelFactory<String, String> modelFactory() {
|
||||
return new RepositoryStateMachineModelFactory(stateRepository, transitionRepository);
|
||||
}
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
@EntityScan(basePackages = {"org.springframework.statemachine.data.jpa"})
|
||||
@EnableJpaRepositories(basePackages = {"org.springframework.statemachine.data.jpa"})
|
||||
static class TestConfig {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.statemachine.buildtests.tck.jpa;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
import org.springframework.statemachine.StateMachine;
|
||||
import org.springframework.statemachine.buildtests.tck.AbstractTckTests;
|
||||
import org.springframework.statemachine.config.EnableStateMachineFactory;
|
||||
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
|
||||
import org.springframework.statemachine.config.builders.StateMachineModelConfigurer;
|
||||
import org.springframework.statemachine.config.model.StateMachineModelFactory;
|
||||
import org.springframework.statemachine.data.RepositoryState;
|
||||
import org.springframework.statemachine.data.RepositoryStateMachineModelFactory;
|
||||
import org.springframework.statemachine.data.RepositoryTransition;
|
||||
import org.springframework.statemachine.data.StateRepository;
|
||||
import org.springframework.statemachine.data.TransitionRepository;
|
||||
import org.springframework.statemachine.data.jpa.JpaRepositoryState;
|
||||
import org.springframework.statemachine.data.jpa.JpaRepositoryTransition;
|
||||
import org.springframework.statemachine.data.jpa.JpaStateRepository;
|
||||
import org.springframework.statemachine.data.jpa.JpaTransitionRepository;
|
||||
|
||||
/**
|
||||
* Tck tests for machine configs build manually agains repository interfaces.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*
|
||||
*/
|
||||
public class JpaManualTckTests extends AbstractTckTests {
|
||||
|
||||
@Override
|
||||
protected AnnotationConfigApplicationContext buildContext() {
|
||||
return new AnnotationConfigApplicationContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StateMachine<String, String> getSimpleMachine() {
|
||||
context.register(TestConfig.class, StateMachineFactoryConfig.class);
|
||||
context.refresh();
|
||||
|
||||
JpaStateRepository stateRepository = context.getBean(JpaStateRepository.class);
|
||||
JpaTransitionRepository transitionRepository = context.getBean(JpaTransitionRepository.class);
|
||||
|
||||
JpaRepositoryState stateS1 = new JpaRepositoryState("S1", true);
|
||||
JpaRepositoryState stateS2 = new JpaRepositoryState("S2");
|
||||
JpaRepositoryState stateS3 = new JpaRepositoryState("S3");
|
||||
|
||||
stateRepository.save(stateS1);
|
||||
stateRepository.save(stateS2);
|
||||
stateRepository.save(stateS3);
|
||||
|
||||
JpaRepositoryTransition transitionS1ToS2 = new JpaRepositoryTransition(stateS1, stateS2, "E1");
|
||||
JpaRepositoryTransition transitionS2ToS3 = new JpaRepositoryTransition(stateS2, stateS3, "E2");
|
||||
|
||||
transitionRepository.save(transitionS1ToS2);
|
||||
transitionRepository.save(transitionS2ToS3);
|
||||
|
||||
return getStateMachineFactoryFromContext().getStateMachine();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableStateMachineFactory
|
||||
public static class StateMachineFactoryConfig extends StateMachineConfigurerAdapter<String, String> {
|
||||
|
||||
@Autowired
|
||||
private StateRepository<? extends RepositoryState> stateRepository;
|
||||
|
||||
@Autowired
|
||||
private TransitionRepository<? extends RepositoryTransition> transitionRepository;
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
|
||||
model
|
||||
.withModel()
|
||||
.factory(modelFactory());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public StateMachineModelFactory<String, String> modelFactory() {
|
||||
return new RepositoryStateMachineModelFactory(stateRepository, transitionRepository);
|
||||
}
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
@EntityScan(basePackages = {"org.springframework.statemachine.data.jpa"})
|
||||
@EnableJpaRepositories(basePackages = {"org.springframework.statemachine.data.jpa"})
|
||||
static class TestConfig {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.statemachine.buildtests.tck.mongodb;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
|
||||
import org.springframework.statemachine.StateMachine;
|
||||
import org.springframework.statemachine.buildtests.tck.AbstractTckTests;
|
||||
import org.springframework.statemachine.config.EnableStateMachineFactory;
|
||||
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
|
||||
import org.springframework.statemachine.config.builders.StateMachineModelConfigurer;
|
||||
import org.springframework.statemachine.config.model.StateMachineModelFactory;
|
||||
import org.springframework.statemachine.data.RepositoryState;
|
||||
import org.springframework.statemachine.data.RepositoryStateMachineModelFactory;
|
||||
import org.springframework.statemachine.data.RepositoryTransition;
|
||||
import org.springframework.statemachine.data.StateRepository;
|
||||
import org.springframework.statemachine.data.TransitionRepository;
|
||||
import org.springframework.statemachine.data.mongodb.MongoDbRepositoryAction;
|
||||
import org.springframework.statemachine.data.mongodb.MongoDbRepositoryGuard;
|
||||
import org.springframework.statemachine.data.mongodb.MongoDbRepositoryState;
|
||||
import org.springframework.statemachine.data.mongodb.MongoDbRepositoryTransition;
|
||||
import org.springframework.statemachine.data.support.StateMachineJackson2RepositoryPopulatorFactoryBean;
|
||||
|
||||
/**
|
||||
* Tck tests for machine configs imported from json entity definitions.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*
|
||||
*/
|
||||
public class MongoDbJsonTckTests extends AbstractTckTests {
|
||||
|
||||
@Rule
|
||||
public MongoDbRule MongoDbAvailableRule = new MongoDbRule();
|
||||
|
||||
@Override
|
||||
protected void cleanInternal() {
|
||||
AnnotationConfigApplicationContext c = new AnnotationConfigApplicationContext();
|
||||
c.register(TestConfig.class);
|
||||
c.refresh();
|
||||
MongoTemplate template = c.getBean(MongoTemplate.class);
|
||||
template.dropCollection(MongoDbRepositoryAction.class);
|
||||
template.dropCollection(MongoDbRepositoryGuard.class);
|
||||
template.dropCollection(MongoDbRepositoryState.class);
|
||||
template.dropCollection(MongoDbRepositoryTransition.class);
|
||||
c.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AnnotationConfigApplicationContext buildContext() {
|
||||
return new AnnotationConfigApplicationContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StateMachine<String, String> getSimpleMachine() {
|
||||
context.register(TestConfig.class, SimpleMachineConfig.class, StateMachineFactoryConfig.class);
|
||||
context.refresh();
|
||||
return getStateMachineFactoryFromContext().getStateMachine();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class SimpleMachineConfig {
|
||||
|
||||
@Bean
|
||||
public StateMachineJackson2RepositoryPopulatorFactoryBean jackson2RepositoryPopulatorFactoryBean() {
|
||||
StateMachineJackson2RepositoryPopulatorFactoryBean factoryBean = new StateMachineJackson2RepositoryPopulatorFactoryBean();
|
||||
factoryBean.setResources(new Resource[]{new ClassPathResource("org/springframework/statemachine/buildtests/tck/mongodb/SimpleMachine.json")});
|
||||
return factoryBean;
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableStateMachineFactory
|
||||
public static class StateMachineFactoryConfig extends StateMachineConfigurerAdapter<String, String> {
|
||||
|
||||
@Autowired
|
||||
private StateRepository<? extends RepositoryState> stateRepository;
|
||||
|
||||
@Autowired
|
||||
private TransitionRepository<? extends RepositoryTransition> transitionRepository;
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
|
||||
model
|
||||
.withModel()
|
||||
.factory(modelFactory());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public StateMachineModelFactory<String, String> modelFactory() {
|
||||
return new RepositoryStateMachineModelFactory(stateRepository, transitionRepository);
|
||||
}
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
@EntityScan(basePackages = {"org.springframework.statemachine.data.mongodb"})
|
||||
@EnableMongoRepositories(basePackages = {"org.springframework.statemachine.data.mongodb"})
|
||||
static class TestConfig {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.statemachine.buildtests.tck.mongodb;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
|
||||
import org.springframework.statemachine.StateMachine;
|
||||
import org.springframework.statemachine.buildtests.tck.AbstractTckTests;
|
||||
import org.springframework.statemachine.config.EnableStateMachineFactory;
|
||||
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
|
||||
import org.springframework.statemachine.config.builders.StateMachineModelConfigurer;
|
||||
import org.springframework.statemachine.config.model.StateMachineModelFactory;
|
||||
import org.springframework.statemachine.data.RepositoryState;
|
||||
import org.springframework.statemachine.data.RepositoryStateMachineModelFactory;
|
||||
import org.springframework.statemachine.data.RepositoryTransition;
|
||||
import org.springframework.statemachine.data.StateRepository;
|
||||
import org.springframework.statemachine.data.TransitionRepository;
|
||||
import org.springframework.statemachine.data.mongodb.MongoDbRepositoryAction;
|
||||
import org.springframework.statemachine.data.mongodb.MongoDbRepositoryGuard;
|
||||
import org.springframework.statemachine.data.mongodb.MongoDbRepositoryState;
|
||||
import org.springframework.statemachine.data.mongodb.MongoDbRepositoryTransition;
|
||||
import org.springframework.statemachine.data.mongodb.MongoDbStateRepository;
|
||||
import org.springframework.statemachine.data.mongodb.MongoDbTransitionRepository;
|
||||
|
||||
/**
|
||||
* Tck tests for machine configs build manually agains repository interfaces.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*
|
||||
*/
|
||||
public class MongoDbManualTckTests extends AbstractTckTests {
|
||||
|
||||
@Rule
|
||||
public MongoDbRule MongoDbAvailableRule = new MongoDbRule();
|
||||
|
||||
@Override
|
||||
protected void cleanInternal() {
|
||||
AnnotationConfigApplicationContext c = new AnnotationConfigApplicationContext();
|
||||
c.register(TestConfig.class);
|
||||
c.refresh();
|
||||
MongoTemplate template = c.getBean(MongoTemplate.class);
|
||||
template.dropCollection(MongoDbRepositoryAction.class);
|
||||
template.dropCollection(MongoDbRepositoryGuard.class);
|
||||
template.dropCollection(MongoDbRepositoryState.class);
|
||||
template.dropCollection(MongoDbRepositoryTransition.class);
|
||||
c.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AnnotationConfigApplicationContext buildContext() {
|
||||
return new AnnotationConfigApplicationContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StateMachine<String, String> getSimpleMachine() {
|
||||
context.register(TestConfig.class, StateMachineFactoryConfig.class);
|
||||
context.refresh();
|
||||
|
||||
MongoDbStateRepository stateRepository = context.getBean(MongoDbStateRepository.class);
|
||||
MongoDbTransitionRepository transitionRepository = context.getBean(MongoDbTransitionRepository.class);
|
||||
|
||||
MongoDbRepositoryState stateS1 = new MongoDbRepositoryState("S1", true);
|
||||
MongoDbRepositoryState stateS2 = new MongoDbRepositoryState("S2");
|
||||
MongoDbRepositoryState stateS3 = new MongoDbRepositoryState("S3");
|
||||
|
||||
stateRepository.save(stateS1);
|
||||
stateRepository.save(stateS2);
|
||||
stateRepository.save(stateS3);
|
||||
|
||||
MongoDbRepositoryTransition transitionS1ToS2 = new MongoDbRepositoryTransition(stateS1, stateS2, "E1");
|
||||
MongoDbRepositoryTransition transitionS2ToS3 = new MongoDbRepositoryTransition(stateS2, stateS3, "E2");
|
||||
|
||||
transitionRepository.save(transitionS1ToS2);
|
||||
transitionRepository.save(transitionS2ToS3);
|
||||
|
||||
return getStateMachineFactoryFromContext().getStateMachine();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableStateMachineFactory
|
||||
public static class StateMachineFactoryConfig extends StateMachineConfigurerAdapter<String, String> {
|
||||
|
||||
@Autowired
|
||||
private StateRepository<? extends RepositoryState> stateRepository;
|
||||
|
||||
@Autowired
|
||||
private TransitionRepository<? extends RepositoryTransition> transitionRepository;
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
|
||||
model
|
||||
.withModel()
|
||||
.factory(modelFactory());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public StateMachineModelFactory<String, String> modelFactory() {
|
||||
return new RepositoryStateMachineModelFactory(stateRepository, transitionRepository);
|
||||
}
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
@EntityScan(basePackages = {"org.springframework.statemachine.data.mongodb"})
|
||||
@EnableMongoRepositories(basePackages = {"org.springframework.statemachine.data.mongodb"})
|
||||
static class TestConfig {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.statemachine.buildtests.tck.mongodb;
|
||||
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.rules.TestWatcher;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
import com.mongodb.MongoClient;
|
||||
import com.mongodb.MongoClientOptions;
|
||||
import com.mongodb.ServerAddress;
|
||||
|
||||
/**
|
||||
* Rule skipping tests if MongoDb is not available from localhost with default settings.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*
|
||||
*/
|
||||
public class MongoDbRule extends TestWatcher implements TestRule {
|
||||
|
||||
@Override
|
||||
public Statement apply(Statement base, Description description) {
|
||||
MongoClient client = null;
|
||||
try {
|
||||
client = new MongoClient(new ServerAddress(), MongoClientOptions.builder().connectTimeout(50).build());
|
||||
client.getAddress();
|
||||
} catch (Exception e) {
|
||||
return super.apply(new Statement() {
|
||||
@Override
|
||||
public void evaluate() throws Throwable {
|
||||
}
|
||||
}, Description.EMPTY);
|
||||
} finally {
|
||||
if (client != null) {
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
return super.apply(base, description);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.statemachine.buildtests.tck.redis;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.data.keyvalue.core.KeyValueTemplate;
|
||||
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
|
||||
import org.springframework.statemachine.StateMachine;
|
||||
import org.springframework.statemachine.buildtests.tck.AbstractTckTests;
|
||||
import org.springframework.statemachine.config.EnableStateMachineFactory;
|
||||
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
|
||||
import org.springframework.statemachine.config.builders.StateMachineModelConfigurer;
|
||||
import org.springframework.statemachine.config.model.StateMachineModelFactory;
|
||||
import org.springframework.statemachine.data.RepositoryState;
|
||||
import org.springframework.statemachine.data.RepositoryStateMachineModelFactory;
|
||||
import org.springframework.statemachine.data.RepositoryTransition;
|
||||
import org.springframework.statemachine.data.StateRepository;
|
||||
import org.springframework.statemachine.data.TransitionRepository;
|
||||
import org.springframework.statemachine.data.redis.RedisRepositoryAction;
|
||||
import org.springframework.statemachine.data.redis.RedisRepositoryGuard;
|
||||
import org.springframework.statemachine.data.redis.RedisRepositoryState;
|
||||
import org.springframework.statemachine.data.redis.RedisRepositoryTransition;
|
||||
import org.springframework.statemachine.data.support.StateMachineJackson2RepositoryPopulatorFactoryBean;
|
||||
|
||||
/**
|
||||
* Tck tests for machine configs imported from json entity definitions.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*
|
||||
*/
|
||||
public class RedisJsonTckTests extends AbstractTckTests {
|
||||
|
||||
@Rule
|
||||
public RedisRule redisAvailableRule = new RedisRule();
|
||||
|
||||
@Override
|
||||
protected AnnotationConfigApplicationContext buildContext() {
|
||||
return new AnnotationConfigApplicationContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void cleanInternal() {
|
||||
AnnotationConfigApplicationContext c = new AnnotationConfigApplicationContext();
|
||||
c.register(TestConfig.class);
|
||||
c.refresh();
|
||||
KeyValueTemplate kvTemplate = c.getBean(KeyValueTemplate.class);
|
||||
kvTemplate.delete(RedisRepositoryAction.class);
|
||||
kvTemplate.delete(RedisRepositoryGuard.class);
|
||||
kvTemplate.delete(RedisRepositoryState.class);
|
||||
kvTemplate.delete(RedisRepositoryTransition.class);
|
||||
c.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StateMachine<String, String> getSimpleMachine() {
|
||||
context.register(TestConfig.class, SimpleMachineConfig.class, StateMachineFactoryConfig.class);
|
||||
context.refresh();
|
||||
return getStateMachineFactoryFromContext().getStateMachine();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class SimpleMachineConfig {
|
||||
|
||||
@Bean
|
||||
public StateMachineJackson2RepositoryPopulatorFactoryBean jackson2RepositoryPopulatorFactoryBean() {
|
||||
StateMachineJackson2RepositoryPopulatorFactoryBean factoryBean = new StateMachineJackson2RepositoryPopulatorFactoryBean();
|
||||
factoryBean.setResources(new Resource[]{new ClassPathResource("org/springframework/statemachine/buildtests/tck/redis/SimpleMachine.json")});
|
||||
return factoryBean;
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableStateMachineFactory
|
||||
public static class StateMachineFactoryConfig extends StateMachineConfigurerAdapter<String, String> {
|
||||
|
||||
@Autowired
|
||||
private StateRepository<? extends RepositoryState> stateRepository;
|
||||
|
||||
@Autowired
|
||||
private TransitionRepository<? extends RepositoryTransition> transitionRepository;
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
|
||||
model
|
||||
.withModel()
|
||||
.factory(modelFactory());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public StateMachineModelFactory<String, String> modelFactory() {
|
||||
return new RepositoryStateMachineModelFactory(stateRepository, transitionRepository);
|
||||
}
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
@EntityScan(basePackages = {"org.springframework.statemachine.data.redis"})
|
||||
@EnableRedisRepositories(basePackages = {"org.springframework.statemachine.data.redis"})
|
||||
static class TestConfig {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.statemachine.buildtests.tck.redis;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.keyvalue.core.KeyValueTemplate;
|
||||
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
|
||||
import org.springframework.statemachine.StateMachine;
|
||||
import org.springframework.statemachine.buildtests.tck.AbstractTckTests;
|
||||
import org.springframework.statemachine.config.EnableStateMachineFactory;
|
||||
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
|
||||
import org.springframework.statemachine.config.builders.StateMachineModelConfigurer;
|
||||
import org.springframework.statemachine.config.model.StateMachineModelFactory;
|
||||
import org.springframework.statemachine.data.RepositoryState;
|
||||
import org.springframework.statemachine.data.RepositoryStateMachineModelFactory;
|
||||
import org.springframework.statemachine.data.RepositoryTransition;
|
||||
import org.springframework.statemachine.data.StateRepository;
|
||||
import org.springframework.statemachine.data.TransitionRepository;
|
||||
import org.springframework.statemachine.data.redis.RedisRepositoryAction;
|
||||
import org.springframework.statemachine.data.redis.RedisRepositoryGuard;
|
||||
import org.springframework.statemachine.data.redis.RedisRepositoryState;
|
||||
import org.springframework.statemachine.data.redis.RedisRepositoryTransition;
|
||||
import org.springframework.statemachine.data.redis.RedisStateRepository;
|
||||
import org.springframework.statemachine.data.redis.RedisTransitionRepository;
|
||||
|
||||
/**
|
||||
* Tck tests for machine configs build manually agains repository interfaces.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*
|
||||
*/
|
||||
public class RedisManualTckTests extends AbstractTckTests {
|
||||
|
||||
@Rule
|
||||
public RedisRule redisAvailableRule = new RedisRule();
|
||||
|
||||
@Override
|
||||
protected void cleanInternal() {
|
||||
AnnotationConfigApplicationContext c = new AnnotationConfigApplicationContext();
|
||||
c.register(TestConfig.class);
|
||||
c.refresh();
|
||||
KeyValueTemplate kvTemplate = c.getBean(KeyValueTemplate.class);
|
||||
kvTemplate.delete(RedisRepositoryAction.class);
|
||||
kvTemplate.delete(RedisRepositoryGuard.class);
|
||||
kvTemplate.delete(RedisRepositoryState.class);
|
||||
kvTemplate.delete(RedisRepositoryTransition.class);
|
||||
c.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AnnotationConfigApplicationContext buildContext() {
|
||||
return new AnnotationConfigApplicationContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StateMachine<String, String> getSimpleMachine() {
|
||||
context.register(TestConfig.class, StateMachineFactoryConfig.class);
|
||||
context.refresh();
|
||||
|
||||
RedisStateRepository stateRepository = context.getBean(RedisStateRepository.class);
|
||||
RedisTransitionRepository transitionRepository = context.getBean(RedisTransitionRepository.class);
|
||||
|
||||
RedisRepositoryState stateS1 = new RedisRepositoryState("S1", true);
|
||||
RedisRepositoryState stateS2 = new RedisRepositoryState("S2");
|
||||
RedisRepositoryState stateS3 = new RedisRepositoryState("S3");
|
||||
|
||||
stateRepository.save(stateS1);
|
||||
stateRepository.save(stateS2);
|
||||
stateRepository.save(stateS3);
|
||||
|
||||
|
||||
RedisRepositoryTransition transitionS1ToS2 = new RedisRepositoryTransition(stateS1, stateS2, "E1");
|
||||
RedisRepositoryTransition transitionS2ToS3 = new RedisRepositoryTransition(stateS2, stateS3, "E2");
|
||||
|
||||
transitionRepository.save(transitionS1ToS2);
|
||||
transitionRepository.save(transitionS2ToS3);
|
||||
|
||||
return getStateMachineFactoryFromContext().getStateMachine();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableStateMachineFactory
|
||||
public static class StateMachineFactoryConfig extends StateMachineConfigurerAdapter<String, String> {
|
||||
|
||||
@Autowired
|
||||
private StateRepository<? extends RepositoryState> stateRepository;
|
||||
|
||||
@Autowired
|
||||
private TransitionRepository<? extends RepositoryTransition> transitionRepository;
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
|
||||
model
|
||||
.withModel()
|
||||
.factory(modelFactory());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public StateMachineModelFactory<String, String> modelFactory() {
|
||||
return new RepositoryStateMachineModelFactory(stateRepository, transitionRepository);
|
||||
}
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
@EntityScan(basePackages = {"org.springframework.statemachine.data.redis"})
|
||||
@EnableRedisRepositories(basePackages = {"org.springframework.statemachine.data.redis"})
|
||||
static class TestConfig {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.statemachine.buildtests.tck.redis;
|
||||
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.rules.TestWatcher;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
|
||||
|
||||
/**
|
||||
* Rule skipping tests if redis is not available from localhost with default settings.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*
|
||||
*/
|
||||
public class RedisRule extends TestWatcher implements TestRule {
|
||||
|
||||
@Override
|
||||
public Statement apply(Statement base, Description description) {
|
||||
JedisConnectionFactory connectionFactory = null;
|
||||
try {
|
||||
connectionFactory = new JedisConnectionFactory();
|
||||
connectionFactory.afterPropertiesSet();
|
||||
connectionFactory.getConnection().close();
|
||||
} catch (Exception e) {
|
||||
return super.apply(new Statement() {
|
||||
@Override
|
||||
public void evaluate() throws Throwable {
|
||||
}
|
||||
}, Description.EMPTY);
|
||||
} finally {
|
||||
if (connectionFactory != null) {
|
||||
connectionFactory.destroy();
|
||||
}
|
||||
}
|
||||
return super.apply(base, description);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.statemachine.buildtests.tck.uml;
|
||||
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.statemachine.StateMachine;
|
||||
import org.springframework.statemachine.buildtests.tck.AbstractTckTests;
|
||||
import org.springframework.statemachine.config.EnableStateMachine;
|
||||
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
|
||||
import org.springframework.statemachine.config.builders.StateMachineModelConfigurer;
|
||||
import org.springframework.statemachine.config.model.StateMachineModelFactory;
|
||||
import org.springframework.statemachine.uml.UmlStateMachineModelFactory;
|
||||
|
||||
/**
|
||||
* Tck tests for machine configs build from uml.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*
|
||||
*/
|
||||
public class UmlTckTests extends AbstractTckTests {
|
||||
|
||||
@Override
|
||||
protected AnnotationConfigApplicationContext buildContext() {
|
||||
return new AnnotationConfigApplicationContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StateMachine<String, String> getSimpleMachine() {
|
||||
context.register(SimpleMachineConfig.class);
|
||||
context.refresh();
|
||||
return getStateMachineFromContext();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableStateMachine
|
||||
public static class SimpleMachineConfig extends StateMachineConfigurerAdapter<String, String> {
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
|
||||
model
|
||||
.withModel()
|
||||
.factory(modelFactory());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public StateMachineModelFactory<String, String> modelFactory() {
|
||||
return new UmlStateMachineModelFactory("classpath:org/springframework/statemachine/buildtests/tck/uml/SimpleMachine.uml");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
[
|
||||
{
|
||||
"@id": "1",
|
||||
"_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState",
|
||||
"initial": true,
|
||||
"state": "S1"
|
||||
},
|
||||
{
|
||||
"@id": "2",
|
||||
"_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState",
|
||||
"initial": false,
|
||||
"state": "S2"
|
||||
},
|
||||
{
|
||||
"@id": "3",
|
||||
"_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState",
|
||||
"initial": false,
|
||||
"state": "S3"
|
||||
},
|
||||
{
|
||||
"_class": "org.springframework.statemachine.data.jpa.JpaRepositoryTransition",
|
||||
"source": "1",
|
||||
"target": "2",
|
||||
"event": "E1"
|
||||
},
|
||||
{
|
||||
"_class": "org.springframework.statemachine.data.jpa.JpaRepositoryTransition",
|
||||
"source": "2",
|
||||
"target": "3",
|
||||
"event": "E2"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,32 @@
|
||||
[
|
||||
{
|
||||
"@id": "1",
|
||||
"_class": "org.springframework.statemachine.data.mongodb.MongoDbRepositoryState",
|
||||
"initial": true,
|
||||
"state": "S1"
|
||||
},
|
||||
{
|
||||
"@id": "2",
|
||||
"_class": "org.springframework.statemachine.data.mongodb.MongoDbRepositoryState",
|
||||
"initial": false,
|
||||
"state": "S2"
|
||||
},
|
||||
{
|
||||
"@id": "3",
|
||||
"_class": "org.springframework.statemachine.data.mongodb.MongoDbRepositoryState",
|
||||
"initial": false,
|
||||
"state": "S3"
|
||||
},
|
||||
{
|
||||
"_class": "org.springframework.statemachine.data.mongodb.MongoDbRepositoryTransition",
|
||||
"source": "1",
|
||||
"target": "2",
|
||||
"event": "E1"
|
||||
},
|
||||
{
|
||||
"_class": "org.springframework.statemachine.data.mongodb.MongoDbRepositoryTransition",
|
||||
"source": "2",
|
||||
"target": "3",
|
||||
"event": "E2"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,32 @@
|
||||
[
|
||||
{
|
||||
"@id": "1",
|
||||
"_class": "org.springframework.statemachine.data.redis.RedisRepositoryState",
|
||||
"initial": true,
|
||||
"state": "S1"
|
||||
},
|
||||
{
|
||||
"@id": "2",
|
||||
"_class": "org.springframework.statemachine.data.redis.RedisRepositoryState",
|
||||
"initial": false,
|
||||
"state": "S2"
|
||||
},
|
||||
{
|
||||
"@id": "3",
|
||||
"_class": "org.springframework.statemachine.data.redis.RedisRepositoryState",
|
||||
"initial": false,
|
||||
"state": "S3"
|
||||
},
|
||||
{
|
||||
"_class": "org.springframework.statemachine.data.redis.RedisRepositoryTransition",
|
||||
"source": "1",
|
||||
"target": "2",
|
||||
"event": "E1"
|
||||
},
|
||||
{
|
||||
"_class": "org.springframework.statemachine.data.redis.RedisRepositoryTransition",
|
||||
"source": "2",
|
||||
"target": "3",
|
||||
"event": "E2"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
|
||||
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:style="http://www.eclipse.org/papyrus/infra/viewpoints/policy/style" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_CvKPUK5kEeasH9qRmhZPUw" type="PapyrusUMLStateMachineDiagram" name="StateMachine Diagram" measurementUnit="Pixel">
|
||||
<children xmi:type="notation:Shape" xmi:id="_CvKPUa5kEeasH9qRmhZPUw" type="2000">
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_CvKPUq5kEeasH9qRmhZPUw" type="2001">
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_CvKPU65kEeasH9qRmhZPUw" width="700" height="23"/>
|
||||
</children>
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_CvKPVK5kEeasH9qRmhZPUw" type="2002">
|
||||
<children xmi:type="notation:Shape" xmi:id="_CvKPVa5kEeasH9qRmhZPUw" type="3000">
|
||||
<eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_CvKPVq5kEeasH9qRmhZPUw" source="RegionAnnotationKey">
|
||||
<details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_CvKPV65kEeasH9qRmhZPUw" key="RegionZoneKey" value=""/>
|
||||
</eAnnotations>
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_CvKPWK5kEeasH9qRmhZPUw" type="3002">
|
||||
<children xmi:type="notation:Shape" xmi:id="_FD55IK5kEeasH9qRmhZPUw" type="6000">
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_FD55Iq5kEeasH9qRmhZPUw" type="6001"/>
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_FD55I65kEeasH9qRmhZPUw" type="19003">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_FD55JK5kEeasH9qRmhZPUw" x="40"/>
|
||||
</children>
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_FD55Ja5kEeasH9qRmhZPUw" type="6002">
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_FD55Jq5kEeasH9qRmhZPUw"/>
|
||||
</children>
|
||||
<element xmi:type="uml:State" href="SimpleMachine.uml#_FD210K5kEeasH9qRmhZPUw"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_FD55Ia5kEeasH9qRmhZPUw" x="137" y="49"/>
|
||||
</children>
|
||||
<children xmi:type="notation:Shape" xmi:id="_GKnpkK5kEeasH9qRmhZPUw" type="6000">
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_GKoQoK5kEeasH9qRmhZPUw" type="6001"/>
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_GKoQoa5kEeasH9qRmhZPUw" type="19003">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_GKoQoq5kEeasH9qRmhZPUw" x="40"/>
|
||||
</children>
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_GKoQo65kEeasH9qRmhZPUw" type="6002">
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_GKoQpK5kEeasH9qRmhZPUw"/>
|
||||
</children>
|
||||
<element xmi:type="uml:State" href="SimpleMachine.uml#_GKkmQK5kEeasH9qRmhZPUw"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_GKnpka5kEeasH9qRmhZPUw" x="272" y="49"/>
|
||||
</children>
|
||||
<children xmi:type="notation:Shape" xmi:id="_G5KxoK5kEeasH9qRmhZPUw" type="6000">
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_G5Kxoq5kEeasH9qRmhZPUw" type="6001"/>
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_G5Kxo65kEeasH9qRmhZPUw" type="19003">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_G5KxpK5kEeasH9qRmhZPUw" x="40"/>
|
||||
</children>
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_G5Kxpa5kEeasH9qRmhZPUw" type="6002">
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_G5Kxpq5kEeasH9qRmhZPUw"/>
|
||||
</children>
|
||||
<element xmi:type="uml:State" href="SimpleMachine.uml#_G5GgMK5kEeasH9qRmhZPUw"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_G5Kxoa5kEeasH9qRmhZPUw" x="409" y="49"/>
|
||||
</children>
|
||||
<children xmi:type="notation:Shape" xmi:id="_KqSS0K5kEeasH9qRmhZPUw" type="8000">
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_KqSS0q5kEeasH9qRmhZPUw" type="8001">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_KqSS065kEeasH9qRmhZPUw" x="25" y="3"/>
|
||||
</children>
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_KqSS1K5kEeasH9qRmhZPUw" type="8002">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_KqSS1a5kEeasH9qRmhZPUw" x="25" y="-10"/>
|
||||
</children>
|
||||
<element xmi:type="uml:Pseudostate" href="SimpleMachine.uml#_KqMzQK5kEeasH9qRmhZPUw"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_KqSS0a5kEeasH9qRmhZPUw" x="44" y="61"/>
|
||||
</children>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_CvKPWa5kEeasH9qRmhZPUw"/>
|
||||
</children>
|
||||
<element xmi:type="uml:Region" href="SimpleMachine.uml#_CvJoQK5kEeasH9qRmhZPUw"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_CvKPWq5kEeasH9qRmhZPUw" width="700" height="287"/>
|
||||
</children>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_CvKPW65kEeasH9qRmhZPUw" y="23" width="700" height="287"/>
|
||||
</children>
|
||||
<element xmi:type="uml:StateMachine" href="SimpleMachine.uml#_CvJBMK5kEeasH9qRmhZPUw"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_CvKPXK5kEeasH9qRmhZPUw" x="30" y="30" width="700" height="310"/>
|
||||
</children>
|
||||
<styles xmi:type="notation:StringValueStyle" xmi:id="_CvKPXa5kEeasH9qRmhZPUw" name="diagram_compatibility_version" stringValue="1.1.0"/>
|
||||
<styles xmi:type="notation:DiagramStyle" xmi:id="_CvKPXq5kEeasH9qRmhZPUw"/>
|
||||
<styles xmi:type="style:PapyrusViewStyle" xmi:id="_CvKPX65kEeasH9qRmhZPUw">
|
||||
<owner xmi:type="uml:Model" href="SimpleMachine.uml#_CvHMAK5kEeasH9qRmhZPUw"/>
|
||||
</styles>
|
||||
<element xmi:type="uml:StateMachine" href="SimpleMachine.uml#_CvJBMK5kEeasH9qRmhZPUw"/>
|
||||
<edges xmi:type="notation:Connector" xmi:id="_MIHiwK5kEeasH9qRmhZPUw" type="7000" source="_KqSS0K5kEeasH9qRmhZPUw" target="_FD55IK5kEeasH9qRmhZPUw">
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_MIHiw65kEeasH9qRmhZPUw" type="7001">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_MIHixK5kEeasH9qRmhZPUw"/>
|
||||
</children>
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_MIHixa5kEeasH9qRmhZPUw" type="7002">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_MIHixq5kEeasH9qRmhZPUw"/>
|
||||
</children>
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_MIHix65kEeasH9qRmhZPUw" type="7003">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_MIHiyK5kEeasH9qRmhZPUw" y="60"/>
|
||||
</children>
|
||||
<styles xmi:type="notation:FontStyle" xmi:id="_MIHiwa5kEeasH9qRmhZPUw"/>
|
||||
<element xmi:type="uml:Transition" href="SimpleMachine.uml#_MICDMK5kEeasH9qRmhZPUw"/>
|
||||
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_MIHiwq5kEeasH9qRmhZPUw" points="[8, -2, -78, 0]$[83, -3, -3, -1]"/>
|
||||
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_MIWzUK5kEeasH9qRmhZPUw" id="(1.0,0.4)"/>
|
||||
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_MIWzUa5kEeasH9qRmhZPUw" id="(0.0,0.425531914893617)"/>
|
||||
</edges>
|
||||
<edges xmi:type="notation:Connector" xmi:id="_NPW3oK5kEeasH9qRmhZPUw" type="7000" source="_FD55IK5kEeasH9qRmhZPUw" target="_GKnpkK5kEeasH9qRmhZPUw">
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_NPXesK5kEeasH9qRmhZPUw" type="7001">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_NPXesa5kEeasH9qRmhZPUw"/>
|
||||
</children>
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_NPXesq5kEeasH9qRmhZPUw" type="7002">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_NPXes65kEeasH9qRmhZPUw" x="-2" y="-11"/>
|
||||
</children>
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_NPXetK5kEeasH9qRmhZPUw" type="7003">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_NPXeta5kEeasH9qRmhZPUw" y="60"/>
|
||||
</children>
|
||||
<styles xmi:type="notation:FontStyle" xmi:id="_NPW3oa5kEeasH9qRmhZPUw"/>
|
||||
<element xmi:type="uml:Transition" href="SimpleMachine.uml#_NPQJ8K5kEeasH9qRmhZPUw"/>
|
||||
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_NPW3oq5kEeasH9qRmhZPUw" points="[8, 0, -99, -2]$[103, 1, -4, -1]"/>
|
||||
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_NPn9YK5kEeasH9qRmhZPUw" id="(1.0,0.44680851063829785)"/>
|
||||
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_NPn9Ya5kEeasH9qRmhZPUw" id="(0.0,0.46808510638297873)"/>
|
||||
</edges>
|
||||
<edges xmi:type="notation:Connector" xmi:id="_Nz4hAK5kEeasH9qRmhZPUw" type="7000" source="_GKnpkK5kEeasH9qRmhZPUw" target="_G5KxoK5kEeasH9qRmhZPUw">
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_Nz4hA65kEeasH9qRmhZPUw" type="7001">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_Nz4hBK5kEeasH9qRmhZPUw"/>
|
||||
</children>
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_Nz4hBa5kEeasH9qRmhZPUw" type="7002">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_Nz4hBq5kEeasH9qRmhZPUw" x="-6" y="-13"/>
|
||||
</children>
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_Nz5IEK5kEeasH9qRmhZPUw" type="7003">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_Nz5IEa5kEeasH9qRmhZPUw" y="60"/>
|
||||
</children>
|
||||
<styles xmi:type="notation:FontStyle" xmi:id="_Nz4hAa5kEeasH9qRmhZPUw"/>
|
||||
<element xmi:type="uml:Transition" href="SimpleMachine.uml#_NzwlMK5kEeasH9qRmhZPUw"/>
|
||||
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_Nz4hAq5kEeasH9qRmhZPUw" points="[7, 0, -97, 22]$[144, 13, 40, 35]"/>
|
||||
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_N0MqEK5kEeasH9qRmhZPUw" id="(1.0,0.46808510638297873)"/>
|
||||
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_N0MqEa5kEeasH9qRmhZPUw" id="(0.0,0.46808510638297873)"/>
|
||||
</edges>
|
||||
</notation:Diagram>
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_CvHMAK5kEeasH9qRmhZPUw" name="RootElement">
|
||||
<packagedElement xmi:type="uml:StateMachine" xmi:id="_CvJBMK5kEeasH9qRmhZPUw" name="StateMachine">
|
||||
<region xmi:type="uml:Region" xmi:id="_CvJoQK5kEeasH9qRmhZPUw" name="Region1">
|
||||
<transition xmi:type="uml:Transition" xmi:id="_MICDMK5kEeasH9qRmhZPUw" source="_KqMzQK5kEeasH9qRmhZPUw" target="_FD210K5kEeasH9qRmhZPUw"/>
|
||||
<transition xmi:type="uml:Transition" xmi:id="_NPQJ8K5kEeasH9qRmhZPUw" source="_FD210K5kEeasH9qRmhZPUw" target="_GKkmQK5kEeasH9qRmhZPUw">
|
||||
<trigger xmi:type="uml:Trigger" xmi:id="_jnN1AK5lEeasH9qRmhZPUw" event="_R_K1sK5kEeasH9qRmhZPUw"/>
|
||||
</transition>
|
||||
<transition xmi:type="uml:Transition" xmi:id="_NzwlMK5kEeasH9qRmhZPUw" source="_GKkmQK5kEeasH9qRmhZPUw" target="_G5GgMK5kEeasH9qRmhZPUw">
|
||||
<trigger xmi:type="uml:Trigger" xmi:id="_ldn9AK5lEeasH9qRmhZPUw" event="_UfT3MK5kEeasH9qRmhZPUw"/>
|
||||
</transition>
|
||||
<subvertex xmi:type="uml:State" xmi:id="_FD210K5kEeasH9qRmhZPUw" name="S1"/>
|
||||
<subvertex xmi:type="uml:State" xmi:id="_GKkmQK5kEeasH9qRmhZPUw" name="S2"/>
|
||||
<subvertex xmi:type="uml:State" xmi:id="_G5GgMK5kEeasH9qRmhZPUw" name="S3"/>
|
||||
<subvertex xmi:type="uml:Pseudostate" xmi:id="_KqMzQK5kEeasH9qRmhZPUw" name=""/>
|
||||
</region>
|
||||
</packagedElement>
|
||||
<packagedElement xmi:type="uml:Signal" xmi:id="_O5YwgK5kEeasH9qRmhZPUw" name="E1"/>
|
||||
<packagedElement xmi:type="uml:Signal" xmi:id="_QgSc4K5kEeasH9qRmhZPUw" name="E2"/>
|
||||
<packagedElement xmi:type="uml:SignalEvent" xmi:id="_R_K1sK5kEeasH9qRmhZPUw" name="SignalEventE1" signal="_O5YwgK5kEeasH9qRmhZPUw"/>
|
||||
<packagedElement xmi:type="uml:SignalEvent" xmi:id="_UfT3MK5kEeasH9qRmhZPUw" name="SignalEventE2" signal="_QgSc4K5kEeasH9qRmhZPUw"/>
|
||||
</uml:Model>
|
||||
@@ -121,7 +121,7 @@ public class MongoDbRepositoryState extends RepositoryState {
|
||||
*/
|
||||
public MongoDbRepositoryState(String machineId, MongoDbRepositoryState parentState, String state, boolean initial, Set<MongoDbRepositoryAction> stateActions,
|
||||
Set<MongoDbRepositoryAction> entryActions, Set<MongoDbRepositoryAction> exitActions) {
|
||||
this.machineId = machineId;
|
||||
this.machineId = machineId == null ? "" : machineId;
|
||||
this.parentState = parentState;
|
||||
this.state = state;
|
||||
this.initial = initial;
|
||||
|
||||
@@ -131,7 +131,7 @@ public class RedisRepositoryState extends RepositoryState {
|
||||
*/
|
||||
public RedisRepositoryState(String machineId, RedisRepositoryState parentState, String state, boolean initial, Set<RedisRepositoryAction> stateActions,
|
||||
Set<RedisRepositoryAction> entryActions, Set<RedisRepositoryAction> exitActions) {
|
||||
this.machineId = machineId;
|
||||
this.machineId = machineId == null ? "" : machineId;
|
||||
this.parentState = parentState;
|
||||
this.state = state;
|
||||
this.initial = initial;
|
||||
|
||||
Reference in New Issue
Block a user