Skip to content

Commit

Permalink
add linting (#140)
Browse files Browse the repository at this point in the history
* pass flake8

* add linting

* pass foxylint
  • Loading branch information
haarcuba authored Sep 13, 2024
1 parent 7a31c66 commit 188fe75
Show file tree
Hide file tree
Showing 127 changed files with 890 additions and 605 deletions.
23 changes: 23 additions & 0 deletions .github/workflows/linters.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Enforce Conventions

on:
push:

jobs:
linters-and-formatters:
runs-on: ubuntu-latest
environment: prod
steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up Python 3.12
uses: actions/setup-python@v4
with:
python-version: '3.12'

- name: Enforce Conventions
uses: pre-commit/action@v3.0.1
with:
extra_args:
--all-files
2 changes: 1 addition & 1 deletion .github/workflows/publish.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: Publish
on:
workflow_dispatch:
jobs:
jobs:
publish:
runs-on: ubuntu-20.04
steps:
Expand Down
39 changes: 39 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.2.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
exclude: template.yml
- repo: https://github.com/psf/black
rev: 23.12.1
hooks:
- id: black
args:
- --line-length=150
- --target-version=py311
- --skip-string-normalization
- repo: https://github.com/PyCQA/flake8
rev: 7.0.0
hooks:
- id: flake8
args:
- --ignore=E203,E501,E266,F541,W503,F405
- "--exclude=docs/*"
- repo: https://github.com/python-jsonschema/check-jsonschema
rev: 0.28.3
hooks:
- id: check-github-workflows
args: [ "--verbose" ]
- repo: https://github.com/PracticeFoxyCode/practice
rev: releases/1.0.0
hooks:
- id: foxylint-imports
args:
- "--accept=/from testix.*import/"
- "--accept=/from examples import/"
- "--accept=/from unittest.*import/"
- "--exclude=./testix/__init__.py"
5 changes: 3 additions & 2 deletions chatbot/src/chatbot/chatbot.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import socket
from . import responder
from . import responder


class Chatbot:
def __init__( self, peer ):
def __init__(self, peer):
self._peer = peer
self._responder = responder.Responder()

Expand Down
27 changes: 14 additions & 13 deletions chatbot/test/test_chatbot.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import pytest
import socket
from testix.frequentlyused import *
from testix import patch_module
from chatbot import chatbot
from testix.frequentlyused import * # noqa: F403
from testix import patch_module # noqa: F401
from chatbot import chatbot # foxylint-imports:ignore


class TestChatbot:
@pytest.fixture(autouse=True)
def globals_patch(self, patch_module):
patch_module( chatbot, 'responder' )
def globals_patch(self, patch_module): # noqa: F811
patch_module(chatbot, 'responder')

def construct(self):
with Scenario() as s:
s.responder.Responder() >> Fake( 'responder_' )
self.tested = chatbot.Chatbot( Fake( 'sock' ) )
s.responder.Responder() >> Fake('responder_')
self.tested = chatbot.Chatbot(Fake('sock'))

def test_construction(self):
self.construct()
Expand All @@ -21,8 +22,8 @@ def test_request_response_loop(self):
self.construct()
with Scenario() as s:
for i in range(10):
s.sock.recv(4096) >> f'request {i}'
s.responder_.process(f'request {i}') >> f'response {i}'
s.sock.recv(4096) >> f'request {i}'
s.responder_.process(f'request {i}') >> f'response {i}'
s.sock.send(f'response {i}')

s.sock.recv(4096) >> Throwing(TestixLoopBreaker)
Expand All @@ -33,15 +34,15 @@ def test_request_response_loop_survives_a_recv_exception(self):
self.construct()
with Scenario() as s:
for i in range(10):
s.sock.recv(4096) >> f'request {i}'
s.responder_.process(f'request {i}') >> f'response {i}'
s.sock.recv(4096) >> f'request {i}'
s.responder_.process(f'request {i}') >> f'response {i}'
s.sock.send(f'response {i}')

s.sock.recv(4096) >> Throwing(socket.error)

for i in range(10):
s.sock.recv(4096) >> f'request {i}'
s.responder_.process(f'request {i}') >> f'response {i}'
s.sock.recv(4096) >> f'request {i}'
s.responder_.process(f'request {i}') >> f'response {i}'
s.sock.send(f'response {i}')

s.sock.recv(4096) >> Throwing(TestixLoopBreaker)
Expand Down
24 changes: 13 additions & 11 deletions chatbot/test/test_chatbot_with_unittest_mock.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,38 @@
import pytest
from unittest.mock import patch
import unittest.mock
from unittest.mock import Mock, call
import socket
import chatbot.chatbot
import chatbot.responder


class TestChatbot:
def construct(self, sock, Responder):
self.tested = chatbot.chatbot.Chatbot( sock )
self.tested = chatbot.chatbot.Chatbot(sock)
Responder.assert_called_once_with()

@patch('chatbot.responder.Responder')
@unittest.mock.patch('chatbot.responder.Responder')
def test_construction(self, Responder):
sock = Mock()
self.construct(sock, Responder)

@patch('chatbot.responder.Responder')
@unittest.mock.patch('chatbot.responder.Responder')
def test_request_response_loop(self, Responder):
sock = Mock()
responder = Mock()
Responder.side_effect = [ responder ]
Responder.side_effect = [responder]
self.construct(sock, Responder)
class EndTestException(Exception): pass

class EndTestException(Exception):
pass

REQUESTS = [f'request {i}' for i in range(10)]
RESPONSES = [f'response {i}' for i in range(10)]
responder.process.side_effect = RESPONSES
sock.recv.side_effect = REQUESTS + [EndTestException]

with pytest.raises(EndTestException):
self.tested.go()

sock.recv.assert_has_calls( [ call(4096) ] * 10 )
responder.process.assert_has_calls( [ call(request) for request in REQUESTS ] )
sock.send.assert_has_calls( [ call( response ) for response in RESPONSES ] )
sock.recv.assert_has_calls([call(4096)] * 10)
responder.process.assert_has_calls([call(request) for request in REQUESTS])
sock.send.assert_has_calls([call(response) for response in RESPONSES])
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,3 @@ def test_send_and_receive_messages():

assert alice_messages == ['hi Alice']
assert bob_messages == ['hi Bob']


Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import chatapp.client


class OnMessage:
def __init__(self):
self.messages = []

def __call__(self, client, message, peer):
self.messages.append({'message': message, 'peer': peer})


def test_send_and_receive_messages():
alice_callback = OnMessage()
bob_callback = OnMessage()
Expand All @@ -17,4 +19,4 @@ def test_send_and_receive_messages():
bob.send('hi Alice', to='Alice')

assert alice_callback.messages == [{'message': 'hi Alice', 'peer': 'Bob'}]
assert bob_callback.messages == [{'message': 'hi Bob', 'peer': 'Alice'}]
assert bob_callback.messages == [{'message': 'hi Bob', 'peer': 'Alice'}]
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import chatapp.client
import time


class OnMessage:
def __init__(self):
self.messages = []

def __call__(self, client, message, peer):
self.messages.append({'message': message, 'peer': peer})


def test_send_and_receive_messages():
alice_callback = OnMessage()
bob_callback = OnMessage()
Expand All @@ -21,4 +23,4 @@ def test_send_and_receive_messages():
time.sleep(LET_SERVER_RELAY_MESSAGES)

assert alice_callback.messages == [{'message': 'hi Alice', 'peer': 'Bob'}]
assert bob_callback.messages == [{'message': 'hi Bob', 'peer': 'Alice'}]
assert bob_callback.messages == [{'message': 'hi Bob', 'peer': 'Alice'}]
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,23 @@
import chatapp.server
import time


class OnMessage:
def __init__(self):
self.messages = []

def __call__(self, client, message, peer):
self.messages.append({'message': message, 'peer': peer})


@pytest.fixture
def chat_app_server():
server = chatapp.server.Server(bind_to=('', 3333))
server.start()
yield 'http://localhost:3333'
server.stop()


def test_send_and_receive_messages(chat_app_server):
alice_callback = OnMessage()
bob_callback = OnMessage()
Expand All @@ -30,4 +33,4 @@ def test_send_and_receive_messages(chat_app_server):
time.sleep(LET_SERVER_RELAY_MESSAGES)

assert alice_callback.messages == [{'message': 'hi Alice', 'peer': 'Bob'}]
assert bob_callback.messages == [{'message': 'hi Bob', 'peer': 'Alice'}]
assert bob_callback.messages == [{'message': 'hi Bob', 'peer': 'Alice'}]
1 change: 0 additions & 1 deletion docs/common.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,3 @@
.. |RED| replace:: :boldred:`RED`
.. |GREEN| replace:: :boldgreen:`GREEN`
.. |REFACTOR| replace:: :boldblue:`REFACTOR`

1 change: 1 addition & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
import sphinx_theme

html_theme = 'stanford_theme'
html_theme_path = [sphinx_theme.get_html_theme_path('stanford-theme')]
#
Expand Down
8 changes: 4 additions & 4 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ The Test-First Mocking Framework

|testix| is special because it allows you to specify what your mock objects do,
and it then enforces your specifications automatically. It also reduces (albeit
not entirely) mock setup.
not entirely) mock setup.

