Skip to content

Commit

Permalink
first draft of tests/ for #5
Browse files Browse the repository at this point in the history
  • Loading branch information
snake-biscuits committed Nov 12, 2022
1 parent 011d224 commit 733e1e3
Show file tree
Hide file tree
Showing 9 changed files with 237 additions and 33 deletions.
54 changes: 54 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# XML & JSON Linters + fuse.py builds

name: Build simulacrum

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]


jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.7, 3.8, 3.9, "3.10", "3.11"]

steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install flake8 demjson3 jsonschema
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
if [ -f tests/requirements.txt ]; then pip install -r tests/requirements.txt; fi
- name: Lint Python with flake8
# check if bloodhound, fuse & qa are ok
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
# TODO: - name: Lint mrvn XML with xmllint
# # mrvn folder; generated by snake-biscuits/bsp_tool_examples/fgd2ent.py via bloodhound.py
# run: |
# # for .xml filename in mrvn subfolder
# xmllint filename
# TODO: - name: Lint pilot JSON with jsonlint (python demjson3)
# run: |
# # for .json filename in pilot subfolder
# # AND for .json filename in choiceType sub-subfolders
# jsonlint filename
# TODO: validate schema (tests/test_quality.py for local testing?)
- name: Test with pytest
run: |
pytest -vv
# TODO: Lint simulactum .ent
# TODO: Export simulacrum artifact

33 changes: 14 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,23 +75,18 @@ TL;DR: Bloodhound hunts and Fuse does the dishes


