Repository: wasilak/yamllint-junit (language: python)

Issue:
Python 3 Comptaibility
Does this only work with Python 2? I tried to install this with `pip3 install yamllint-junit` and got error
```
Collecting yamllint-junit
  Using cached yamllint-junit-0.5.tar.gz (2.0 kB)
    ERROR: Command errored out with exit status 1:
     command: /usr/local/opt/python@3.8/bin/python3.8 -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/private/var/folders/9b/6n0_krj15rs3z6mcjm417dwr0000gn/T/pip-install-h7m_i_6j/yamllint-junit/setup.py'"'"'; __file__='"'"'/private/var/folders/9b/6n0_krj15rs3z6mcjm417dwr0000gn/T/pip-install-h7m_i_6j/yamllint-junit/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /private/var/folders/9b/6n0_krj15rs3z6mcjm417dwr0000gn/T/pip-pip-egg-info-of9c2ewk
         cwd: /private/var/folders/9b/6n0_krj15rs3z6mcjm417dwr0000gn/T/pip-install-h7m_i_6j/yamllint-junit/
    Complete output (8 lines):
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/private/var/folders/9b/6n0_krj15rs3z6mcjm417dwr0000gn/T/pip-install-h7m_i_6j/yamllint-junit/setup.py", line 3, in <module>
        from yamllint_junit_bootstrap import bootstrap
      File "/private/var/folders/9b/6n0_krj15rs3z6mcjm417dwr0000gn/T/pip-install-h7m_i_6j/yamllint-junit/yamllint_junit_bootstrap/bootstrap.py", line 85
        print parsed_lines_xml
              ^
    SyntaxError: Missing parentheses in call to 'print'. Did you mean print(parsed_lines_xml)?
    ----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
```

Main error shows `yamllint-junit/yamllint_junit_bootstrap/bootstrap.py", line 85 -- SyntaxError: Missing parentheses in call to 'print'. Did you mean print(parsed_lines_xml)?`


Discussion / hints:

Fix patch:
diff --git a/.gitignore b/.gitignore
index c2ce63f..d2e68da 100644
--- a/.gitignore
+++ b/.gitignore
@@ -195,3 +195,6 @@ $RECYCLE.BIN/
 *.lnk
 
 # End of https://www.gitignore.io/api/windows,macos,vim,sublimetext,python
+
+# IntelliJ
+.idea
\ No newline at end of file
diff --git a/.travis.yaml b/.travis.yaml
new file mode 100644
index 0000000..da4ad50
--- /dev/null
+++ b/.travis.yaml
@@ -0,0 +1,23 @@
+---
+language: python
+python:
+  - 2.7
+  - 3.5
+  - 3.6
+  - 3.7
+  - 3.8
+before_install:
+  - python --version
+  - pip install -U pip
+  - pip install -U pytest
+  - pip install -U flake8
+  - pip install -U mock
+  - pip install codecov
+install:
+  - pip install ".[test]" .  # install package + test dependencies
+before_script:
+  # 127 are the length of a line in the github-editor
+  - flake8 --count --exclude ./tests,./doc --max-complexity 20 --max-line-length 127 --statistics
+script: pytest  # run tests
+after_success:
+  - codecov  # submit coverage
diff --git a/setup.py b/setup.py
index 4cf46b6..7b0c07b 100644
--- a/setup.py
+++ b/setup.py
@@ -1,3 +1,6 @@
+#! /usr/bin/env python
+#  -*- coding: utf-8 -*-
+
 from setuptools import setup
 
 from yamllint_junit_bootstrap import bootstrap
@@ -12,13 +15,19 @@
     author='wasil',
     author_email='piotr.m.wasilewski@gmail.com',
     url='https://github.com/wasilak/yamllint-junit',
-    download_url='https://github.com/wasilak/yamllint-junit/archive/%s.tar.gz'  % (version),
+    download_url='https://github.com/wasilak/yamllint-junit/archive/%s.tar.gz' % version,
     keywords=['yaml', 'junit'],
     classifiers=[],
-    entry_points = {
+    entry_points={
         "console_scripts": ['yamllint-junit = yamllint_junit_bootstrap.bootstrap:main']
     },
     install_requires=[
         'yamllint',
     ],
+    tests_require=[
+        'pytest',
+        'flake8',
+        'coverage',
+        'mock',
+    ],
 )
diff --git a/yamllint_junit_bootstrap/__init__.py b/yamllint_junit_bootstrap/__init__.py
index e69de29..cff6a29 100644
--- a/yamllint_junit_bootstrap/__init__.py
+++ b/yamllint_junit_bootstrap/__init__.py
@@ -0,0 +1,2 @@
+#! /usr/bin/env python
+#  -*- coding: utf-8 -*-
diff --git a/yamllint_junit_bootstrap/__main__.py b/yamllint_junit_bootstrap/__main__.py
index 680765c..ee8cf0a 100644
--- a/yamllint_junit_bootstrap/__main__.py
+++ b/yamllint_junit_bootstrap/__main__.py
@@ -1,2 +1,5 @@
+#! /usr/bin/env python
+#  -*- coding: utf-8 -*-
+
 from .bootstrap import main
 main()
