added migration to the new version with tasks

This commit is contained in:
Ekaterina Tuzova
2017-03-23 14:28:51 +03:00
parent baa484b2bc
commit ef6a45017b
7 changed files with 697 additions and 5 deletions
@@ -20,6 +20,7 @@ import com.jetbrains.edu.learning.courseFormat.tasks.*;
import com.jetbrains.edu.learning.stepic.EduStepicConnector;
import com.jetbrains.edu.learning.stepic.StepicWrappers;
import org.jdom.Attribute;
import org.jdom.Content;
import org.jdom.Element;
import org.jdom.output.XMLOutputter;
import org.jetbrains.annotations.NotNull;
@@ -95,6 +96,14 @@ public class StudySerializationUtils {
public static final String SELECTED = "selected";
public static final String TASK_TEXT = "taskText";
public static final String PLACEHOLDER_TEXT = "placeholderText";
private static String LAST_SUBTASK_INDEX = "lastSubtaskIndex";
private static String THEORY_TAG = "theoryTask";
private static String ADAPTIVE_TASK_PARAMETERS = "adaptiveTaskParameters";
private static String ADAPTIVE = "adaptive";
private static String TASK_WITH_SUBTASKS = "TaskWithSubtasks";
private static String THEORY_TASK = "TheoryTask";
private static String CHOICE_TASK = "ChoiceTask";
private static String CODE_TASK = "CodeTask";
private Xml() {
}
@@ -246,6 +255,43 @@ public class StudySerializationUtils {
return state;
}
public static Element convertToFifthVersion(Element state) throws StudyUnrecognizedFormatException {
Element taskManagerElement = state.getChild(MAIN_ELEMENT);
Element courseElement = getChildWithName(taskManagerElement, COURSE).getChild(COURSE_TITLED);
final Element adaptive = getChildWithName(courseElement, ADAPTIVE);
for (Element lesson : getChildList(courseElement, LESSONS)) {
for (Element task : getChildList(lesson, TASK_LIST)) {
final Element lastSubtaskIndex = getChildWithName(task, LAST_SUBTASK_INDEX);
final Element theoryTask = getChildWithName(task, THEORY_TAG);
final Element adaptiveParams = getChildWithName(task, ADAPTIVE_TASK_PARAMETERS);
final boolean hasAdaptiveParams = !adaptiveParams.getChildren().isEmpty();
if (Integer.valueOf(lastSubtaskIndex.getAttributeValue(VALUE)) != 0) {
task.setName(TASK_WITH_SUBTASKS);
}
else if (Boolean.valueOf(theoryTask.getAttributeValue(VALUE))) {
task.setName(THEORY_TASK);
}
else if (hasAdaptiveParams) {
task.setName(CHOICE_TASK);
final Element adaptiveParameters = adaptiveParams.getChildren().get(0);
for (Element element : adaptiveParameters.getChildren()) {
final Attribute name = element.getAttribute(NAME);
if (name != null && !THEORY_TAG.equals(name.getValue())) {
final Content elementCopy = element.clone();
task.addContent(elementCopy);
}
}
}
else if (Boolean.valueOf(adaptive.getAttributeValue(VALUE))) {
task.setName(CODE_TASK);
}
task.removeContent(adaptiveParams);
task.removeContent(theoryTask);
}
}
return state;
}
public static String addStatus(XMLOutputter outputter,
Map<String, String> placeholderTextToStatus,
String taskStatus,
@@ -34,9 +34,9 @@ import java.util.Map;
@State(name = "StudySettings", storages = @Storage("study_project.xml"))
public class StudyTaskManager implements PersistentStateComponent<Element>, DumbAware {
private static final Logger LOG = Logger.getInstance(StudyTaskManager.class);
public static final int CURRENT_VERSION = 4;
public static final int CURRENT_VERSION = 5;
private Course myCourse;
public int VERSION = 4;
public int VERSION = 5;
public Map<Task, List<UserTest>> myUserTests = new HashMap<>();
public List<String> myInvisibleFiles = new ArrayList<>();
@@ -140,9 +140,11 @@ public class StudyTaskManager implements PersistentStateComponent<Element>, Dumb
state = StudySerializationUtils.Xml.convertToThirdVersion(state, myProject);
case 3:
state = StudySerializationUtils.Xml.convertToForthVersion(state);
//uncomment for future versions
//case 4:
//state = StudySerializationUtils.Xml.convertToForthVersion(state, myProject);
case 4:
state = StudySerializationUtils.Xml.convertToFifthVersion(state);
//uncomment for future versions
//case 5:
// state = StudySerializationUtils.Xml.convertToSixthVersion(state, myProject);
}
XmlSerializer.deserializeInto(this, state.getChild(StudySerializationUtils.Xml.MAIN_ELEMENT));
VERSION = CURRENT_VERSION;
@@ -0,0 +1,175 @@
<component name="StudySettings">
<StudyTaskManager>
<option name="course">
<Course>
<option name="adaptive" value="true" />
<option name="authors">
<list>
<StepicUser>
<option name="accessToken" />
<option name="email" value="" />
<option name="firstName" value="" />
<option name="id" value="-1" />
<option name="lastName" value="" />
<option name="refreshToken" />
</StepicUser>
</list>
</option>
<option name="courseDirectory" value="$APPLICATION_CONFIG_DIR$/courses/__AdaptivePyCharmPython__test_adaptive_PyCharm_course_2_tuzova.k@gmail.com" />
<option name="courseMode" value="Study" />
<option name="courseType" value="PyCharm" />
<option name="description" value="This is a Stepik Adaptive course.&#10;&#10;Choice-test&#10;&#10;Initially, the adaptive system may behave somewhat randomly, but the more problems you solve, the smarter it become!" />
<option name="id" value="1730" />
<option name="language" value="Python" />
<option name="lessons">
<list>
<Lesson>
<option name="id" value="35738" />
<option name="index" value="1" />
<option name="name" value="Adaptive" />
<option name="updateDate" />
<option name="taskList">
<list>
<Task>
<option name="activeSubtaskIndex" value="0" />
<option name="adaptiveTaskParameters" />
<option name="index" value="1" />
<option name="lastSubtaskIndex" value="0" />
<option name="name" value="Hello world!" />
<option name="status" value="Solved" />
<option name="stepId" value="98994" />
<option name="text" />
<option name="theoryTask" value="false" />
<option name="updateDate" />
<option name="taskFiles">
<map>
<entry key="code.py">
<value>
<TaskFile>
<option name="answerPlaceholders">
<list />
</option>
<option name="highlightErrors" value="true" />
<option name="index" value="0" />
<option name="trackChanges" value="true" />
<option name="trackLengths" value="true" />
<option name="userCreated" value="false" />
<option name="name" value="code" />
<option name="text" value="# put your python code here" />
</TaskFile>
</value>
</entry>
</map>
</option>
</Task>
<Task>
<option name="activeSubtaskIndex" value="0" />
<option name="adaptiveTaskParameters">
<AdaptiveTaskParameters>
<option name="choiceVariants">
<list />
</option>
<option name="multipleChoice" value="false" />
<option name="selectedVariants">
<list />
</option>
<option name="theoryTask" value="true" />
</AdaptiveTaskParameters>
</option>
<option name="index" value="2" />
<option name="lastSubtaskIndex" value="0" />
<option name="name" value="Theory. Input/output" />
<option name="status" value="Solved" />
<option name="stepId" value="131457" />
<option name="text" />
<option name="theoryTask" value="true" />
<option name="updateDate" />
<option name="taskFiles">
<map>
<entry key="code.py">
<value>
<TaskFile>
<option name="answerPlaceholders">
<list />
</option>
<option name="highlightErrors" value="false" />
<option name="index" value="0" />
<option name="trackChanges" value="true" />
<option name="trackLengths" value="true" />
<option name="userCreated" value="false" />
<option name="name" value="code" />
<option name="text" value="# you can experiment here, it won't be checked" />
</TaskFile>
</value>
</entry>
</map>
</option>
</Task>
<Task>
<option name="activeSubtaskIndex" value="0" />
<option name="adaptiveTaskParameters">
<AdaptiveTaskParameters>
<option name="choiceVariants">
<list>
<option value="(2, 1)" />
<option value="It causes TypeError: f() got an unexpected keyword argument" />
<option value="(1, 2)" />
</list>
</option>
<option name="multipleChoice" value="false" />
<option name="selectedVariants">
<list />
</option>
<option name="theoryTask" value="false" />
</AdaptiveTaskParameters>
</option>
<option name="index" value="3" />
<option name="lastSubtaskIndex" value="0" />
<option name="name" value="Small question about functions" />
<option name="status" value="Unchecked" />
<option name="stepId" value="145807" />
<option name="text" value="What does this function return?&lt;div&gt;&lt;br&gt;&lt;div&gt;&lt;pre&gt;&lt;pre&gt;&lt;code&gt;def f(a,b):&lt;br&gt; return a,b&lt;br&gt;&lt;br&gt;f(**{'b':2,'a':1})&lt;/code&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;" />
<option name="theoryTask" value="false" />
<option name="updateDate" />
<option name="taskFiles">
<map>
<entry key="code.py">
<value>
<TaskFile>
<option name="answerPlaceholders">
<list />
</option>
<option name="highlightErrors" value="false" />
<option name="index" value="0" />
<option name="trackChanges" value="true" />
<option name="trackLengths" value="true" />
<option name="userCreated" value="false" />
<option name="name" value="code" />
<option name="text" value="# you can experiment here, it won't be checked" />
</TaskFile>
</value>
</entry>
</map>
</option>
</Task>
</list>
</option>
</Lesson>
</list>
</option>
<option name="name" value="test_adaptive_PyCharm_course_2" />
<option name="updateDate" />
</Course>
</option>
<option name="toolWindowMode" value="TEXT" />
<option name="turnEditingMode" value="false" />
<option name="VERSION" value="4" />
<option name="myUserTests">
<map />
</option>
<option name="myInvisibleFiles">
<list />
</option>
<option name="myShouldUseJavaFx" value="true" />
</StudyTaskManager>
</component>
@@ -0,0 +1,154 @@
<component name="StudySettings">
<StudyTaskManager>
<option name="course">
<Course>
<option name="adaptive" value="true" />
<option name="authors">
<list>
<StepicUser>
<option name="accessToken" />
<option name="email" value="" />
<option name="firstName" value="" />
<option name="id" value="-1" />
<option name="lastName" value="" />
<option name="refreshToken" />
</StepicUser>
</list>
</option>
<option name="courseDirectory" value="$APPLICATION_CONFIG_DIR$/courses/__AdaptivePyCharmPython__test_adaptive_PyCharm_course_2_tuzova.k@gmail.com" />
<option name="courseMode" value="Study" />
<option name="courseType" value="PyCharm" />
<option name="description" value="This is a Stepik Adaptive course.&#10;&#10;Choice-test&#10;&#10;Initially, the adaptive system may behave somewhat randomly, but the more problems you solve, the smarter it become!" />
<option name="id" value="1730" />
<option name="language" value="Python" />
<option name="lessons">
<list>
<Lesson>
<option name="id" value="35738" />
<option name="index" value="1" />
<option name="name" value="Adaptive" />
<option name="updateDate" />
<option name="taskList">
<list>
<CodeTask>
<option name="activeSubtaskIndex" value="0" />
<option name="index" value="1" />
<option name="lastSubtaskIndex" value="0" />
<option name="name" value="Hello world!" />
<option name="status" value="Solved" />
<option name="stepId" value="98994" />
<option name="text" />
<option name="updateDate" />
<option name="taskFiles">
<map>
<entry key="code.py">
<value>
<TaskFile>
<option name="answerPlaceholders">
<list />
</option>
<option name="highlightErrors" value="true" />
<option name="index" value="0" />
<option name="trackChanges" value="true" />
<option name="trackLengths" value="true" />
<option name="userCreated" value="false" />
<option name="name" value="code" />
<option name="text" value="# put your python code here" />
</TaskFile>
</value>
</entry>
</map>
</option>
</CodeTask>
<TheoryTask>
<option name="activeSubtaskIndex" value="0" />
<option name="index" value="2" />
<option name="lastSubtaskIndex" value="0" />
<option name="name" value="Theory. Input/output" />
<option name="status" value="Solved" />
<option name="stepId" value="131457" />
<option name="text" />
<option name="updateDate" />
<option name="taskFiles">
<map>
<entry key="code.py">
<value>
<TaskFile>
<option name="answerPlaceholders">
<list />
</option>
<option name="highlightErrors" value="false" />
<option name="index" value="0" />
<option name="trackChanges" value="true" />
<option name="trackLengths" value="true" />
<option name="userCreated" value="false" />
<option name="name" value="code" />
<option name="text" value="# you can experiment here, it won't be checked" />
</TaskFile>
</value>
</entry>
</map>
</option>
</TheoryTask>
<ChoiceTask>
<option name="activeSubtaskIndex" value="0" />
<option name="index" value="3" />
<option name="lastSubtaskIndex" value="0" />
<option name="name" value="Small question about functions" />
<option name="status" value="Unchecked" />
<option name="stepId" value="145807" />
<option name="text" value="What does this function return?&lt;div&gt;&lt;br&gt;&lt;div&gt;&lt;pre&gt;&lt;pre&gt;&lt;code&gt;def f(a,b):&lt;br&gt; return a,b&lt;br&gt;&lt;br&gt;f(**{'b':2,'a':1})&lt;/code&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;" />
<option name="updateDate" />
<option name="taskFiles">
<map>
<entry key="code.py">
<value>
<TaskFile>
<option name="answerPlaceholders">
<list />
</option>
<option name="highlightErrors" value="false" />
<option name="index" value="0" />
<option name="trackChanges" value="true" />
<option name="trackLengths" value="true" />
<option name="userCreated" value="false" />
<option name="name" value="code" />
<option name="text" value="# you can experiment here, it won't be checked" />
</TaskFile>
</value>
</entry>
</map>
</option>
<option name="choiceVariants">
<list>
<option value="(2, 1)" />
<option value="It causes TypeError: f() got an unexpected keyword argument" />
<option value="(1, 2)" />
</list>
</option>
<option name="multipleChoice" value="false" />
<option name="selectedVariants">
<list />
</option>
</ChoiceTask>
</list>
</option>
</Lesson>
</list>
</option>
<option name="name" value="test_adaptive_PyCharm_course_2" />
<option name="updateDate" />
</Course>
</option>
<option name="toolWindowMode" value="TEXT" />
<option name="turnEditingMode" value="false" />
<option name="VERSION" value="4" />
<option name="myUserTests">
<map />
</option>
<option name="myInvisibleFiles">
<list />
</option>
<option name="myShouldUseJavaFx" value="true" />
</StudyTaskManager>
</component>
@@ -0,0 +1,158 @@
<component name="StudySettings">
<StudyTaskManager>
<option name="course">
<Course>
<option name="adaptive" value="false" />
<option name="authors">
<list>
<StepicUser>
<option name="accessToken" />
<option name="email" value="" />
<option name="firstName" value="ktisha" />
<option name="id" value="-1" />
<option name="lastName" value="" />
<option name="refreshToken" />
</StepicUser>
</list>
</option>
<option name="courseDirectory" value="$APPLICATION_CONFIG_DIR$/courses/1234-untitled" />
<option name="courseMode" value="Course Creator" />
<option name="courseType" value="PyCharm" />
<option name="description" value="qwer" />
<option name="id" value="0" />
<option name="language" value="Python" />
<option name="lessons">
<list>
<Lesson>
<option name="id" value="0" />
<option name="index" value="1" />
<option name="name" value="lesson1" />
<option name="updateDate" />
<option name="taskList">
<list>
<Task>
<option name="activeSubtaskIndex" value="1" />
<option name="adaptiveTaskParameters">
<AdaptiveTaskParameters>
<option name="choiceVariants">
<list />
</option>
<option name="multipleChoice" value="false" />
<option name="selectedVariants">
<list />
</option>
<option name="theoryTask" value="false" />
</AdaptiveTaskParameters>
</option>
<option name="index" value="1" />
<option name="lastSubtaskIndex" value="1" />
<option name="name" value="task1" />
<option name="status" value="Unchecked" />
<option name="stepId" value="0" />
<option name="text" />
<option name="theoryTask" value="false" />
<option name="updateDate" />
<option name="taskFiles">
<map>
<entry key="task.py">
<value>
<TaskFile>
<option name="answerPlaceholders">
<list>
<AnswerPlaceholder>
<option name="index" value="0" />
<option name="initialState" />
<option name="length" value="3" />
<option name="offset" value="7" />
<option name="selected" value="false" />
<option name="subtaskInfos">
<map>
<entry key="0">
<value>
<AnswerPlaceholderSubtaskInfo>
<option name="answer" value="" />
<option name="hasFrame" value="true" />
<option name="hints">
<list>
<option value="hint1" />
</list>
</option>
<option name="needInsertText" value="false" />
<option name="placeholderText" value="123" />
<option name="possibleAnswer" value=" type" />
<option name="selected" value="false" />
<option name="status" value="Unchecked" />
</AnswerPlaceholderSubtaskInfo>
</value>
</entry>
</map>
</option>
<option name="useLength" value="false" />
</AnswerPlaceholder>
<AnswerPlaceholder>
<option name="index" value="1" />
<option name="initialState" />
<option name="length" value="4" />
<option name="offset" value="22" />
<option name="selected" value="false" />
<option name="subtaskInfos">
<map>
<entry key="1">
<value>
<AnswerPlaceholderSubtaskInfo>
<option name="answer" value="" />
<option name="hasFrame" value="true" />
<option name="hints">
<list>
<option value="hint2" />
</list>
</option>
<option name="needInsertText" value="false" />
<option name="placeholderText" value="zxcv" />
<option name="possibleAnswer" value="here" />
<option name="selected" value="false" />
<option name="status" value="Unchecked" />
</AnswerPlaceholderSubtaskInfo>
</value>
</entry>
</map>
</option>
<option name="useLength" value="false" />
</AnswerPlaceholder>
</list>
</option>
<option name="highlightErrors" value="true" />
<option name="index" value="1" />
<option name="trackChanges" value="true" />
<option name="trackLengths" value="true" />
<option name="userCreated" value="false" />
<option name="name" value="task.py" />
<option name="text" />
</TaskFile>
</value>
</entry>
</map>
</option>
</Task>
</list>
</option>
</Lesson>
</list>
</option>
<option name="name" value="1234" />
<option name="updateDate" />
</Course>
</option>
<option name="enableTestingFromSamples" value="false" />
<option name="toolWindowMode" value="TEXT" />
<option name="turnEditingMode" value="false" />
<option name="VERSION" value="4" />
<option name="myUserTests">
<map />
</option>
<option name="myInvisibleFiles">
<list />
</option>
<option name="myShouldUseJavaFx" value="true" />
</StudyTaskManager>
</component>
@@ -0,0 +1,145 @@
<component name="StudySettings">
<StudyTaskManager>
<option name="course">
<Course>
<option name="adaptive" value="false" />
<option name="authors">
<list>
<StepicUser>
<option name="accessToken" />
<option name="email" value="" />
<option name="firstName" value="ktisha" />
<option name="id" value="-1" />
<option name="lastName" value="" />
<option name="refreshToken" />
</StepicUser>
</list>
</option>
<option name="courseDirectory" value="$APPLICATION_CONFIG_DIR$/courses/1234-untitled" />
<option name="courseMode" value="Course Creator" />
<option name="courseType" value="PyCharm" />
<option name="description" value="qwer" />
<option name="id" value="0" />
<option name="language" value="Python" />
<option name="lessons">
<list>
<Lesson>
<option name="id" value="0" />
<option name="index" value="1" />
<option name="name" value="lesson1" />
<option name="updateDate" />
<option name="taskList">
<list>
<TaskWithSubtasks>
<option name="activeSubtaskIndex" value="1" />
<option name="index" value="1" />
<option name="lastSubtaskIndex" value="1" />
<option name="name" value="task1" />
<option name="status" value="Unchecked" />
<option name="stepId" value="0" />
<option name="text" />
<option name="updateDate" />
<option name="taskFiles">
<map>
<entry key="task.py">
<value>
<TaskFile>
<option name="answerPlaceholders">
<list>
<AnswerPlaceholder>
<option name="index" value="0" />
<option name="initialState" />
<option name="length" value="3" />
<option name="offset" value="7" />
<option name="selected" value="false" />
<option name="subtaskInfos">
<map>
<entry key="0">
<value>
<AnswerPlaceholderSubtaskInfo>
<option name="answer" value="" />
<option name="hasFrame" value="true" />
<option name="hints">
<list>
<option value="hint1" />
</list>
</option>
<option name="needInsertText" value="false" />
<option name="placeholderText" value="123" />
<option name="possibleAnswer" value=" type" />
<option name="selected" value="false" />
<option name="status" value="Unchecked" />
</AnswerPlaceholderSubtaskInfo>
</value>
</entry>
</map>
</option>
<option name="useLength" value="false" />
</AnswerPlaceholder>
<AnswerPlaceholder>
<option name="index" value="1" />
<option name="initialState" />
<option name="length" value="4" />
<option name="offset" value="22" />
<option name="selected" value="false" />
<option name="subtaskInfos">
<map>
<entry key="1">
<value>
<AnswerPlaceholderSubtaskInfo>
<option name="answer" value="" />
<option name="hasFrame" value="true" />
<option name="hints">
<list>
<option value="hint2" />
</list>
</option>
<option name="needInsertText" value="false" />
<option name="placeholderText" value="zxcv" />
<option name="possibleAnswer" value="here" />
<option name="selected" value="false" />
<option name="status" value="Unchecked" />
</AnswerPlaceholderSubtaskInfo>
</value>
</entry>
</map>
</option>
<option name="useLength" value="false" />
</AnswerPlaceholder>
</list>
</option>
<option name="highlightErrors" value="true" />
<option name="index" value="1" />
<option name="trackChanges" value="true" />
<option name="trackLengths" value="true" />
<option name="userCreated" value="false" />
<option name="name" value="task.py" />
<option name="text" />
</TaskFile>
</value>
</entry>
</map>
</option>
</TaskWithSubtasks>
</list>
</option>
</Lesson>
</list>
</option>
<option name="name" value="1234" />
<option name="updateDate" />
</Course>
</option>
<option name="enableTestingFromSamples" value="false" />
<option name="toolWindowMode" value="TEXT" />
<option name="turnEditingMode" value="false" />
<option name="VERSION" value="4" />
<option name="myUserTests">
<map />
</option>
<option name="myInvisibleFiles">
<list />
</option>
<option name="myShouldUseJavaFx" value="true" />
</StudyTaskManager>
</component>
@@ -20,6 +20,18 @@ public class StudyMigrationTest {
assertThat(StudySerializationUtils.Xml.convertToForthVersion(element)).isEqualTo(getTestDataPath().resolve("4.xml"));
}
@Test
public void testAdaptive45() throws JDOMException, IOException, StudySerializationUtils.StudyUnrecognizedFormatException {
Element element = JdomKt.loadElement(getTestDataPath().resolve("adaptive4.xml"));
assertThat(StudySerializationUtils.Xml.convertToFifthVersion(element)).isEqualTo(getTestDataPath().resolve("adaptive5.xml"));
}
@Test
public void testSubtasks45() throws JDOMException, IOException, StudySerializationUtils.StudyUnrecognizedFormatException {
Element element = JdomKt.loadElement(getTestDataPath().resolve("subtasks4.xml"));
assertThat(StudySerializationUtils.Xml.convertToFifthVersion(element)).isEqualTo(getTestDataPath().resolve("subtasks5.xml"));
}
@NotNull
protected Path getTestDataPath() {
return Paths.get(PlatformTestUtil.getCommunityPath(), "python/educational-core/student/testData/migration");