## TODOs
* Write `fuse.py`
- parse `.xml`
- parse `.json`
* allow changes to choicesList types (choice names) e.g. `TEAM_IMC`
- apply changes
- write to `simulacrum/<game>/<block_entities>.ent`
* Write `quality_assurance.py`
- verify `.json` has good data, no typos
- don't enforce styleguide, essentials only
- break if:
* `contributors` missing
* invalid index for `block`, `entity`, `key` or `spawnflag`
- suggest fixes
- [ ] Write `fuse.py`
- see #5
- [ ] Write `tests/`
- [ ] `test_bloodhound.py`
- [ ] `test_fuse.py`
- [x] `mrvn/` & `simulacrum/` `test_xml.py` (see #5)
- [x] `pilot/` `test_json.py` (see #5)
* GitHub Workflows
- lint `.xml`
- run `quality_assurance.py`
- run `fuse.py`
- turn `simulacrum/` into an artifact
* Documentation
- using `fgd2ent.py` to compare `omega_entity` to `fgd.entities` to find the "Ur" entity
- [ ] lint python
- [ ] run `fuse.py`
- [ ] run `tests/` (2nd to include latests `simulacrum/`)
- [ ] create `simulacrum/` artifact
- [ ] Documentation
- [ ] extending `fgd2ent` to auto-fill common keys & updating the repo w/ `bloodhound.py`
- [ ] using `snake-biscuits/bsp_tool_examples/fgd2ent.py` in a REPL for research
19 changes: 5 additions & 14 deletions fuse.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
# import json
# import xml


raise NotImplementedError("fusey's on smoko mate")

# TODO:
# -- decide on `.json` layout
# -- * write `info_example.json`
# -- for each `ENTITIES.xml`
# -- * parse `.xml`
# -- * collect changes from `.json` (1 per entity or choiceType)
# -- * credit `.json` contributor(s) in a comment above definition
# -- * FUSE `.xml` base with `.json` changes into renamed `.ent`
# -- * write to f"simulacrum/<game>/{ent_filename[xml_filename]}"
#
# -- mimic pilot regen screen
# TODO: mimic pilot regen screen w/ prints

ent_filename = {"ENTITIES.xml": "entities.ent",
"ENTITIES_env.xml": "environment_entites.ent",
Expand All @@ -22,6 +16,3 @@
types = {"float": "real"} # fuzzy matching
defaults = {"float": "1.0"} # allow undefined
# TODO: choiceTypes default to first Option

thesaurus = {"0": ["no", "0", "false"],
"1": ["yes", "1", "true"]}
3 changes: 3 additions & 0 deletions tests/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
jsonschema
pytest
xmlschema
Empty file added tests/schema/choiceTypes.json
Empty file.
103 changes: 103 additions & 0 deletions tests/schema/entity.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
{
"title": "MRVN-radiant Entity Definition",
"description": "an entity defintion to be amended in a .ent file",
"type": "object",
"properties": {
"Contributors": {
"description": "List of people that contributed to this definition",
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"uniqueItems": true
},
"Block": {
"description": "Entity block (mrvn/game/<Block>.xml) this definition overrides",
"type": "string",
"pattern": "ENTITIES(_(env|fx|script|spawn|snd))?"
},
"Entity": {
"description": "Entity classname & json filename (TODO: editorclass)",
"type": "string",
"pattern": "[a-z]*(_[a-z])*"
},
"Type": {
"description": "Entity type (group for brush entities)",
"type": "string",
"pattern": "point|group"
},
"Description": {
"description": "One-line descrition",
"type": "string"
},
"Keys": {
"description": "List of entity keys",
"type": "array",
"items": {
"type": "object",
"properties": {
"keyname": {
"description": "INDEX: Name of key (as it appears in bsp entity data) to override",
"type": "string"
},
"type": {
"description": "MRVN-radiant type to use (affects editor preview & interface widget)",
"type": "string"
},
"name": {
"description": "Key name displayed in MRVN-radiant",
"type": "string"
},
"default": {
"description": "Default value",
"type": "string"
},
"description": {
"description": "Description of key use & default behaviour",
"type": "string"
}
},
"required": [ "keyname" ]
},
"minItems": 1,
"uniqueItems": true
},
"SpawnFlags": {
"description": "List of entity keys",
"type": "array",
"items": {
"type": "object",
"properties": {
"bit": {
"description": "INDEX: bit to override",
"value": "integer"
},
"name": {
"description": "Spawnflag name displayed in MRVN-radiant",
"type": "string"
},
"default": {
"description": "Default value",
"type": "string"
},
"description": {
"description": "Description of spawnflag use & default behaviour",
"type": "string"
}
},
"required": [ "bit" ]
}
},
"Notes": {
"description": "Detailed general description & notes",
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"uniqueItems": true
},
"required": [ "Contributors", "Block", "Entity" ]
}
}
Empty file.
37 changes: 37 additions & 0 deletions tests/test_json.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import fnmatch
import json
import os

import jsonschema
import pytest


games = tuple(filter(os.path.isdir, os.listdir("mrvn")))

entity_schema = json.load("schema/entity.json")
entity_json = [os.path.join("pilot", g, j) for g in games
for j in fnmatch.filter(os.listdir(f"pilot/{g}"), "*.json")]

choiceType_schema = json.load("schema/choiceType.json")
choiceType_json = list()
for game_dir in games:
search_dir = os.path.join("pilot", game_dir, "choiceTypes")
if not os.path.exists(search_dir):
continue
for choiceType in fnmatch.filter(os.listdir(search_dir), "*.json"):
choiceType_json.append()


@pytest.mark.parametrize("json_filename", entity_json)
def validate_entity(json_filename: str):
entity = json.load(json_filename)
jsonschema.validate(entity, schema=entity_schema)
# TODO: dynamic type checking
# -- list of valid key types for radiant
# -- add choiceType lists from .xml & .json


@pytest.mark.parametrize("json_filename", choiceType_json)
def validate_choiceType(json_filename: str):
choiceType = json.load(json_filename)
jsonschema.validate(choiceType, schema=choiceType_schema)
21 changes: 21 additions & 0 deletions tests/test_xml.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import fnmatch
import os

import pytest
import xmlschema


ent_schema = xmlschema.XMLSchema("schema/entity_definitions.xsd")

games = tuple(filter(os.path.isdir, os.listdir("mrvn")))

mrvn_xml = [os.path.join("mrvn", g, x) for g in games
for x in fnmatch.filter(os.listdir(f"mrvn/{g}"), "*.xml")]

simulacrum_ent = [os.path.join("simulacrum", g, e) for g in games
for e in fnmatch.filter(os.listdir(f"simulacrum/{g}"), "*.ent")]


@pytest.mark.parametrize("xml_filename", (*mrvn_xml, *simulacrum_ent))
def validate(xml_filename: str):
raise NotImplementedError()

0 comments on commit 733e1e3

Please sign in to comment.