diff --git a/yamllint_junit_bootstrap/bootstrap.py b/yamllint_junit_bootstrap/bootstrap.py
index 7eab896..0f10c7f 100755
--- a/yamllint_junit_bootstrap/bootstrap.py
+++ b/yamllint_junit_bootstrap/bootstrap.py
@@ -1,19 +1,39 @@
+#! /usr/bin/env python
+#  -*- coding: utf-8 -*-
+
 from optparse import OptionParser
 import xml.etree.cElementTree as ET
 import sys
 from os import isatty
 
-__version__ = "0.5"
+__version__ = "0.6"
+"""Version of lib"""
 
 
 def version():
+    """
+    Returns version of libary
+
+    :return: Version of lib as String
+    """
     return __version__
 
+
+def is_pipe():
+    """
+    Return if stdin has a value
+
+    :return: True, if there is a value on stdin
+    """
+    return not isatty(sys.stdin.fileno())
+
+
 def main():
+    """
+    Main Method of lib
+    """
 
     # detecting if script was run interactively
-    is_pipe = not isatty(sys.stdin.fileno())
-
     junit_xml_output = "yamllint-junit.xml"
 
     parser = OptionParser(
@@ -21,13 +41,15 @@ def main():
         version="%prog " + version()
     )
 
-    parser.add_option("-o", "--output", action="store", dest="output_file", help="output XML to file", default=junit_xml_output)
-    parser.add_option("-v", "--verbose", action="store_true", dest="verbose", help="print XML to console as command output", default=False)
+    parser.add_option("-o", "--output", action="store", dest="output_file", help="output XML to file",
+                      default=junit_xml_output)
+    parser.add_option("-v", "--verbose", action="store_true", dest="verbose",
+                      help="print XML to console as command output", default=False)
 
     (options, args) = parser.parse_args()
 
     lines = []
-    if is_pipe:
+    if is_pipe():
         for line in sys.stdin:
             if len(line.strip()) > 0:
                 lines.append(line.strip())
@@ -51,7 +73,7 @@ def main():
     testsuite = ET.SubElement(testsuites, "testsuite", errors=errors_count, failures="0", tests=errors_count, time="0")
 
     if 0 == len(lines):
-        testcase = ET.SubElement(testsuite, "testcase", name="dummy_testcase.py")
+        ET.SubElement(testsuite, "testcase", name="dummy_testcase.py")
     else:
         parsed_lines = []
         for line in lines:
@@ -82,4 +104,4 @@ def main():
     parsed_lines_xml = ET.tostring(testsuites, encoding='utf8', method='xml')
 
     if options.verbose:
-        print parsed_lines_xml
+        print(parsed_lines_xml)


Test patch:
diff --git a/test/test_yamllint_junit.py b/test/test_yamllint_junit.py
new file mode 100644
index 0000000..6830e90
--- /dev/null
+++ b/test/test_yamllint_junit.py
@@ -0,0 +1,38 @@
+#! /usr/bin/env python3
+#  -*- coding: utf-8 -*-
+import io
+import mock
+import pytest
+import yamllint_junit_bootstrap.bootstrap as yamllint_junit
+
+
+def test_no_parameters_no_input():
+    # Prepare
+    # It's terrible to mock sys.stdin.fileno() in a test, so I extracted it in an extra method
+    yamllint_junit.is_pipe = mock.MagicMock(return_value=False)
+
+    # Execute
+    with pytest.raises(SystemExit) as pytest_wrapped_e:
+        yamllint_junit.main()
+
+    # Test
+    assert pytest_wrapped_e.type == SystemExit
+    assert pytest_wrapped_e.value.code == 2
+
+
+def test_with_input(monkeypatch):
+    # Prepare
+    stdin = u"""\
+first.yaml:7:1: [error] trailing spaces (trailing-spaces)
+first.yaml:16:1: [error] trailing spaces (trailing-spaces)
+second.yaml:22:1: [error] trailing spaces (trailing-spaces)"""
+    monkeypatch.setattr('sys.stdin', io.StringIO(stdin))
+    # It's terrible to mock sys.stdin.fileno() in a test, so I extracted it in an extra method
+    yamllint_junit.is_pipe = mock.MagicMock(return_value=True)
+    yamllint_junit.ET.ElementTree.write = mock.MagicMock()
+
+    # Execute
+    yamllint_junit.main()
+
+    # Test
+    yamllint_junit.ET.ElementTree.write.assert_any_call("yamllint-junit.xml", encoding='utf8', method='xml')