From b0d7a9757866f5587ef245fee05a9a3474620be8 Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Fri, 6 Nov 2015 16:20:28 +0100 Subject: [PATCH 1/8] Add a test for source files with CRLF lin endings (failing) --- test/test_chordpro/test_parser.py | 38 +++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/test/test_chordpro/test_parser.py b/test/test_chordpro/test_parser.py index f0e94290..fd30a9b3 100644 --- a/test/test_chordpro/test_parser.py +++ b/test/test_chordpro/test_parser.py @@ -60,6 +60,12 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): "test_{}_{}".format(os.path.basename(base), dest), cls._create_test(base, dest), ) + if os.path.basename(base) == 'newline': + yield ( + "test_crlf_{}_{}".format(os.path.basename(base), dest), + cls._create_crlf_test(base, dest), + ) + @classmethod def _create_test(cls, base, dest): @@ -86,3 +92,35 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): ).format(base=os.path.basename(base), format=dest) return test_parse_render + @classmethod + def _create_crlf_test(cls, base, dest): + """Transform the `base` line endings into CRLF and test the compilation. + """ + + def test_parse_render(self): + """Test that `base` is correctly parsed and rendered when line endings are CRLF. + """ + if base is None or dest is None: + return + originalname = "{}.source".format(base) + chordproname = "{}.crlf.source".format(base) + with open_read(originalname) as originalfile: + with open(chordproname, 'w') as chordprofile: + for line in originalfile: + chordprofile.write(line.replace('\n', '\r\n')) + destname = "{}.{}".format(base, dest) + with open_read(destname) as expectfile: + with disable_logging(): + self.assertMultiLineEqual( + self.song_plugins[LANGUAGES[dest]]['sgc'](chordproname, self.config).render( + output=chordproname, + ).strip(), + expectfile.read().strip(), + ) + os.remove(chordproname) + + test_parse_render.__doc__ = ( + "Test that '{base}' is correctly parsed and rendererd into '{format}' format with CRLF." + ).format(base=os.path.basename(base), format=dest) + return test_parse_render + From e981c70bc6b202bb36451ed337a62ff91372cbdd Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Fri, 6 Nov 2015 10:35:27 +0100 Subject: [PATCH 2/8] Support CRLF, LF and CR line endings --- patacrep/songs/chordpro/lexer.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/patacrep/songs/chordpro/lexer.py b/patacrep/songs/chordpro/lexer.py index a0b57826..9554f8bf 100644 --- a/patacrep/songs/chordpro/lexer.py +++ b/patacrep/songs/chordpro/lexer.py @@ -80,8 +80,8 @@ class ChordProLexer: r'[ \t]+' return token - t_tablature_TEXT = r'[^\n]+' - t_tablature_ENDOFLINE = r'\n' + t_tablature_TEXT = r'[^\n\r]+' + t_tablature_ENDOFLINE = r'(\r\n)|\r|\n' def __init__(self, *, filename=None): self.__class__.lexer = lex.lex(module=self) @@ -90,7 +90,7 @@ class ChordProLexer: # Define a rule so we can track line numbers @staticmethod def t_ENDOFLINE(token): - r'[\n\r]' + r'(\r\n)|\r|\n' token.lexer.lineno += 1 return token @@ -101,7 +101,7 @@ class ChordProLexer: @staticmethod def t_WORD(token): - r'[^{}\n\][\t ]+' + r'[^{}\r\n\][\t ]+' return token def t_LBRACKET(self, __token): From 2468f2f094ab1807dfaf26d7c868d0f553acafc8 Mon Sep 17 00:00:00 2001 From: Louis Date: Fri, 6 Nov 2015 19:55:25 +0100 Subject: [PATCH 3/8] [test] Create a test with CLRF endings --- test/test_chordpro/clrf.html | 43 ++++++++++++++++++++++ test/test_chordpro/clrf.sgc | 41 +++++++++++++++++++++ test/test_chordpro/clrf.source | 32 ++++++++++++++++ test/test_chordpro/clrf.tex | 61 +++++++++++++++++++++++++++++++ test/test_chordpro/test_parser.py | 39 -------------------- 5 files changed, 177 insertions(+), 39 deletions(-) create mode 100644 test/test_chordpro/clrf.html create mode 100644 test/test_chordpro/clrf.sgc create mode 100644 test/test_chordpro/clrf.source create mode 100644 test/test_chordpro/clrf.tex diff --git a/test/test_chordpro/clrf.html b/test/test_chordpro/clrf.html new file mode 100644 index 00000000..5540af64 --- /dev/null +++ b/test/test_chordpro/clrf.html @@ -0,0 +1,43 @@ + +Lang: en
+ + + +
+

