Skip to content

Commit ff1e5eb

Browse files
Merge pull request #74 from riscv/73-norm-rule-tests
Add unit-level regression test for normative rule extraction scripts
2 parents 6ef1a1f + 56bf0a3 commit ff1e5eb

File tree

7 files changed

+412
-37
lines changed

7 files changed

+412
-37
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/build/*
2+
*.log

Makefile

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
# Makefile for tests for tools/scripts in docs-resources repository.
2+
# Must be run in top-level directory of docs-resources repository.
3+
#
4+
# This work is licensed under the Creative Commons Attribution-ShareAlike 4.0
5+
# International License. To view a copy of this license, visit
6+
# http://creativecommons.org/licenses/by-sa/4.0/ or send a letter to
7+
# Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
8+
#
9+
# SPDX-License-Identifier: CC-BY-SA-4.0
10+
#
11+
# This Makefile is designed to automate the process of running tests.
12+
# Running with a preinstalled docker container is strongly recommended.
13+
# Install by running:
14+
# docker pull riscvintl/riscv-docs-base-container-image:latest
15+
16+
# Directories all relative to the top-level.
17+
CONVERTERS_DIR := converters
18+
TOOLS_DIR := tools
19+
BUILD_DIR := build
20+
TESTS_DIR := tests
21+
NORM_RULE_TESTS_DIR := $(TESTS_DIR)/norm-rule
22+
NORM_RULE_DEF_DIR := $(NORM_RULE_TESTS_DIR)
23+
NORM_RULE_EXPECTED_DIR := $(NORM_RULE_TESTS_DIR)/expected
24+
25+
# Ruby scripts being tested.
26+
TAGS_BACKEND := tags.rb
27+
CREATE_NORM_RULE_TOOL := create_normative_rules.rb
28+
29+
# Input and output file names
30+
TEST_ADOC_INPUT_FNAME := test.adoc
31+
NORM_TAGS_OUTPUT_FNAME := test-norm-tags.json
32+
NORM_RULE_OUTPUT_FNAME := test-norm-rules.json
33+
34+
# Built output files
35+
BUILT_NORM_TAGS := $(BUILD_DIR)/$(NORM_TAGS_OUTPUT_FNAME)
36+
BUILT_NORM_RULES := $(BUILD_DIR)/$(NORM_RULE_OUTPUT_FNAME)
37+
38+
# Copies of expected output files.
39+
# Use make target "update-expected" to update from build dir contents.
40+
EXPECTED_NORM_TAGS := $(NORM_RULE_EXPECTED_DIR)/$(NORM_TAGS_OUTPUT_FNAME)
41+
EXPECTED_NORM_RULES := $(NORM_RULE_EXPECTED_DIR)/$(NORM_RULE_OUTPUT_FNAME)
42+
43+
# All normative rule definition input YAML files
44+
NORM_RULE_DEF_FILES := $(wildcard $(NORM_RULE_DEF_DIR)/*.yaml)
45+
46+
# Add -t to each normative tag input filename and add prefix of "/" to make into absolute pathname.
47+
NORM_TAG_FILE_ARGS := $(foreach relative_pname,$(BUILT_NORM_TAGS),-t /$(relative_pname))
48+
49+
# Add -d to each normative rule definition filename
50+
NORM_RULE_DEF_ARGS := $(foreach relative_pname,$(NORM_RULE_DEF_FILES),-d $(relative_pname))
51+
52+
# Docker stuff
53+
DOCKER_BIN ?= docker
54+
SKIP_DOCKER ?= $(shell if command -v ${DOCKER_BIN} >/dev/null 2>&1 ; then echo false; else echo true; fi)
55+
DOCKER_IMG := riscvintl/riscv-docs-base-container-image:latest
56+
ifneq ($(SKIP_DOCKER),true)
57+
DOCKER_IS_PODMAN = \
58+
$(shell ! ${DOCKER_BIN} -v | grep podman >/dev/null ; echo $$?)
59+
ifeq "$(DOCKER_IS_PODMAN)" "1"
60+
# Modify the SELinux label for the host directory to indicate
61+
# that it can be shared with multiple containers. This is apparently
62+
# only required for Podman, though it is also supported by Docker.
63+
DOCKER_VOL_SUFFIX = :z
64+
DOCKER_EXTRA_VOL_SUFFIX = ,z
65+
else
66+
DOCKER_IS_ROOTLESS = \
67+
$(shell ! ${DOCKER_BIN} info -f '{{println .SecurityOptions}}' | grep rootless >/dev/null ; echo $$?)
68+
ifneq "$(DOCKER_IS_ROOTLESS)" "1"
69+
# Rooted Docker needs this flag so that the files it creates are
70+
# owned by the current user instead of root. Rootless docker does not
71+
# require it, and Podman doesn't either since it is always rootless.
72+
DOCKER_USER_ARG := --user $(shell id -u)
73+
endif
74+
endif
75+
76+
DOCKER_CMD = \
77+
${DOCKER_BIN} run --rm \
78+
-v ${PWD}/$@.workdir:/build${DOCKER_VOL_SUFFIX} \
79+
-v ${PWD}/${CONVERTERS_DIR}:/${CONVERTERS_DIR}:ro${DOCKER_EXTRA_VOL_SUFFIX} \
80+
-v ${PWD}/$(TOOLS_DIR):/$(TOOLS_DIR):ro${DOCKER_EXTRA_VOL_SUFFIX} \
81+
-v ${PWD}/$(TESTS_DIR):/$(TESTS_DIR):ro${DOCKER_EXTRA_VOL_SUFFIX} \
82+
-w /build \
83+
$(DOCKER_USER_ARG) \
84+
${DOCKER_IMG} \
85+
/bin/sh -c
86+
DOCKER_QUOTE := "
87+
else
88+
DOCKER_CMD = \
89+
cd $@.workdir &&
90+
endif
91+
92+
WORKDIR_SETUP = \
93+
rm -rf $@.workdir && \
94+
mkdir -p $@.workdir && \
95+
ln -sfn ../../converters ../../tools ../../tests $@.workdir/
96+
97+
WORKDIR_TEARDOWN = \
98+
mv $@.workdir/$@ $@ && \
99+
rm -rf $@.workdir
100+
101+
ASCIIDOCTOR_TAGS := asciidoctor --backend tags --require=./$(CONVERTERS_DIR)/$(TAGS_BACKEND)
102+
103+
OPTIONS := --trace \
104+
-D build \
105+
--failure-level=WARN
106+
107+
108+
# Default target
109+
.PHONY: all
110+
all: test
111+
112+
# Build tests and compare against expected
113+
.PHONY: test
114+
test: build-tests compare-tests
115+
116+
# Build tests
117+
.PHONY: build-tests build-test-tags build-test-norm-rules
118+
build-tests: build-test-tags build-test-norm-rules
119+
build-test-tags: $(BUILT_NORM_TAGS)
120+
build-test-norm-rules: $(BUILT_NORM_RULES)
121+
122+
# Compare tests against expected
123+
.PHONY: compare-tests
124+
compare-tests: compare-test-tags compare-test-norm-rules
125+
126+
compare-test-tags: $(EXPECTED_NORM_TAGS) $(BUILT_NORM_TAGS)
127+
@echo XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
128+
@echo Comparing $(EXPECTED_NORM_TAGS) to $(BUILT_NORM_TAGS)
129+
@echo XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
130+
diff $(EXPECTED_NORM_TAGS) $(BUILT_NORM_TAGS)
131+
132+
compare-test-norm-rules: $(EXPECTED_NORM_RULES) $(BUILT_NORM_RULES)
133+
@echo XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
134+
@echo Comparing $(EXPECTED_NORM_RULES) to $(BUILT_NORM_RULES)
135+
@echo XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
136+
diff $(EXPECTED_NORM_RULES) $(BUILT_NORM_RULES)
137+
138+
# Update expected files from built files
139+
.PHONY: update-expected
140+
update-expected: update-test-tags update-test-norm-rules
141+
142+
update-test-tags: $(BUILT_NORM_TAGS)
143+
cp -f $(BUILT_NORM_TAGS) $(EXPECTED_NORM_TAGS)
144+
145+
update-test-norm-rules: $(BUILT_NORM_RULES)
146+
cp -f $(BUILT_NORM_RULES) $(EXPECTED_NORM_RULES)
147+
148+
# Build normative tags
149+
$(BUILT_NORM_TAGS): $(NORM_RULE_TESTS_DIR)/$(TEST_ADOC_INPUT_FNAME) $(CONVERTERS_DIR)/$(TAGS_BACKEND)
150+
$(WORKDIR_SETUP)
151+
$(DOCKER_CMD) $(DOCKER_QUOTE) $(ASCIIDOCTOR_TAGS) $(OPTIONS) -a tags-match-prefix='norm:' -a tags-output-suffix='-norm-tags.json' $< $(DOCKER_QUOTE)
152+
$(WORKDIR_TEARDOWN)
153+
154+
# Build normative rules
155+
$(BUILT_NORM_RULES): $(BUILT_NORM_TAGS) $(NORM_RULE_DEF_FILES)
156+
$(WORKDIR_SETUP)
157+
cp -f $(BUILT_NORM_TAGS) $@.workdir
158+
mkdir -p $@.workdir/build
159+
$(DOCKER_CMD) $(DOCKER_QUOTE) ruby $(TOOLS_DIR)/$(CREATE_NORM_RULE_TOOL) $(NORM_TAG_FILE_ARGS) $(NORM_RULE_DEF_ARGS) $@ $(DOCKER_QUOTE)
160+
$(WORKDIR_TEARDOWN)
161+
162+
# Update docker image to latest
163+
docker-pull-latest:
164+
${DOCKER_BIN} pull ${DOCKER_IMG}
165+
166+
clean:
167+
@echo "Cleaning up generated files..."
168+
rm -rf $(BUILD_DIR)
169+
@echo "Cleanup completed."

normative-rules.md

Lines changed: 31 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## What is a Normative Rule?
44

5-
Normative rules specify the behaviors an implementation must meet in order to be compliant with the standard. Each normative rule can be thought of as a complete individual testable behavior. In some cases, normative rules allow a plurality of acceptable implementations. These are called "parameters" and can be thought of as a special case of a normative rule.
5+
Normative rules specify the behaviors an implementation must meet in order to be compliant with the standard. Each normative rule can be thought of as a complete individually testable behavior. In some cases, a normative rule allows multiple acceptable implementation behaviors. These are called "parameters" and can be thought of as a special case of a normative rule.
66

77
### Examples of Normative Rules:
88
| ISA Manual Text |
@@ -46,28 +46,7 @@ AsciiDoc supports several styles of anchors:
4646
>
4747
> `This isn't part of the anchor since it is the next paragraph.`
4848
49-
* You must use the _paragraph anchor_ for table cells, list items, or description list terms
50-
* For table cells and list items, put the anchor before its associated text as follows:
51-
* Table cell<br>
52-
> `| [[foo]] Here are the table cell contents | next cell`
53-
* List item<br>
54-
> `* [[foo]] Here is the list item`
55-
* For description list terms (e.g., `Apples`, `Oranges`), put the anchor immediately after the term on its own line as follows:
56-
> `Apples::`<br>
57-
> `[[apple-colors]]`<br>
58-
> `Typically be red, yellow, or green.`<br>
59-
> <br>
60-
> `Oranges:: Generally orange in color`<br>
61-
> <br>
62-
> `Bananas::`<br>
63-
> `[[banana-color]]`<br>
64-
> `Generally yellow in color`
65-
* These won't work
66-
> * `Bananas:: [[banana-color]] Generally yellow in color`<br>
67-
> * `[[banana-color]] Bananas:: Generally yellow in color`
68-
> * `[[banana-color]]`<br>
69-
> `Bananas::`<br>
70-
> `Generally yellow in color`
49+
* You must use the _paragraph anchor_ for table cells, unordered/ordered list items or description list terms
7150

7251
Naming restrictions:
7352
* Start anchor names with a letter and use `:` to separate fields in the anchor name. No spaces allowed in name.
@@ -80,12 +59,12 @@ If you'd like to get more detailed AsciiDoc information on anchors, please read:
8059
* How to make cross-references: https://docs.asciidoctor.org/asciidoc/latest/macros/xref/
8160
* How to create anchors: https://docs.asciidoctor.org/asciidoc/latest/attributes/id/
8261

83-
## Adding anchors into AsciiDoc files
84-
1. Anchor to part of a paragraph
62+
## Using AsciiDoc Anchors to Tag Normative Rules
63+
1. Tag part of a paragraph
8564

8665
> Syntax: `[#<anchor-name>]# ... #`<br>
87-
> Example: `Here is an example of [#foo]#anchoring part# of a paragraph
88-
> and can have [#bar]#multiple anchors# if needed.`<br>
66+
> Example: `Here is an example of [#norm:foo]#anchoring part# of a paragraph
67+
> and can have [#norm:bar]#multiple anchors# if needed.`<br>
8968
> Tagged text: `anchoring part` and `multiple anchors`<br>
9069
>
9170
> Limitations:
@@ -95,23 +74,38 @@ If you'd like to get more detailed AsciiDoc information on anchors, please read:
9574
> * Can't put inside admonitions such as [NOTE] (see #5 below for solution).
9675
> * Can't have `.` in anchor-name (replace with `-`)
9776
98-
2. Anchor to entire paragraph
77+
2. Tag entire paragraph
9978

10079
> Syntax: `[[<anchor-name]]`<br>
101-
> Example: `[[zort]]`<br>
80+
> Example: `[[norm:zort]]`<br>
10281
> `Here is an example of anchoring a whole paragraph.`<br>
10382
> Tagged text: Entire paragraph<br>
10483
105-
3. Anchor to entire table cell, list entry, or description list entry
84+
3. Tag tables, unordered lists (AKA bullet), or ordered lists (AKA numbered)
85+
* Don't have acceptable solution right now (see https://github.com/riscv/docs-resources/issues/72)
10686

107-
> Example: `| Alan Turing | [[Alan_Turing_Birthday]] June 23, 1912 | London`<br>
108-
> Tagged text: None (just creates hyperlink to anchor in table/list so not so useful)
109-
>
110-
> Limitations:
111-
> * Anchor must be to entire contents of cell/item.
112-
> * Only one anchor per cell/item.
87+
> Example: `| Alan Turing | [[norm:Alan_Turing_Birthday]] June 23, 1912 | London`<br>
88+
> Won't create a tag (just creates hyperlink to anchor in table/list entry so not so useful)
89+
90+
4. Tag description lists
91+
* For description list terms (e.g., `Apples`, `Oranges`), put the anchor immediately after the term on its own line as follows:
92+
> `Apples::`<br>
93+
> `[[norm:apple-colors]]`<br>
94+
> `Typically be red, yellow, or green.`<br>
95+
> <br>
96+
> `Oranges:: Generally orange in color`<br>
97+
> <br>
98+
> `Bananas::`<br>
99+
> `[[norm:banana-color]]`<br>
100+
> `Generally yellow in color`
101+
* These won't work
102+
> * `Bananas:: [[norm:banana-color]] Generally yellow in color`<br>
103+
> * `[[norm:banana-color]] Bananas:: Generally yellow in color`
104+
> * `[[norm:banana-color]]`<br>
105+
> `Bananas::`<br>
106+
> `Generally yellow in color`
113107
114-
4. Anchor inside admonition (e.g. `[NOTE]`):
108+
5. Tag admonitions (e.g. `[NOTE]`):
115109
* Must use `[[<anchor-name]]` before each paragraph (with unique anchor names of course) being tagged
116110
* Can't use `[#<anchor-name]#Here's some note text.#` since it just shows up in HTML as normal text
117111
* Don't put `[[<<anchor-name]]` before the entire admonition (e.g., before `[NOTE]`) to apply to entire admonition
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
{
2+
"normative_rules": [
3+
{
4+
"name": "inline",
5+
"def_filename": "tests/norm-rule/test.yaml",
6+
"summary": "A few words",
7+
"tags": [
8+
{
9+
"name": "norm:inline",
10+
"text": "inside inline",
11+
"tag_filename": "/build/test-norm-tags.json"
12+
}
13+
]
14+
},
15+
{
16+
"name": "paragraph",
17+
"def_filename": "tests/norm-rule/test.yaml",
18+
"tags": [
19+
{
20+
"name": "norm:para",
21+
"text": "Paragraph anchor",
22+
"tag_filename": "/build/test-norm-tags.json"
23+
}
24+
]
25+
},
26+
{
27+
"name": "note_with_2_tags",
28+
"def_filename": "tests/norm-rule/test.yaml",
29+
"description": "Here's a description.\nIt's got 2 lines.\n",
30+
"tags": [
31+
{
32+
"name": "norm:note-1",
33+
"text": "Multi-paragraph note 1",
34+
"tag_filename": "/build/test-norm-tags.json"
35+
},
36+
{
37+
"name": "norm:note-3",
38+
"text": "Multi-paragraph note 3",
39+
"tag_filename": "/build/test-norm-tags.json"
40+
}
41+
]
42+
},
43+
{
44+
"name": "desc1",
45+
"def_filename": "tests/norm-rule/test.yaml",
46+
"tags": [
47+
{
48+
"name": "norm:description-item-1",
49+
"text": "Description Item 1",
50+
"tag_filename": "/build/test-norm-tags.json"
51+
},
52+
{
53+
"name": "norm:description-item-3",
54+
"text": "Description Item 3",
55+
"tag_filename": "/build/test-norm-tags.json"
56+
}
57+
]
58+
},
59+
{
60+
"name": "desc2",
61+
"def_filename": "tests/norm-rule/test.yaml",
62+
"tags": [
63+
{
64+
"name": "norm:description-item-1",
65+
"text": "Description Item 1",
66+
"tag_filename": "/build/test-norm-tags.json"
67+
},
68+
{
69+
"name": "norm:description-item-3",
70+
"text": "Description Item 3",
71+
"tag_filename": "/build/test-norm-tags.json"
72+
}
73+
]
74+
}
75+
]
76+
}

0 commit comments

Comments
 (0)