Other frameworks usually have a flow like this:

Expand All @@ -29,7 +29,7 @@ Other frameworks usually have a flow like this:

#. setup mock objects
#. specify *exactly* what should happen to them using a Scenario context


Quick Example
-------------
Expand Down Expand Up @@ -86,10 +86,10 @@ Advantages
#. Readability - the expectations are very similar to the actual code that they
test (compare ``s.sock.recv(4096)`` with the standard ``sock.recv.assert_called_once_with(4096)``
#. Test Driven Development friendliness: if you use ``sock.recv.assert_called_once_with(4096)``, you must
use it after the code has run. With |testix|, you specify what you *expect*, and the asserting
use it after the code has run. With |testix|, you specify what you *expect*, and the asserting
is done for you by magic.

What are you waiting for?
What are you waiting for?


Go to the :doc:`reference<reference/index>` or read the :doc:`Tutorial<tutorial/index>`
Expand Down
1 change: 1 addition & 0 deletions docs/line_monitor/source/12/line_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import pty
import select


class LineMonitor:
def __init__(self):
self._callback = None
Expand Down
1 change: 1 addition & 0 deletions docs/line_monitor/source/14/line_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import pty
import select


class LineMonitor:
def __init__(self):
self._callback = None
Expand Down
1 change: 1 addition & 0 deletions docs/line_monitor/source/16/line_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import pty
import select


class LineMonitor:
def __init__(self):
self._callback = None
Expand Down
1 change: 1 addition & 0 deletions docs/line_monitor/source/17/line_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import pty
import select


class LineMonitor:
def __init__(self):
self._callback = None
Expand Down
1 change: 1 addition & 0 deletions docs/line_monitor/source/19/line_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import pty
import select


class LineMonitor:
def __init__(self):
self._callback = None
Expand Down
1 change: 1 addition & 0 deletions docs/line_monitor/source/2/line_monitor.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import subprocess
import pty


class LineMonitor:
def register_callback(self, callback):
pass
Expand Down
1 change: 1 addition & 0 deletions docs/line_monitor/source/21/line_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import pty
import select


class LineMonitor:
def __init__(self):
self._callback = None
Expand Down
1 change: 1 addition & 0 deletions docs/line_monitor/source/23/line_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import pty
import select


class LineMonitor:
def __init__(self):
self._callback = None
Expand Down
1 change: 1 addition & 0 deletions docs/line_monitor/source/25/line_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import pty
import select


class LineMonitor:
def __init__(self):
self._callback = None
Expand Down
1 change: 1 addition & 0 deletions docs/line_monitor/source/26/line_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import pty
import select


class LineMonitor:
def __init__(self):
self._callback = None
Expand Down
Loading

0 comments on commit 188fe75

Please sign in to comment.