This is a verse
+With a new line
+
+The second part of the verse
+Is this line +

+ +

Here is a new line at the end
+ +

+ +

Foo bar +

+ +


+And a new line
+At the beginning +

+ +

New lines can also
+
+Be in chorus +

+ +

New lines can also
+
+Be in bridges +

+ +

New lines can also
+
+Be surrounded by spaces +

+ +

New lines cannot +

+
\ No newline at end of file diff --git a/test/test_chordpro/clrf.sgc b/test/test_chordpro/clrf.sgc new file mode 100644 index 00000000..e9bf0c62 --- /dev/null +++ b/test/test_chordpro/clrf.sgc @@ -0,0 +1,41 @@ +{lang: en} + +This is a verse +With a new line +{newline} +The second part of the verse +Is this line + + +Here is a new line at the end +{newline} + + +Foo bar + + +{newline} +And a new line +At the beginning + + +{start_of_chorus} + New lines can also + {newline} + Be in chorus +{end_of_chorus} + + +{start_of_bridge} + New lines can also + {newline} + Be in bridges +{end_of_bridge} + + +New lines can also +{newline} +Be surrounded by spaces + + +New lines cannot diff --git a/test/test_chordpro/clrf.source b/test/test_chordpro/clrf.source new file mode 100644 index 00000000..484df519 --- /dev/null +++ b/test/test_chordpro/clrf.source @@ -0,0 +1,32 @@ +This is a verse +With a new line +{newline} +The second part of the verse +Is this line + +Here is a new line at the end +{newline} + +Foo bar + +{newline} +And a new line +At the beginning + +{soc} +New lines can also +{newline} +Be in chorus +{eoc} + +{sob} +New lines can also +{newline} +Be in bridges +{eob} + +New lines can also + {newline} +Be surrounded by spaces + +New lines cannot {newline} appear in the middle of a line diff --git a/test/test_chordpro/clrf.tex b/test/test_chordpro/clrf.tex new file mode 100644 index 00000000..d557de5f --- /dev/null +++ b/test/test_chordpro/clrf.tex @@ -0,0 +1,61 @@ +\selectlanguage{english} + +\beginsong{}[ + by={ + }, +] + + +\begin{verse} + This is a verse + With a new line + ~\\ + The second part of the verse + Is this line +\end{verse} + + +\begin{verse} + Here is a new line at the end + ~\\ +\end{verse} + + +\begin{verse} + Foo bar +\end{verse} + + +\begin{verse} + ~\\ + And a new line + At the beginning +\end{verse} + + +\begin{chorus} + New lines can also + ~\\ + Be in chorus +\end{chorus} + + +\begin{bridge} + New lines can also + ~\\ + Be in bridges +\end{bridge} + + +\begin{verse} + New lines can also + ~\\ + Be surrounded by spaces +\end{verse} + + +\begin{verse} + New lines cannot +\end{verse} + +\endsong diff --git a/test/test_chordpro/test_parser.py b/test/test_chordpro/test_parser.py index fd30a9b3..3f0c652e 100644 --- a/test/test_chordpro/test_parser.py +++ b/test/test_chordpro/test_parser.py @@ -60,12 +60,6 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): "test_{}_{}".format(os.path.basename(base), dest), cls._create_test(base, dest), ) - if os.path.basename(base) == 'newline': - yield ( - "test_crlf_{}_{}".format(os.path.basename(base), dest), - cls._create_crlf_test(base, dest), - ) - @classmethod def _create_test(cls, base, dest): @@ -91,36 +85,3 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): "Test that '{base}' is correctly parsed and rendererd into '{format}' format." ).format(base=os.path.basename(base), format=dest) return test_parse_render - - @classmethod - def _create_crlf_test(cls, base, dest): - """Transform the `base` line endings into CRLF and test the compilation. - """ - - def test_parse_render(self): - """Test that `base` is correctly parsed and rendered when line endings are CRLF. - """ - if base is None or dest is None: - return - originalname = "{}.source".format(base) - chordproname = "{}.crlf.source".format(base) - with open_read(originalname) as originalfile: - with open(chordproname, 'w') as chordprofile: - for line in originalfile: - chordprofile.write(line.replace('\n', '\r\n')) - destname = "{}.{}".format(base, dest) - with open_read(destname) as expectfile: - with disable_logging(): - self.assertMultiLineEqual( - self.song_plugins[LANGUAGES[dest]]['sgc'](chordproname, self.config).render( - output=chordproname, - ).strip(), - expectfile.read().strip(), - ) - os.remove(chordproname) - - test_parse_render.__doc__ = ( - "Test that '{base}' is correctly parsed and rendererd into '{format}' format with CRLF." - ).format(base=os.path.basename(base), format=dest) - return test_parse_render - From 837ce8e3b1c3185ff6923b300d243c148c3f4153 Mon Sep 17 00:00:00 2001 From: Louis Date: Sat, 7 Nov 2015 04:49:50 +0100 Subject: [PATCH 4/8] Revert "[test] Create a test with CLRF endings" This reverts commit 2468f2f094ab1807dfaf26d7c868d0f553acafc8. --- test/test_chordpro/clrf.html | 43 ---------------------- test/test_chordpro/clrf.sgc | 41 --------------------- test/test_chordpro/clrf.source | 32 ---------------- test/test_chordpro/clrf.tex | 61 ------------------------------- test/test_chordpro/test_parser.py | 39 ++++++++++++++++++++ 5 files changed, 39 insertions(+), 177 deletions(-) delete mode 100644 test/test_chordpro/clrf.html delete mode 100644 test/test_chordpro/clrf.sgc delete mode 100644 test/test_chordpro/clrf.source delete mode 100644 test/test_chordpro/clrf.tex diff --git a/test/test_chordpro/clrf.html b/test/test_chordpro/clrf.html deleted file mode 100644 index 5540af64..00000000 --- a/test/test_chordpro/clrf.html +++ /dev/null @@ -1,43 +0,0 @@ - -Lang: en
- - - -
-

