From 94f549ec05fbfc1494120eecc005d5a7ac3acbe7 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Fri, 9 Nov 2012 18:31:41 +0400 Subject: [PATCH] fixed PY-7962 Doctest: IndentationError: false positives for tests with empty lines --- .../doctest/PyDocstringLexer.java | 13 +++++---- python/testData/doctests/hasErrors.py | 14 +++++++++ python/testData/doctests/noErrors.py | 14 +++++++++ .../com/jetbrains/python/PyDocstringTest.java | 29 +++++++++++++++++++ 4 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 python/testData/doctests/hasErrors.py create mode 100644 python/testData/doctests/noErrors.py diff --git a/python/src/com/jetbrains/python/documentation/doctest/PyDocstringLexer.java b/python/src/com/jetbrains/python/documentation/doctest/PyDocstringLexer.java index 9f71faa7a211..117113b03822 100644 --- a/python/src/com/jetbrains/python/documentation/doctest/PyDocstringLexer.java +++ b/python/src/com/jetbrains/python/documentation/doctest/PyDocstringLexer.java @@ -42,19 +42,22 @@ public class PyDocstringLexer extends PythonIndentingLexer { indent = 0; while (getBaseTokenType() != null && ourIgnoreSet.contains(getBaseTokenType())) advanceBase(); - while (getBaseTokenType() != null && PyTokenTypes.WHITESPACE.contains(getBaseTokenType())) { + + while (getBaseTokenType() != null && (PyTokenTypes.WHITESPACE_OR_LINEBREAK.contains(getBaseTokenType()) || + ourIgnoreSet.contains(getBaseTokenType()))) { if (getBaseTokenType() == PyTokenTypes.TAB) { indent = ((indent / 8) + 1) * 8; } else if (getBaseTokenType() == PyTokenTypes.SPACE) { indent++; } + else if (getBaseTokenType() == PyTokenTypes.LINE_BREAK) { + indent = 0; + super.getNextLineIndent(); + } + advanceBase(); } - if (getBaseTokenType() == PyTokenTypes.LINE_BREAK) { - advanceBase(); - return 0; - } if (getBaseTokenType() == null) { return 0; diff --git a/python/testData/doctests/hasErrors.py b/python/testData/doctests/hasErrors.py new file mode 100644 index 000000000000..f05d0e69d788 --- /dev/null +++ b/python/testData/doctests/hasErrors.py @@ -0,0 +1,14 @@ + +def foo3(x): + ''' + >>> class User(Base): + ... __tablename__ = 'users' + ... + ... id = Column(Integer, primary_key=True) + ... name = Column(String) + ... fullname = Column(String) + ... + ... password = Column(String) + ''' + pass + diff --git a/python/testData/doctests/noErrors.py b/python/testData/doctests/noErrors.py new file mode 100644 index 000000000000..db664a15deea --- /dev/null +++ b/python/testData/doctests/noErrors.py @@ -0,0 +1,14 @@ + +def foo3(x): + ''' + >>> class User(Base): + ... __tablename__ = 'users' + ... + ... id = Column(Integer, primary_key=True) + ... name = Column(String) + ... fullname = Column(String) + ... + ... password = Column(String) + ''' + pass + diff --git a/python/testSrc/com/jetbrains/python/PyDocstringTest.java b/python/testSrc/com/jetbrains/python/PyDocstringTest.java index 5b80b66dbf31..5d5562741be8 100644 --- a/python/testSrc/com/jetbrains/python/PyDocstringTest.java +++ b/python/testSrc/com/jetbrains/python/PyDocstringTest.java @@ -1,9 +1,17 @@ package com.jetbrains.python; +import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.lexer.Lexer; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiLanguageInjectionHost; +import com.intellij.psi.util.PsiTreeUtil; import com.jetbrains.python.documentation.doctest.PyDocstringParserDefinition; import com.jetbrains.python.fixtures.PyTestCase; +import java.util.List; + /** * User: ktisha */ @@ -46,6 +54,27 @@ public class PyDocstringTest extends PyTestCase { return testName + ".expected.docstring"; } + public void testNoErrors() { + doTestIndentation(false); + } + + public void testHasErrors() { + doTestIndentation(true); + } + + private void doTestIndentation(boolean hasErrors) { + String inputDataFileName = getTestName(true) + ".py"; + myFixture.configureByFile(inputDataFileName); + final InjectedLanguageManager languageManager = InjectedLanguageManager.getInstance(myFixture.getProject()); + final PsiLanguageInjectionHost host = languageManager.getInjectionHost(myFixture.getElementAtCaret()); + assertNotNull(host); + final List> files = languageManager.getInjectedPsiFiles(host); + assertNotNull(files); + for (Pair pair : files) { + assertEquals(hasErrors, PsiTreeUtil.hasErrorElements(pair.getFirst())); + } + } + private void doTestLexer(final String text, String... expectedTokens) { Lexer lexer = new PyDocstringParserDefinition().createLexer(myFixture.getProject());