1 package com.jetbrains.edu.coursecreator;
3 import com.intellij.openapi.application.ApplicationManager;
4 import com.intellij.openapi.application.Result;
5 import com.intellij.openapi.command.WriteCommandAction;
6 import com.intellij.openapi.diagnostic.Logger;
7 import com.intellij.openapi.editor.Document;
8 import com.intellij.openapi.editor.EditorFactory;
9 import com.intellij.openapi.editor.markup.MarkupModel;
10 import com.intellij.openapi.editor.markup.RangeHighlighter;
11 import com.intellij.openapi.fileEditor.FileDocumentManager;
12 import com.intellij.openapi.util.Pair;
13 import com.intellij.openapi.util.TextRange;
14 import com.intellij.openapi.util.io.FileUtil;
15 import com.intellij.openapi.vfs.LocalFileSystem;
16 import com.intellij.openapi.vfs.VirtualFile;
17 import com.intellij.testFramework.EditorTestUtil;
18 import com.intellij.testFramework.fixtures.CodeInsightFixtureTestCase;
19 import com.jetbrains.edu.learning.StudyTaskManager;
20 import com.jetbrains.edu.learning.StudyUtils;
21 import com.jetbrains.edu.learning.courseFormat.*;
22 import org.jetbrains.annotations.NotNull;
23 import org.jetbrains.annotations.Nullable;
24 import org.junit.ComparisonFailure;
26 import java.io.IOException;
27 import java.util.ArrayList;
28 import java.util.List;
29 import java.util.regex.Matcher;
30 import java.util.regex.Pattern;
32 public abstract class CCTestCase extends CodeInsightFixtureTestCase {
33 private static final Logger LOG = Logger.getInstance(CCTestCase.class);
36 public static RangeHighlighter getHighlighter(MarkupModel model, AnswerPlaceholder placeholder) {
37 for (RangeHighlighter highlighter : model.getAllHighlighters()) {
38 int endOffset = placeholder.getOffset() + placeholder.getRealLength();
39 if (highlighter.getStartOffset() == placeholder.getOffset() && highlighter.getEndOffset() == endOffset) {
46 protected static void checkHighlighters(TaskFile taskFile, MarkupModel markupModel) {
47 for (AnswerPlaceholder answerPlaceholder : taskFile.getAnswerPlaceholders()) {
48 if (getHighlighter(markupModel, answerPlaceholder) == null) {
49 throw new AssertionError("No highlighter for placeholder: " + CCTestsUtil.getPlaceholderPresentation(answerPlaceholder));
54 public void checkByFile(TaskFile taskFile, String fileName, boolean useLength) {
55 Pair<Document, List<AnswerPlaceholder>> placeholders = getPlaceholders(fileName, useLength, true);
56 String message = "Placeholders don't match";
57 if (taskFile.getAnswerPlaceholders().size() != placeholders.second.size()) {
58 throw new ComparisonFailure(message,
59 CCTestsUtil.getPlaceholdersPresentation(taskFile.getAnswerPlaceholders()),
60 CCTestsUtil.getPlaceholdersPresentation(placeholders.second));
62 for (AnswerPlaceholder answerPlaceholder : placeholders.getSecond()) {
63 AnswerPlaceholder placeholder = taskFile.getAnswerPlaceholder(answerPlaceholder.getOffset());
64 if (!CCTestsUtil.comparePlaceholders(placeholder, answerPlaceholder)) {
65 throw new ComparisonFailure(message,
66 CCTestsUtil.getPlaceholdersPresentation(taskFile.getAnswerPlaceholders()),
67 CCTestsUtil.getPlaceholdersPresentation(placeholders.second));
73 protected String getBasePath() {
74 return "/community/python/educational-core/course-creator/testData";
78 protected void setUp() throws Exception {
80 Course course = new Course();
81 course.setName("test course");
82 course.setCourseDirectory(getProject().getBasePath());
83 StudyTaskManager.getInstance(getProject()).setCourse(course);
85 Lesson lesson = new Lesson();
86 lesson.setName("lesson1");
87 Task task = new Task();
88 task.setName("task1");
92 course.getLessons().add(lesson);
93 course.setCourseMode(CCUtils.COURSE_MODE);
94 course.initCourse(false);
95 ApplicationManager.getApplication().runWriteAction(new Runnable() {
99 VirtualFile lesson1 = myFixture.getProject().getBaseDir().createChildDirectory(this, "lesson1");
100 lesson1.createChildDirectory(this, "task1");
102 catch (IOException e) {
109 protected VirtualFile configureByTaskFile(String name) {
110 Task task = StudyTaskManager.getInstance(getProject()).getCourse().getLessons().get(0).getTaskList().get(0);
111 TaskFile taskFile = new TaskFile();
112 taskFile.setTask(task);
113 task.getTaskFiles().put(name, taskFile);
115 myFixture.copyFileToProject(name, FileUtil.join(getProject().getBasePath(), "lesson1", "task1", name));
116 myFixture.configureFromExistingVirtualFile(file);
117 Document document = FileDocumentManager.getInstance().getDocument(file);
118 for (AnswerPlaceholder placeholder : getPlaceholders(document, false)) {
119 taskFile.addAnswerPlaceholder(placeholder);
121 taskFile.sortAnswerPlaceholders();
122 StudyUtils.drawAllWindows(myFixture.getEditor(), taskFile);
123 CCUtils.createResourceFile(file, StudyTaskManager.getInstance(getProject()).getCourse(), file.getParent());
127 private static List<AnswerPlaceholder> getPlaceholders(Document document, boolean useLength) {
128 final List<AnswerPlaceholder> placeholders = new ArrayList<>();
129 new WriteCommandAction(null) {
131 protected void run(@NotNull Result result) {
132 final String openingTagRx = "<placeholder( taskText=\"(.+?)\")?( possibleAnswer=\"(.+?)\")?( hint=\"(.+?)\")?>";
133 final String closingTagRx = "</placeholder>";
134 CharSequence text = document.getCharsSequence();
135 final Matcher openingMatcher = Pattern.compile(openingTagRx).matcher(text);
136 final Matcher closingMatcher = Pattern.compile(closingTagRx).matcher(text);
138 while (openingMatcher.find(pos)) {
139 AnswerPlaceholder answerPlaceholder = new AnswerPlaceholder();
140 answerPlaceholder.setUseLength(useLength);
141 String taskText = openingMatcher.group(2);
142 if (taskText != null) {
143 answerPlaceholder.setTaskText(taskText);
144 answerPlaceholder.setLength(taskText.length());
146 String possibleAnswer = openingMatcher.group(4);
147 if (possibleAnswer != null) {
148 answerPlaceholder.setPossibleAnswer(possibleAnswer);
150 String hint = openingMatcher.group(6);
152 answerPlaceholder.setHint(hint);
154 answerPlaceholder.setOffset(openingMatcher.start());
155 if (!closingMatcher.find(openingMatcher.end())) {
156 LOG.error("No matching closing tag found");
159 answerPlaceholder.setLength(closingMatcher.start() - openingMatcher.end());
161 if (possibleAnswer == null) {
162 answerPlaceholder.setPossibleAnswer(document.getText(TextRange.create(openingMatcher.end(), closingMatcher.start())));
165 document.deleteString(closingMatcher.start(), closingMatcher.end());
166 document.deleteString(openingMatcher.start(), openingMatcher.end());
167 placeholders.add(answerPlaceholder);
168 pos = answerPlaceholder.getOffset() + answerPlaceholder.getRealLength();
175 public Pair<Document, List<AnswerPlaceholder>> getPlaceholders(String name) {
176 return getPlaceholders(name, true, false);
179 public Pair<Document, List<AnswerPlaceholder>> getPlaceholders(String name, boolean useLength, boolean removeMarkers) {
180 VirtualFile resultFile = LocalFileSystem.getInstance().findFileByPath(getTestDataPath() + "/" + name);
181 Document document = FileDocumentManager.getInstance().getDocument(resultFile);
182 Document tempDocument = EditorFactory.getInstance().createDocument(document.getCharsSequence());
184 EditorTestUtil.extractCaretAndSelectionMarkers(tempDocument);
186 List<AnswerPlaceholder> placeholders = getPlaceholders(tempDocument, useLength);
187 return Pair.create(tempDocument, placeholders);