This is a verse
-With a new line
-
-The second part of the verse
-Is this line -

- -

Here is a new line at the end
- -

- -

Foo bar -

- -


-And a new line
-At the beginning -

- -

New lines can also
-
-Be in chorus -

- -

New lines can also
-
-Be in bridges -

- -

New lines can also
-
-Be surrounded by spaces -

- -

New lines cannot -

-
\ No newline at end of file diff --git a/test/test_chordpro/clrf.sgc b/test/test_chordpro/clrf.sgc deleted file mode 100644 index e9bf0c62..00000000 --- a/test/test_chordpro/clrf.sgc +++ /dev/null @@ -1,41 +0,0 @@ -{lang: en} - -This is a verse -With a new line -{newline} -The second part of the verse -Is this line - - -Here is a new line at the end -{newline} - - -Foo bar - - -{newline} -And a new line -At the beginning - - -{start_of_chorus} - New lines can also - {newline} - Be in chorus -{end_of_chorus} - - -{start_of_bridge} - New lines can also - {newline} - Be in bridges -{end_of_bridge} - - -New lines can also -{newline} -Be surrounded by spaces - - -New lines cannot diff --git a/test/test_chordpro/clrf.source b/test/test_chordpro/clrf.source deleted file mode 100644 index 484df519..00000000 --- a/test/test_chordpro/clrf.source +++ /dev/null @@ -1,32 +0,0 @@ -This is a verse -With a new line -{newline} -The second part of the verse -Is this line - -Here is a new line at the end -{newline} - -Foo bar - -{newline} -And a new line -At the beginning - -{soc} -New lines can also -{newline} -Be in chorus -{eoc} - -{sob} -New lines can also -{newline} -Be in bridges -{eob} - -New lines can also - {newline} -Be surrounded by spaces - -New lines cannot {newline} appear in the middle of a line diff --git a/test/test_chordpro/clrf.tex b/test/test_chordpro/clrf.tex deleted file mode 100644 index d557de5f..00000000 --- a/test/test_chordpro/clrf.tex +++ /dev/null @@ -1,61 +0,0 @@ -\selectlanguage{english} - -\beginsong{}[ - by={ - }, -] - - -\begin{verse} - This is a verse - With a new line - ~\\ - The second part of the verse - Is this line -\end{verse} - - -\begin{verse} - Here is a new line at the end - ~\\ -\end{verse} - - -\begin{verse} - Foo bar -\end{verse} - - -\begin{verse} - ~\\ - And a new line - At the beginning -\end{verse} - - -\begin{chorus} - New lines can also - ~\\ - Be in chorus -\end{chorus} - - -\begin{bridge} - New lines can also - ~\\ - Be in bridges -\end{bridge} - - -\begin{verse} - New lines can also - ~\\ - Be surrounded by spaces -\end{verse} - - -\begin{verse} - New lines cannot -\end{verse} - -\endsong diff --git a/test/test_chordpro/test_parser.py b/test/test_chordpro/test_parser.py index 3f0c652e..fd30a9b3 100644 --- a/test/test_chordpro/test_parser.py +++ b/test/test_chordpro/test_parser.py @@ -60,6 +60,12 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): "test_{}_{}".format(os.path.basename(base), dest), cls._create_test(base, dest), ) + if os.path.basename(base) == 'newline': + yield ( + "test_crlf_{}_{}".format(os.path.basename(base), dest), + cls._create_crlf_test(base, dest), + ) + @classmethod def _create_test(cls, base, dest): @@ -85,3 +91,36 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): "Test that '{base}' is correctly parsed and rendererd into '{format}' format." ).format(base=os.path.basename(base), format=dest) return test_parse_render + + @classmethod + def _create_crlf_test(cls, base, dest): + """Transform the `base` line endings into CRLF and test the compilation. + """ + + def test_parse_render(self): + """Test that `base` is correctly parsed and rendered when line endings are CRLF. + """ + if base is None or dest is None: + return + originalname = "{}.source".format(base) + chordproname = "{}.crlf.source".format(base) + with open_read(originalname) as originalfile: + with open(chordproname, 'w') as chordprofile: + for line in originalfile: + chordprofile.write(line.replace('\n', '\r\n')) + destname = "{}.{}".format(base, dest) + with open_read(destname) as expectfile: + with disable_logging(): + self.assertMultiLineEqual( + self.song_plugins[LANGUAGES[dest]]['sgc'](chordproname, self.config).render( + output=chordproname, + ).strip(), + expectfile.read().strip(), + ) + os.remove(chordproname) + + test_parse_render.__doc__ = ( + "Test that '{base}' is correctly parsed and rendererd into '{format}' format with CRLF." + ).format(base=os.path.basename(base), format=dest) + return test_parse_render + From 5cc173fd0bee38a7992e8582fb85c06f9cb527a9 Mon Sep 17 00:00:00 2001 From: Louis Date: Sat, 7 Nov 2015 05:17:32 +0100 Subject: [PATCH 5/8] [WIP][test] Improve clrf test --- test/test_chordpro/test_parser.py | 96 ++++++++++++++----------------- 1 file changed, 42 insertions(+), 54 deletions(-) diff --git a/test/test_chordpro/test_parser.py b/test/test_chordpro/test_parser.py index fd30a9b3..82a02fb6 100644 --- a/test/test_chordpro/test_parser.py +++ b/test/test_chordpro/test_parser.py @@ -2,6 +2,7 @@ # pylint: disable=too-few-public-methods +import contextlib import glob import os import unittest @@ -33,6 +34,28 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): maxDiff = None + @staticmethod + @contextlib.contextmanager + def chdir(): + """Context to temporarry change current directory to this file directory + """ + olddir = os.getcwd() + os.chdir(resource_filename(__name__, "")) + yield + os.chdir(olddir) + + def assertRender(self, destformat, sourcename, destname): # pylint: disable=invalid-name + """Assert that `sourcename` is correctly rendered as `destname` in `destformat`. + """ + with self.chdir(): + with open_read(destname) as expectfile: + with disable_logging(): + song = self.song_plugins[LANGUAGES[destformat]]['sgc'](sourcename, self.config) + self.assertMultiLineEqual( + song.render(output=sourcename).strip(), + expectfile.read().strip(), + ) + @classmethod def _iter_testmethods(cls): """Iterate over song files to test.""" @@ -40,33 +63,25 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): cls.config = DEFAULT_CONFIG if 'datadir' not in cls.config: cls.config['datadir'] = [] - cls.config['datadir'].append(resource_filename(__name__, 'datadir')) + cls.config['datadir'].append('datadir') cls.song_plugins = files.load_plugins( datadirs=cls.config['datadir'], root_modules=['songs'], keyword='SONG_RENDERERS', ) - for source in sorted(glob.glob(os.path.join( - os.path.dirname(__file__), - '*.source', - ))): - base = os.path.relpath(source, os.getcwd())[:-len(".source")] - for dest in LANGUAGES: - destname = "{}.{}".format(base, dest) - if not os.path.exists(destname): - continue - yield ( - "test_{}_{}".format(os.path.basename(base), dest), - cls._create_test(base, dest), - ) - if os.path.basename(base) == 'newline': + with cls.chdir(): + for source in sorted(glob.glob('*.source')): + base = source[:-len(".source")] + for dest in LANGUAGES: + destname = "{}.{}".format(base, dest) + if not os.path.exists(destname): + continue yield ( - "test_crlf_{}_{}".format(os.path.basename(base), dest), - cls._create_crlf_test(base, dest), + "test_{}_{}".format(base, dest), + cls._create_test(base, dest), ) - @classmethod def _create_test(cls, base, dest): """Return a function testing that `base` compilation in `dest` format. @@ -76,51 +91,24 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): """Test that `base` is correctly parsed and rendered.""" if base is None or dest is None: return - destname = "{}.{}".format(base, dest) - with open_read(destname) as expectfile: - chordproname = "{}.source".format(base) - with disable_logging(): - self.assertMultiLineEqual( - self.song_plugins[LANGUAGES[dest]]['sgc'](chordproname, self.config).render( - output=chordproname, - ).strip(), - expectfile.read().strip(), - ) + self.assertRender(dest, "{}.source".format(base), "{}.{}".format(base, dest)) test_parse_render.__doc__ = ( "Test that '{base}' is correctly parsed and rendererd into '{format}' format." ).format(base=os.path.basename(base), format=dest) return test_parse_render - @classmethod - def _create_crlf_test(cls, base, dest): - """Transform the `base` line endings into CRLF and test the compilation. + def test_clrf(self): + """Test that source is correctly parsed and rendered when line endings are CRLF. """ - - def test_parse_render(self): - """Test that `base` is correctly parsed and rendered when line endings are CRLF. - """ - if base is None or dest is None: - return - originalname = "{}.source".format(base) - chordproname = "{}.crlf.source".format(base) + originalname = "newline.source" + chordproname = "newline.crlf.source" + with self.chdir(): with open_read(originalname) as originalfile: with open(chordproname, 'w') as chordprofile: for line in originalfile: chordprofile.write(line.replace('\n', '\r\n')) - destname = "{}.{}".format(base, dest) - with open_read(destname) as expectfile: - with disable_logging(): - self.assertMultiLineEqual( - self.song_plugins[LANGUAGES[dest]]['sgc'](chordproname, self.config).render( - output=chordproname, - ).strip(), - expectfile.read().strip(), - ) + for dest in LANGUAGES: + with self.subTest(dest): + self.assertRender(dest, chordproname, "newline.{}".format(dest)) os.remove(chordproname) - - test_parse_render.__doc__ = ( - "Test that '{base}' is correctly parsed and rendererd into '{format}' format with CRLF." - ).format(base=os.path.basename(base), format=dest) - return test_parse_render - From 2788405285c66739a71f22da8f967945a205f8bb Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Sat, 7 Nov 2015 09:57:46 +0100 Subject: [PATCH 6/8] Correct render path --- test/test_chordpro/metadata.tex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/test_chordpro/metadata.tex b/test/test_chordpro/metadata.tex index 0be273f1..52582de4 100644 --- a/test/test_chordpro/metadata.tex +++ b/test/test_chordpro/metadata.tex @@ -11,7 +11,7 @@ Subtitle5}[ Texte de Jean Richepin, chanté par Georges Brassens }, album={Album}, copyright={Copyright}, - cover={img/test/test_chordpro/metadata_cover}, + cover={img/metadata_cover}, foo={Foo}, ] @@ -19,8 +19,8 @@ Subtitle5}[ \textnote{Comment} \musicnote{GuitarComment} -\lilypond{scores/test/test_chordpro/metadata_lilypond} -\image{img/test/test_chordpro/metadata_image} +\lilypond{scores/metadata_lilypond} +\image{img/metadata_image} From 6330c66483b00dba5b16b0ead8c8724df0400858 Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Sat, 7 Nov 2015 10:37:19 +0100 Subject: [PATCH 7/8] Create .crlf.source file that are overwritten at testing time --- test/test_chordpro/newline.crlf.html | 43 ++++++++++++++++++ test/test_chordpro/newline.crlf.sgc | 41 +++++++++++++++++ test/test_chordpro/newline.crlf.source | 2 + test/test_chordpro/newline.crlf.tex | 61 ++++++++++++++++++++++++++ test/test_chordpro/test_parser.py | 53 +++++++++++++++------- 5 files changed, 184 insertions(+), 16 deletions(-) create mode 100644 test/test_chordpro/newline.crlf.html create mode 100644 test/test_chordpro/newline.crlf.sgc create mode 100644 test/test_chordpro/newline.crlf.source create mode 100644 test/test_chordpro/newline.crlf.tex diff --git a/test/test_chordpro/newline.crlf.html b/test/test_chordpro/newline.crlf.html new file mode 100644 index 00000000..5540af64 --- /dev/null +++ b/test/test_chordpro/newline.crlf.html @@ -0,0 +1,43 @@ + +Lang: en
+ + + +
+

