Skip to content

Commit 39c7289

Browse files
committed
Started to add tests
1 parent 18bc2e0 commit 39c7289

File tree

3 files changed

+187
-0
lines changed

3 files changed

+187
-0
lines changed

.github/workflows/ci.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: Project Tests
2+
on:
3+
push:
4+
branches:
5+
- master
6+
pull_request:
7+
branches:
8+
- master
9+
10+
jobs:
11+
build:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v2
15+
- name: Set up Python 3.7
16+
uses: actions/setup-python@v1
17+
with:
18+
python-version: 3.7
19+
- name: Test with pytest
20+
run: ./run-tests.sh

run-tests.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/bash
2+
3+
set -x
4+
pytest -vv test_lcd.py

test_lcd.py

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
#!/usr/bin/env python3
2+
3+
# This file tests the LcdApi class
4+
5+
import unittest
6+
7+
from lcd import LcdApi
8+
9+
DDRAM_SIZE = 128
10+
11+
class LcdSim(LcdApi):
12+
"""Implements an HD44780 character LCD emulator.
13+
14+
The addressing modes are described here:
15+
http://web.alfredstate.edu/faculty/weimandn/lcd/lcd_addressing/lcd_addressing_index.html
16+
"""
17+
18+
def __init__(self, num_lines=2, num_columns=16):
19+
LcdApi.__init__(self, num_lines, num_columns)
20+
self.reset()
21+
self.num_lines = num_lines
22+
self.num_columns = num_columns
23+
24+
def hal_backlight_on(self):
25+
"""Allows the hal layer to turn the backlight on."""
26+
27+
def hal_backlight_off(self):
28+
"""Allows the hal layer to turn the backlight off."""
29+
30+
def hal_write_command(self, cmd):
31+
"""Writes a command to the LCD.
32+
33+
Data is latched on the falling edge of E.
34+
"""
35+
if cmd == LcdApi.LCD_CLR:
36+
self.reset()
37+
elif cmd == LcdApi.LCD_HOME:
38+
self.addr = 0
39+
elif cmd & LcdApi.LCD_DDRAM != 0:
40+
self.addr = cmd & 0x7f
41+
42+
def hal_write_data(self, data):
43+
"""Write data to the LCD."""
44+
self.ddram[self.addr & 0x7f] = data
45+
self.addr += 1
46+
47+
def reset(self):
48+
"""Resets the DDRAM."""
49+
self.ddram = [ord(' ')] * DDRAM_SIZE
50+
self.addr = 0
51+
52+
def display_lines(self):
53+
"""Returns the DDRAM as an array of display lines."""
54+
lines = []
55+
for i in range(self.num_lines):
56+
addr = self.addr_for_line(i)
57+
line = bytes(self.ddram[addr:addr+self.num_columns])
58+
lines.append(line)
59+
return lines
60+
61+
def addr_for_line(self, line):
62+
"""Calculates the DDRAM address for a particular line."""
63+
64+
# From http://web.alfredstate.edu/faculty/weimandn/lcd/lcd_addressing/lcd_addressing_index.html
65+
#
66+
# 2 x 40: 0x00, 0x40
67+
# 4 x 20: 0x00, 0x40, 0x14, 0x54
68+
# 2 x 20: 0x00, 0x40
69+
# 2 x 16: 0x00, 0x40
70+
# 4 x 16: 0x00, 0x40, 0x10, 0x50
71+
72+
addr = 0
73+
if line & 1 != 0:
74+
addr += 0x40
75+
if line & 2 != 0:
76+
if self.num_columns == 16:
77+
addr += 0x10
78+
else:
79+
addr += 0x14
80+
return addr
81+
82+
def dump_lines(self):
83+
lines = self.display_lines()
84+
for i in range(self.num_lines):
85+
line = lines[i].decode('utf-8','ignore')
86+
print('Line {}: {:02x} >{}<'.format(i, self.addr_for_line(i), line))
87+
88+
89+
class TestLcd(unittest.TestCase):
90+
91+
def test_simple(self):
92+
lcd = LcdSim(4, 20)
93+
lcd.putstr('Line 1')
94+
self.assertEqual(lcd.display_lines(), [
95+
b'Line 1 ',
96+
b' ',
97+
b' ',
98+
b' '
99+
])
100+
lcd.putstr(': more\n')
101+
lcd.putstr('Line 2')
102+
self.assertEqual(lcd.display_lines(), [
103+
b'Line 1: more ',
104+
b'Line 2 ',
105+
b' ',
106+
b' '
107+
])
108+
109+
def test_full_line(self):
110+
lcd = LcdSim(4, 20)
111+
lcd.putstr('Line 1 - 01234567890')
112+
self.assertEqual(lcd.display_lines(), [
113+
b'Line 1 - 01234567890',
114+
b' ',
115+
b' ',
116+
b' '
117+
])
118+
lcd.putstr('Line 2 - 01234567890')
119+
self.assertEqual(lcd.display_lines(), [
120+
b'Line 1 - 01234567890',
121+
b'Line 2 - 01234567890',
122+
b' ',
123+
b' '
124+
])
125+
lcd.putstr('Line 3 - 01234567890')
126+
lcd.putstr('Line 4 - 01234567890')
127+
lcd.putstr('Line 5 - 01234567890')
128+
self.assertEqual(lcd.display_lines(), [
129+
b'Line 5 - 01234567890',
130+
b'Line 2 - 01234567890',
131+
b'Line 3 - 01234567890',
132+
b'Line 4 - 01234567890',
133+
])
134+
135+
def test_full_line2(self):
136+
lcd = LcdSim(4, 20)
137+
lcd.putstr('Line 1 - 01234567890\n')
138+
self.assertEqual(lcd.display_lines(), [
139+
b'Line 1 - 01234567890',
140+
b' ',
141+
b' ',
142+
b' '
143+
])
144+
lcd.putstr('Line 2 - 01234567890\n')
145+
self.assertEqual(lcd.display_lines(), [
146+
b'Line 1 - 01234567890',
147+
b'Line 2 - 01234567890',
148+
b' ',
149+
b' '
150+
])
151+
lcd.putstr('Line 3 - 01234567890\n')
152+
lcd.putstr('Line 4 - 01234567890\n')
153+
lcd.putstr('Line 5 - 01234567890\n')
154+
self.assertEqual(lcd.display_lines(), [
155+
b'Line 5 - 01234567890',
156+
b'Line 2 - 01234567890',
157+
b'Line 3 - 01234567890',
158+
b'Line 4 - 01234567890',
159+
])
160+
161+
162+
if __name__ == '__main__':
163+
unittest.main()

0 commit comments

Comments
 (0)