Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/workflows/python-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: python-tests
on: [push, pull_request]

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run tests
run: pytest -q
Empty file added aps_logcomp/__init__.py
Empty file.
Empty file added requirements.txt
Empty file.
27 changes: 27 additions & 0 deletions tests/test_integration_midi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import os
from aps_logcomp import main

def test_integration_generate_midi(tmp_path):
# Minimal music: one instrument, one play
content = "Music X 100 { Instrument piano { play 60 1 } }"
tokenizer = main.Tokenizer(content)
parser = main.Parser(tokenizer)
music_node = parser.parse_program()

# Build context by evaluating nodes (this populates context["instrumentos"])
context = {}
music_node.evaluate(context)

# instrument map: piano -> GM program 0
instrument_map = {"piano": 0}

out_base = tmp_path / "out_test"
# criar_midi_com_duracoes writes {nome}.mid, so pass a path-like name
out_name = str(out_base)

# call the function under test
main.criar_midi_com_duracoes(context, music_node.bpm, out_name, music_node.instrumentos, instrument_map)

out_file = out_base.with_suffix(".mid")
assert out_file.exists(), "MIDI file was not created"
assert out_file.stat().st_size > 0, "MIDI file size is zero"
23 changes: 23 additions & 0 deletions tests/test_tokenizer_parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import pytest
from aps_logcomp import main

def test_tokenizer_basic_sequence():
content = "Music Song 120 { Instrument piano { play 60 1 } }"
tokenizer = main.Tokenizer(content)
tokens = tokenizer.tokenize()
types = [t.type for t in tokens]
# Expected prefix of token types
expected = ["MUSIC", "ID", "NUMBER", "LBRACE", "INSTRUMENT", "ID",
"LBRACE", "PLAY", "NUMBER", "NUMBER", "RBRACE", "RBRACE"]
assert types[:len(expected)] == expected

def test_parser_produces_music_node():
content = "Music Foobar 100 { Instrument piano { play 63 1 } }"
tokenizer = main.Tokenizer(content)
parser = main.Parser(tokenizer)
node = parser.parse_program()
assert isinstance(node, main.MusicNode)
assert node.nome == "Foobar"
assert node.bpm == 100
# at least one instrument parsed
assert len(node.instrumentos) >= 1