-- major tests for drawings -- We minimize assumptions about specific pixels, and try to test at the level -- of specific shapes. In particular, no tests of freehand drawings. function test_creating_drawing_saves() App.screen.init{width=120, height=60} Editor_state = edit.initialize_test_state() Editor_state.filename = 'foo' Editor_state.lines = load_array{} Text.redraw_all(Editor_state) edit.draw(Editor_state) -- click on button to create drawing edit.run_after_mouse_click(Editor_state, 8,Editor_state.top+8, 1) -- file not immediately saved edit.update(Editor_state, 0.01) check_nil(App.filesystem['foo'], 'early') -- wait until save Current_time = Current_time + 3.1 edit.update(Editor_state, 0) -- filesystem contains drawing and an empty line of text check_eq(App.filesystem['foo'], '```lines\n```\n\n', 'check') end function test_draw_line() -- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end) App.screen.init{width=Test_margin_left+256, height=300} -- drawing coordinates 1:1 with pixels Editor_state = edit.initialize_test_state() Editor_state.filename = 'foo' Editor_state.lines = load_array{'```lines', '```', ''} Text.redraw_all(Editor_state) Editor_state.current_drawing_mode = 'line' edit.draw(Editor_state) check_eq(#Editor_state.lines, 2, 'baseline/#lines') check_eq(Editor_state.lines[1].mode, 'drawing', 'baseline/mode') check_eq(Editor_state.line_cache[1].starty, Editor_state.top+Drawing_padding_top, 'baseline/y') check_eq(Editor_state.lines[1].h, 128, 'baseline/y') check_eq(#Editor_state.lines[1].shapes, 0, 'baseline/#shapes') -- draw a line edit.run_after_mouse_press(Editor_state, Editor_state.left+5, Editor_state.top+Drawing_padding_top+6, 1) edit.run_after_mouse_release(Editor_state, Editor_state.left+35, Editor_state.top+Drawing_padding_top+36, 1) local drawing = Editor_state.lines[1] check_eq(#drawing.shapes, 1, '#shapes') check_eq(#drawing.points, 2, '#points') check_eq(drawing.shapes[1].mode, 'line', 'shape:1') local p1 = drawing.points[drawing.shapes[1].p1] local p2 = drawing.points[drawing.shapes[1].p2] check_eq(p1.x, 5, 'p1:x') check_eq(p1.y, 6, 'p1:y') check_eq(p2.x, 35, 'p2:x') check_eq(p2.y, 36, 'p2:y') -- wait until save Current_time = Current_time + 3.1 edit.update(Editor_state, 0) -- The format on disk isn't perfectly stable. Table fields can be reordered. -- So just reload from disk to verify. load_from_disk(Editor_state) Text.redraw_all(Editor_state) local drawing = Editor_state.lines[1] check_eq(#drawing.shapes, 1, 'save/#shapes') check_eq(#drawing.points, 2, 'save/#points') check_eq(drawing.shapes[1].mode, 'line', 'save/shape:1') local p1 = drawing.points[drawing.shapes[1].p1] local p2 = drawing.points[drawing.shapes[1].p2] check_eq(p1.x, 5, 'save/p1:x') check_eq(p1.y, 6, 'save/p1:y') check_eq(p2.x, 35, 'save/p2:x') check_eq(p2.y, 36, 'save/p2:y') end function test_draw_horizontal_line() -- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end) App.screen.init{width=Test_margin_left+256, height=300} -- drawing coordinates 1:1 with pixels Editor_state = edit.initialize_test_state() Editor_state.lines = load_array{'```lines', '```', ''} Text.redraw_all(Editor_state) Editor_state.current_drawing_mode = 'manhattan' edit.draw(Editor_state) check_eq(#Editor_state.lines, 2, 'baseline/#lines') check_eq(Editor_state.lines[1].mode, 'drawing', 'baseline/mode') check_eq(Editor_state.line_cache[1].starty, Editor_state.top+Drawing_padding_top, 'baseline/y') check_eq(Editor_state.lines[1].h, 128, 'baseline/y') check_eq(#Editor_state.lines[1].shapes, 0, 'baseline/#shapes') -- draw a line that is more horizontal than vertical edit.run_after_mouse_press(Editor_state, Editor_state.left+5, Editor_state.top+Drawing_padding_top+6, 1) edit.run_after_mouse_release(Editor_state, Editor_state.left+35, Editor_state.top+Drawing_padding_top+26, 1) local drawing = Editor_state.lines[1] check_eq(#drawing.shapes, 1, '#shapes') check_eq(#drawing.points, 2, '#points') check_eq(drawing.shapes[1].mode, 'manhattan', 'shape_mode') local p1 = drawing.points[drawing.shapes[1].p1] local p2 = drawing.points[drawing.shapes[1].p2] check_eq(p1.x, 5, 'p1:x') check_eq(p1.y, 6, 'p1:y') check_eq(p2.x, 35, 'p2:x') check_eq(p2.y, p1.y, 'p2:y') end function test_draw_circle() -- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end) App.screen.init{width=Test_margin_left+256, height=300} -- drawing coordinates 1:1 with pixels Editor_state = edit.initialize_test_state() Editor_state.lines = load_array{'```lines', '```', ''} Text.redraw_all(Editor_state) Editor_state.current_drawing_mode = 'line' edit.draw(Editor_state) check_eq(#Editor_state.lines, 2, 'baseline/#lines') check_eq(Editor_state.lines[1].mode, 'drawing', 'baseline/mode') check_eq(Editor_state.line_cache[1].starty, Editor_state.top+Drawing_padding_top, 'baseline/y') check_eq(Editor_state.lines[1].h, 128, 'baseline/y') check_eq(#Editor_state.lines[1].shapes, 0, 'baseline/#shapes') -- draw a circle App.mouse_move(Editor_state.left+4, Editor_state.top+Drawing_padding_top+4) -- hover on drawing edit.run_after_keychord(Editor_state, 'C-o') edit.run_after_mouse_press(Editor_state, Editor_state.left+35, Editor_state.top+Drawin
#
#
# The Nim Compiler
# (c) Copyright 2017 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
## The compiler can generate debuginfo to help debuggers in translating back
## from C/C++/JS code to Nim. The data structure has been designed to produce
## something useful with Nim's marshal module.
import sighashes
type
FilenameMapping* = object
package*, file*: string
mangled*: SigHash
EnumDesc* = object
size*: int
owner*: SigHash
id*: int
name*: string
values*: seq[(string, int)]
DebugInfo* = object
version*: int
files*: seq[FilenameMapping]
enums*: seq[EnumDesc]
conflicts*: bool
proc sdbmHash(package, file: string): SigHash =
result = 0
for i in 0..<package.len:
result &= package[i]
result &= '.'
for i in 0..<file.len:
result &= file[i]
proc register*(self: var DebugInfo; package, file: string): SigHash =
result = sdbmHash(package, file)
for f in self.files:
if f.mangled == result:
if f.package == package and f.file == file: return
self.conflicts = true
break
self.files.add(FilenameMapping(package: package, file: file, mangled: result))
proc hasEnum*(self: DebugInfo; ename: string; id: int; owner: SigHash): bool =
for en in self.enums:
if en.owner == owner and en.name == ename and en.id == id: return true
proc registerEnum*(self: var DebugInfo; ed: EnumDesc) =
self.enums.add ed
proc init*(self: var DebugInfo) =
self.version = 1
self.files = @[]
self.enums = @[]
var gDebugInfo*: DebugInfo
debuginfo.init gDebugInfo
import marshal, streams
proc writeDebugInfo*(self: var DebugInfo; file: string) =
let s = newFileStream(file, fmWrite)
store(s, self)
s.close
proc writeDebugInfo*(file: string) = writeDebugInfo(gDebugInfo, file)
proc loadDebugInfo*(self: var DebugInfo; file: string) =
let s = newFileStream(file, fmRead)
load(s, self)
s.close
proc loadDebugInfo*(file: string) = loadDebugInfo(gDebugInfo, file)