mirror of https://github.com/dirtbags/moth.git
puzzle.json: move Pre and Post out to top-level
This commit is contained in:
parent
2e0dfb601a
commit
1fffeb0060
|
@ -15,13 +15,12 @@ import (
|
|||
var testMothYaml = []byte(`---
|
||||
answers:
|
||||
- YAML answer
|
||||
pre:
|
||||
authors:
|
||||
- Arthur
|
||||
- Buster
|
||||
- DW
|
||||
attachments:
|
||||
- filename: moo.txt
|
||||
authors:
|
||||
- Arthur
|
||||
- Buster
|
||||
- DW
|
||||
attachments:
|
||||
- filename: moo.txt
|
||||
---
|
||||
YAML body
|
||||
`)
|
||||
|
|
|
@ -11,10 +11,8 @@ case $1:$2 in
|
|||
cat <<EOT
|
||||
{
|
||||
"Answers": ["$answer"],
|
||||
"Pre": {
|
||||
"Authors": ["neale"],
|
||||
"Body": "I am a generated puzzle."
|
||||
}
|
||||
"Authors": ["neale"],
|
||||
"Body": "I am a generated puzzle."
|
||||
}
|
||||
EOT
|
||||
;;
|
||||
|
|
|
@ -18,10 +18,8 @@ EOT
|
|||
cat <<EOT
|
||||
{
|
||||
"Answers": ["answer1.0"],
|
||||
"Pre": {
|
||||
"Authors": ["author1.0"],
|
||||
"Body": "<h1>moo.</h1>"
|
||||
}
|
||||
"Authors": ["author1.0"],
|
||||
"Body": "<h1>moo.</h1>"
|
||||
}
|
||||
EOT
|
||||
;;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
---
|
||||
pre:
|
||||
authors:
|
||||
- neale
|
||||
authors:
|
||||
- neale
|
||||
debug:
|
||||
summary: static puzzles
|
||||
answers:
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
---
|
||||
pre:
|
||||
authors:
|
||||
- neale
|
||||
authors:
|
||||
- neale
|
||||
debug:
|
||||
summary: Making excellent puzzles
|
||||
answers:
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
---
|
||||
pre:
|
||||
authors:
|
||||
- neale
|
||||
attachments:
|
||||
- filename: salad.jpg
|
||||
- filename: s2.jpg
|
||||
filesystempath: salad2.jpg
|
||||
authors:
|
||||
- neale
|
||||
attachments:
|
||||
- filename: salad.jpg
|
||||
- filename: s2.jpg
|
||||
filesystempath: salad2.jpg
|
||||
debug:
|
||||
summary: Static puzzle resource files
|
||||
answers:
|
||||
|
|
|
@ -15,15 +15,13 @@ answer = ' '.join(random.sample(words, 4))
|
|||
def puzzle():
|
||||
number = random.randint(20, 500)
|
||||
obj = {
|
||||
"Pre": {
|
||||
"Authors": ["neale"],
|
||||
"Body": (
|
||||
"<p>Dynamic puzzles are provided with a JSON-generating <code>mkpuzzles</code> program in the puzzle directory.</p>"
|
||||
"<p>You can write <code>mkpuzzles</code> in any language you like. This puzzle was written in Python 3.</p>"
|
||||
"<p>Here is some salad:<img src='salad.jpg'></p>"
|
||||
),
|
||||
"Attachments": ["salad.jpg"],
|
||||
},
|
||||
"Authors": ["neale"],
|
||||
"Body": (
|
||||
"<p>Dynamic puzzles are provided with a JSON-generating <code>mkpuzzles</code> program in the puzzle directory.</p>"
|
||||
"<p>You can write <code>mkpuzzles</code> in any language you like. This puzzle was written in Python 3.</p>"
|
||||
"<p>Here is some salad:<img src='salad.jpg'></p>"
|
||||
),
|
||||
"Attachments": ["salad.jpg"],
|
||||
"Answers": [
|
||||
answer,
|
||||
],
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
---
|
||||
pre:
|
||||
authors:
|
||||
- neale
|
||||
scripts:
|
||||
- filename: helpers.js
|
||||
- filename: draggable.js
|
||||
authors:
|
||||
- neale
|
||||
scripts:
|
||||
- filename: helpers.js
|
||||
- filename: draggable.js
|
||||
answers:
|
||||
- helper
|
||||
debug:
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
---
|
||||
pre:
|
||||
authors: ["neale"]
|
||||
authors: ["neale"]
|
||||
answers: ["6"]
|
||||
---
|
||||
This category shows off how to use the transpiler from an
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
---
|
||||
pre:
|
||||
authors: ["neale"]
|
||||
authors: ["neale"]
|
||||
answers: ["C", "c"]
|
||||
---
|
||||
2 4 6 8 A _
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
---
|
||||
pre:
|
||||
authors: ["neale"]
|
||||
authors: ["neale"]
|
||||
answers: ["17"]
|
||||
---
|
||||
1 2 3 5 7 11 13 _
|
||||
|
|
|
@ -59,16 +59,16 @@ func TestOsFsCategory(t *testing.T) {
|
|||
|
||||
if p, err := static.Puzzle(1); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(p.Pre.Authors) != 1 {
|
||||
t.Error("Wrong authors list", p.Pre.Authors)
|
||||
} else if p.Pre.Authors[0] != "neale" {
|
||||
t.Error("Wrong authors", p.Pre.Authors)
|
||||
} else if len(p.Authors) != 1 {
|
||||
t.Error("Wrong authors list", p.Authors)
|
||||
} else if p.Authors[0] != "neale" {
|
||||
t.Error("Wrong authors", p.Authors)
|
||||
}
|
||||
|
||||
if p, err := static.Puzzle(3); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(p.Pre.Authors) != 1 {
|
||||
t.Error("Wrong authors", p.Pre.Authors)
|
||||
} else if len(p.Authors) != 1 {
|
||||
t.Error("Wrong authors", p.Authors)
|
||||
}
|
||||
|
||||
generated := NewFsCategory(fs, "generated")
|
||||
|
|
|
@ -7,13 +7,12 @@ import (
|
|||
var testMothYaml = []byte(`---
|
||||
answers:
|
||||
- YAML answer
|
||||
pre:
|
||||
authors:
|
||||
- Arthur
|
||||
- Buster
|
||||
- DW
|
||||
attachments:
|
||||
- moo.txt
|
||||
authors:
|
||||
- Arthur
|
||||
- Buster
|
||||
- DW
|
||||
attachments:
|
||||
- moo.txt
|
||||
---
|
||||
YAML body
|
||||
`)
|
||||
|
@ -27,9 +26,8 @@ RFC822 body
|
|||
var testMothMarkdown = []byte(`---
|
||||
answers:
|
||||
- answer
|
||||
pre:
|
||||
authors:
|
||||
- Fred
|
||||
authors:
|
||||
- Fred
|
||||
---
|
||||
|
||||
one | two
|
||||
|
|
|
@ -53,7 +53,7 @@ func Mothball(c Category, w io.Writer) error {
|
|||
}
|
||||
|
||||
// Write out all attachments and scripts
|
||||
attachments := append(puzzle.Pre.Attachments, puzzle.Pre.Scripts...)
|
||||
attachments := append(puzzle.Attachments, puzzle.Scripts...)
|
||||
for _, att := range attachments {
|
||||
attPath := fmt.Sprintf("%d/%s", points, att)
|
||||
aw, err := zf.Create(attPath)
|
||||
|
|
|
@ -32,28 +32,26 @@ type AnswerResponse struct {
|
|||
|
||||
// Puzzle contains everything about a puzzle that a client would see.
|
||||
type Puzzle struct {
|
||||
Pre struct {
|
||||
Authors []string
|
||||
Attachments []string
|
||||
Scripts []string
|
||||
Body string
|
||||
AnswerPattern string
|
||||
AnswerHashes []string
|
||||
}
|
||||
Post struct {
|
||||
Objective string
|
||||
Success struct {
|
||||
Acceptable string
|
||||
Mastery string
|
||||
}
|
||||
KSAs []string
|
||||
}
|
||||
Debug struct {
|
||||
Log []string
|
||||
Errors []string
|
||||
Hints []string
|
||||
Summary string
|
||||
}
|
||||
Authors []string
|
||||
Attachments []string
|
||||
Scripts []string
|
||||
Body string
|
||||
AnswerPattern string
|
||||
AnswerHashes []string
|
||||
Objective string
|
||||
KSAs []string
|
||||
Success struct {
|
||||
Acceptable string
|
||||
Mastery string
|
||||
}
|
||||
|
||||
// Answers will be empty in a mothball
|
||||
Answers []string
|
||||
}
|
||||
|
||||
|
@ -61,30 +59,26 @@ func (puzzle *Puzzle) computeAnswerHashes() {
|
|||
if len(puzzle.Answers) == 0 {
|
||||
return
|
||||
}
|
||||
puzzle.Pre.AnswerHashes = make([]string, len(puzzle.Answers))
|
||||
puzzle.AnswerHashes = make([]string, len(puzzle.Answers))
|
||||
for i, answer := range puzzle.Answers {
|
||||
sum := sha256.Sum256([]byte(answer))
|
||||
hexsum := fmt.Sprintf("%x", sum)
|
||||
puzzle.Pre.AnswerHashes[i] = hexsum
|
||||
puzzle.AnswerHashes[i] = hexsum
|
||||
}
|
||||
}
|
||||
|
||||
// StaticPuzzle contains everything a static puzzle might tell us.
|
||||
type StaticPuzzle struct {
|
||||
Pre struct {
|
||||
Authors []string
|
||||
Attachments []StaticAttachment
|
||||
Scripts []StaticAttachment
|
||||
AnswerPattern string
|
||||
}
|
||||
Post struct {
|
||||
Objective string
|
||||
Success struct {
|
||||
Acceptable string
|
||||
Mastery string
|
||||
}
|
||||
KSAs []string
|
||||
Authors []string
|
||||
Attachments []StaticAttachment
|
||||
Scripts []StaticAttachment
|
||||
AnswerPattern string
|
||||
Objective string
|
||||
Success struct {
|
||||
Acceptable string
|
||||
Mastery string
|
||||
}
|
||||
KSAs []string
|
||||
Debug struct {
|
||||
Log []string
|
||||
Errors []string
|
||||
|
@ -187,7 +181,7 @@ type FsPuzzle struct {
|
|||
|
||||
// Puzzle returns a Puzzle struct for the current puzzle.
|
||||
func (fp FsPuzzle) Puzzle() (Puzzle, error) {
|
||||
var puzzle Puzzle
|
||||
puzzle := Puzzle{}
|
||||
|
||||
static, body, err := fp.staticPuzzle()
|
||||
if err != nil {
|
||||
|
@ -195,20 +189,21 @@ func (fp FsPuzzle) Puzzle() (Puzzle, error) {
|
|||
}
|
||||
|
||||
// Convert to an exportable Puzzle
|
||||
puzzle.Post = static.Post
|
||||
puzzle.Debug = static.Debug
|
||||
puzzle.Answers = static.Answers
|
||||
puzzle.Pre.Authors = static.Pre.Authors
|
||||
puzzle.Pre.Body = string(body)
|
||||
puzzle.Pre.AnswerPattern = static.Pre.AnswerPattern
|
||||
puzzle.Pre.Attachments = make([]string, len(static.Pre.Attachments))
|
||||
for i, attachment := range static.Pre.Attachments {
|
||||
puzzle.Pre.Attachments[i] = attachment.Filename
|
||||
puzzle.Authors = static.Authors
|
||||
puzzle.Body = string(body)
|
||||
puzzle.AnswerPattern = static.AnswerPattern
|
||||
puzzle.Attachments = make([]string, len(static.Attachments))
|
||||
for i, attachment := range static.Attachments {
|
||||
puzzle.Attachments[i] = attachment.Filename
|
||||
}
|
||||
puzzle.Pre.Scripts = make([]string, len(static.Pre.Scripts))
|
||||
for i, script := range static.Pre.Scripts {
|
||||
puzzle.Pre.Scripts[i] = script.Filename
|
||||
puzzle.Scripts = make([]string, len(static.Scripts))
|
||||
for i, script := range static.Scripts {
|
||||
puzzle.Scripts[i] = script.Filename
|
||||
}
|
||||
empty := Puzzle{}
|
||||
puzzle.Debug = empty.Debug
|
||||
puzzle.computeAnswerHashes()
|
||||
|
||||
return puzzle, nil
|
||||
|
@ -223,7 +218,7 @@ func (fp FsPuzzle) Open(name string) (ReadSeekCloser, error) {
|
|||
}
|
||||
|
||||
var fsPath string
|
||||
for _, attachment := range append(static.Pre.Attachments, static.Pre.Scripts...) {
|
||||
for _, attachment := range append(static.Attachments, static.Scripts...) {
|
||||
if attachment.Filename == name {
|
||||
if attachment.FilesystemPath == "" {
|
||||
fsPath = attachment.Filename
|
||||
|
@ -337,13 +332,13 @@ func rfc822HeaderParser(r io.Reader) (StaticPuzzle, error) {
|
|||
key = strings.ToLower(key)
|
||||
switch key {
|
||||
case "author":
|
||||
p.Pre.Authors = val
|
||||
p.Authors = val
|
||||
case "pattern":
|
||||
p.Pre.AnswerPattern = val[0]
|
||||
p.AnswerPattern = val[0]
|
||||
case "script":
|
||||
p.Pre.Scripts = legacyAttachmentParser(val)
|
||||
p.Scripts = legacyAttachmentParser(val)
|
||||
case "file":
|
||||
p.Pre.Attachments = legacyAttachmentParser(val)
|
||||
p.Attachments = legacyAttachmentParser(val)
|
||||
case "answer":
|
||||
p.Answers = val
|
||||
case "summary":
|
||||
|
@ -353,13 +348,13 @@ func rfc822HeaderParser(r io.Reader) (StaticPuzzle, error) {
|
|||
case "solution":
|
||||
p.Debug.Hints = val
|
||||
case "ksa":
|
||||
p.Post.KSAs = val
|
||||
p.KSAs = val
|
||||
case "objective":
|
||||
p.Post.Objective = val[0]
|
||||
p.Objective = val[0]
|
||||
case "success.acceptable":
|
||||
p.Post.Success.Acceptable = val[0]
|
||||
p.Success.Acceptable = val[0]
|
||||
case "success.mastery":
|
||||
p.Post.Success.Mastery = val[0]
|
||||
p.Success.Mastery = val[0]
|
||||
default:
|
||||
return p, fmt.Errorf("Unknown header field: %s", key)
|
||||
}
|
||||
|
|
|
@ -23,11 +23,11 @@ func TestPuzzle(t *testing.T) {
|
|||
if (len(p.Answers) == 0) || (p.Answers[0] != "YAML answer") {
|
||||
t.Error("Answers are wrong", p.Answers)
|
||||
}
|
||||
if (len(p.Pre.Authors) != 3) || (p.Pre.Authors[1] != "Buster") {
|
||||
t.Error("Authors are wrong", p.Pre.Authors)
|
||||
if (len(p.Authors) != 3) || (p.Authors[1] != "Buster") {
|
||||
t.Error("Authors are wrong", p.Authors)
|
||||
}
|
||||
if p.Pre.Body != "<p>YAML body</p>\n" {
|
||||
t.Errorf("Body parsed wrong: %#v", p.Pre.Body)
|
||||
if p.Body != "<p>YAML body</p>\n" {
|
||||
t.Errorf("Body parsed wrong: %#v", p.Body)
|
||||
}
|
||||
|
||||
f, err := pd.Open("moo.txt")
|
||||
|
@ -52,11 +52,11 @@ func TestPuzzle(t *testing.T) {
|
|||
if (len(p.Answers) == 0) || (p.Answers[0] != "RFC822 answer") {
|
||||
t.Error("Answers are wrong", p.Answers)
|
||||
}
|
||||
if (len(p.Pre.Authors) != 3) || (p.Pre.Authors[1] != "Arthur") {
|
||||
t.Error("Authors are wrong", p.Pre.Authors)
|
||||
if (len(p.Authors) != 3) || (p.Authors[1] != "Arthur") {
|
||||
t.Error("Authors are wrong", p.Authors)
|
||||
}
|
||||
if p.Pre.Body != "<p>RFC822 body</p>\n" {
|
||||
t.Errorf("Body parsed wrong: %#v", p.Pre.Body)
|
||||
if p.Body != "<p>RFC822 body</p>\n" {
|
||||
t.Errorf("Body parsed wrong: %#v", p.Body)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,9 +66,9 @@ func TestPuzzle(t *testing.T) {
|
|||
|
||||
if puzzle, err := NewFsPuzzlePoints(catFs, 4).Puzzle(); err != nil {
|
||||
t.Error("Markdown test file:", err)
|
||||
} else if !strings.Contains(puzzle.Pre.Body, "<table>") {
|
||||
} else if !strings.Contains(puzzle.Body, "<table>") {
|
||||
t.Error("Markdown table extension isn't making tables")
|
||||
} else if !strings.Contains(puzzle.Pre.Body, "<dl>") {
|
||||
} else if !strings.Contains(puzzle.Body, "<dl>") {
|
||||
t.Error("Markdown dictionary extension isn't making tables")
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,7 @@ func TestFsPuzzle(t *testing.T) {
|
|||
|
||||
if puzzle, err := NewFsPuzzlePoints(catFs, 2).Puzzle(); err != nil {
|
||||
t.Error(err)
|
||||
} else if !strings.Contains(puzzle.Pre.Body, "class=\"moo\"") {
|
||||
} else if !strings.Contains(puzzle.Body, "class=\"moo\"") {
|
||||
t.Error("Raw HTML didn't make it through")
|
||||
}
|
||||
|
||||
|
@ -150,11 +150,10 @@ func TestFsPuzzle(t *testing.T) {
|
|||
|
||||
func TestAttachment(t *testing.T) {
|
||||
buf := bytes.NewBufferString(`
|
||||
pre:
|
||||
attachments:
|
||||
- simple
|
||||
- filename: complex
|
||||
filesystempath: backingfile
|
||||
attachments:
|
||||
- simple
|
||||
- filename: complex
|
||||
filesystempath: backingfile
|
||||
`)
|
||||
p, err := yamlHeaderParser(buf)
|
||||
if err != nil {
|
||||
|
@ -162,7 +161,7 @@ pre:
|
|||
return
|
||||
}
|
||||
|
||||
att := p.Pre.Attachments
|
||||
att := p.Attachments
|
||||
if len(att) != 2 {
|
||||
t.Error("Wrong number of attachments", att)
|
||||
}
|
||||
|
|
|
@ -18,10 +18,8 @@ EOT
|
|||
cat <<EOT
|
||||
{
|
||||
"Answers": ["answer1.0"],
|
||||
"Pre": {
|
||||
"Authors": ["author1.0"],
|
||||
"Body": "<h1>moo.</h1>"
|
||||
}
|
||||
"Authors": ["author1.0"],
|
||||
"Body": "<h1>moo.</h1>"
|
||||
}
|
||||
EOT
|
||||
;;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
---
|
||||
pre:
|
||||
authors:
|
||||
- neale
|
||||
authors:
|
||||
- neale
|
||||
answers:
|
||||
- moo
|
||||
---
|
||||
|
|
|
@ -10,10 +10,8 @@ case $1:$2 in
|
|||
cat <<'EOT'
|
||||
{
|
||||
"Answers": ["answer"],
|
||||
"Pre": {
|
||||
"Authors": ["neale"],
|
||||
"Body": "I am a generated puzzle."
|
||||
}
|
||||
"Authors": ["neale"],
|
||||
"Body": "I am a generated puzzle."
|
||||
}
|
||||
EOT
|
||||
;;
|
||||
|
|
Loading…
Reference in New Issue