This is a verse
+With a new line
+
+The second part of the verse
+Is this line +

+ +

Here is a new line at the end
+ +

+ +

Foo bar +

+ +


+And a new line
+At the beginning +

+ +

New lines can also
+
+Be in chorus +

+ +

New lines can also
+
+Be in bridges +

+ +

New lines can also
+
+Be surrounded by spaces +

+ +

New lines cannot +

+
\ No newline at end of file diff --git a/test/test_chordpro/newline.crlf.sgc b/test/test_chordpro/newline.crlf.sgc new file mode 100644 index 00000000..e9bf0c62 --- /dev/null +++ b/test/test_chordpro/newline.crlf.sgc @@ -0,0 +1,41 @@ +{lang: en} + +This is a verse +With a new line +{newline} +The second part of the verse +Is this line + + +Here is a new line at the end +{newline} + + +Foo bar + + +{newline} +And a new line +At the beginning + + +{start_of_chorus} + New lines can also + {newline} + Be in chorus +{end_of_chorus} + + +{start_of_bridge} + New lines can also + {newline} + Be in bridges +{end_of_bridge} + + +New lines can also +{newline} +Be surrounded by spaces + + +New lines cannot diff --git a/test/test_chordpro/newline.crlf.source b/test/test_chordpro/newline.crlf.source new file mode 100644 index 00000000..bd45d5ce --- /dev/null +++ b/test/test_chordpro/newline.crlf.source @@ -0,0 +1,2 @@ +# This content will be overwritten with `newline.source` content +# with windows line endings (CRLF) - for testing purposes diff --git a/test/test_chordpro/newline.crlf.tex b/test/test_chordpro/newline.crlf.tex new file mode 100644 index 00000000..d557de5f --- /dev/null +++ b/test/test_chordpro/newline.crlf.tex @@ -0,0 +1,61 @@ +\selectlanguage{english} + +\beginsong{}[ + by={ + }, +] + + +\begin{verse} + This is a verse + With a new line + ~\\ + The second part of the verse + Is this line +\end{verse} + + +\begin{verse} + Here is a new line at the end + ~\\ +\end{verse} + + +\begin{verse} + Foo bar +\end{verse} + + +\begin{verse} + ~\\ + And a new line + At the beginning +\end{verse} + + +\begin{chorus} + New lines can also + ~\\ + Be in chorus +\end{chorus} + + +\begin{bridge} + New lines can also + ~\\ + Be in bridges +\end{bridge} + + +\begin{verse} + New lines can also + ~\\ + Be surrounded by spaces +\end{verse} + + +\begin{verse} + New lines cannot +\end{verse} + +\endsong diff --git a/test/test_chordpro/test_parser.py b/test/test_chordpro/test_parser.py index 82a02fb6..bab1bb9a 100644 --- a/test/test_chordpro/test_parser.py +++ b/test/test_chordpro/test_parser.py @@ -34,6 +34,14 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): maxDiff = None + @classmethod + def setUpClass(cls): + cls._overwrite_clrf() + + @classmethod + def tearDownClass(cls): + cls._reset_clrf() + @staticmethod @contextlib.contextmanager def chdir(): @@ -44,9 +52,11 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): yield os.chdir(olddir) - def assertRender(self, destformat, sourcename, destname): # pylint: disable=invalid-name - """Assert that `sourcename` is correctly rendered as `destname` in `destformat`. + def assertRender(self, base, destformat): # pylint: disable=invalid-name + """Assert that `{base}.source` is correctly rendered in the `destformat`. """ + sourcename = "{}.source".format(base) + destname = "{}.{}".format(base, destformat) with self.chdir(): with open_read(destname) as expectfile: with disable_logging(): @@ -91,24 +101,35 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): """Test that `base` is correctly parsed and rendered.""" if base is None or dest is None: return - self.assertRender(dest, "{}.source".format(base), "{}.{}".format(base, dest)) + self.assertRender(base, dest) test_parse_render.__doc__ = ( "Test that '{base}' is correctly parsed and rendererd into '{format}' format." ).format(base=os.path.basename(base), format=dest) return test_parse_render - def test_clrf(self): - """Test that source is correctly parsed and rendered when line endings are CRLF. + @classmethod + def _overwrite_clrf(cls): + """Overwrite `*.crlf.source` files to force the CRLF line endings. """ - originalname = "newline.source" - chordproname = "newline.crlf.source" - with self.chdir(): - with open_read(originalname) as originalfile: - with open(chordproname, 'w') as chordprofile: - for line in originalfile: - chordprofile.write(line.replace('\n', '\r\n')) - for dest in LANGUAGES: - with self.subTest(dest): - self.assertRender(dest, chordproname, "newline.{}".format(dest)) - os.remove(chordproname) + with cls.chdir(): + for crlfname in sorted(glob.glob('*.crlf.source')): + base = crlfname[:-len(".crlf.source")] + sourcename = base + ".source" + with open_read(sourcename) as sourcefile: + with open(crlfname, 'w') as crlffile: + for line in sourcefile: + crlffile.write(line.replace('\n', '\r\n')) + + @classmethod + def _reset_clrf(cls): + """Reset `*.crlf.source` files. + """ + crlf_msg = """# This content will be overwritten with `{}.source` content +# with windows line endings (CRLF) - for testing purposes +""" + with cls.chdir(): + for crlfname in sorted(glob.glob('*.crlf.source')): + base = crlfname[:-len(".crlf.source")] + with open(crlfname, 'w') as crlffile: + crlffile.write(crlf_msg.format(base)) From e6330c78b37d11344dc04b649f755f2e9a7256b9 Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Sat, 7 Nov 2015 10:57:03 +0100 Subject: [PATCH 8/8] Do not support CR-only line endings (either CRLF or LF) --- patacrep/songs/chordpro/lexer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/patacrep/songs/chordpro/lexer.py b/patacrep/songs/chordpro/lexer.py index 9554f8bf..50048b4c 100644 --- a/patacrep/songs/chordpro/lexer.py +++ b/patacrep/songs/chordpro/lexer.py @@ -81,7 +81,7 @@ class ChordProLexer: return token t_tablature_TEXT = r'[^\n\r]+' - t_tablature_ENDOFLINE = r'(\r\n)|\r|\n' + t_tablature_ENDOFLINE = r'\r?\n' def __init__(self, *, filename=None): self.__class__.lexer = lex.lex(module=self) @@ -90,7 +90,7 @@ class ChordProLexer: # Define a rule so we can track line numbers @staticmethod def t_ENDOFLINE(token): - r'(\r\n)|\r|\n' + r'\r?\n' token.lexer.lineno += 1 return token