aboutsummaryrefslogtreecommitdiffstats
path: root/tests
Commit message (Collapse)AuthorAgeFilesLines
* Add time: now, every timers, floor and %eunhhu2026-09-261-0/+74
| | | | | | | | | | now is the time of the event a handler runs for (milliseconds since 1970, UTC), which a host gives and a script can replay; views cannot read it. input tick = every 1 second declares a timer (ms, second, minute or hour; 1 ms to a day). floor(x) and x % y, taking the divisor's sign as Python does, take times apart. Checked against a Python model over 3,600 random steps; nine diagnostics.
* Declare number and text message fields; check JSON bodieseunhhu2026-09-261-1/+109
| | | | | | | | | input add = message { title: text, points: number } now compiles, with variable fields anywhere and several of them. The served-app checks post 300 random JSON objects (escapes, control bytes, Korean, surrogate pairs, members in any order) and read them back as Python's json module does, with a list of bodies that must be refused and why.
* Check the served app with an owner thread tooeunhhu2026-09-261-12/+17
| | | | | | | The random HTTP requests against the model and the kill -9 while clients post also run with three connection threads handing requests to the app's owner.
* Check an app served by its views and inputseunhhu2026-09-261-0/+174
| | | | | | | | | A keyed-list app is served by pure-serve and driven by random POSTs (a message with query fields and a body, a text, a key) and GETs (a number, a text, pages of a table): statuses, fault names, bodies and JSON rows match a Python model, and every acknowledged event survives a restart and a kill -9 while six clients post.
* Add keyed lists and text comparisoneunhhu2026-09-261-0/+147
| | | | | | | | | | | | | state xs: list of R by field keeps its items in that field's order, each key once: xs.add(R { ... }) places an item (a taken key fails the event with exists), xs[key] finds one by halving (its field, or its index), xs.has(key) asks, xs.remove(key) removes. append and insert are refused on a keyed list, add on another, and a key field is never assigned. Texts compare with == != < <= > >= by their bytes. Checked against a Python model over 3,600 random steps with a text-keyed and a number-keyed list; 13 diagnostics; examples/tally.aup.
* Add aup watch: build again when what a build read changeseunhhu2026-09-261-0/+86
| | | | | | | | | | A build records every path it opened or looked for and a digest of the bytes there, so a rebuild happens exactly when one of them reads differently: the source, a library (the one with the error too), or a library appearing where one was searched. A change is built once it reads the same twice in a row, so a file caught halfway through being written is never built; the module is replaced whole through a rename.
* Find an item with first(t in tasks where ...)eunhhu2026-09-261-2/+10
| | | | | | | | | | first(item in list [where condition]) is the index of the first item the condition keeps, typed as an index of that list: at = first(...), a field through first(...).title, or its .position. With no such item a view has no value and a handler fails not_found. A fold's result now takes member access like a call's. The random model check jumps to the first open task and shows its position; one diagnostic joins.
* Filter a table view with whereeunhhu2026-09-261-4/+13
| | | | | | | | | | | view open_list = each t in tasks where !t.done { ... } has a row for each item the condition keeps, in the list's order; the condition compiles to the table's filter block, generated like a column so it reads the row's item, and the view entry names the list in the byte after its type. A count, sum, max or min inside the condition is a compile error, as Pure refuses a fold in a filter. The random model check now compares a filtered table too; two diagnostics join.
* Add count, sum, max and min over a listeunhhu2026-09-261-0/+86
| | | | | | | | | | | | | | | count(t in tasks where !t.done), sum(t.points for t in tasks), and max and min in the same form compile to Pure's FOLD: the value and the where condition become a block run once per item, as a column of the list, so views count and add without a copy of the list or a state kept in step. max(a, b), min(a, b) and fns of the same names stay calls, told apart by the `for` after the first expression or the `name in` after count(. Inside the block only its item and states can be read; a parameter of the fn outside, the enclosing column's row, dt and a fold inside a fold are compile errors that say why. The checks run 3,600 random steps against a Python model and add seven diagnostics.
* Declare marks: cursors that stay before inserted texteunhhu2026-09-261-1/+2
| | | | | | | | `state from: mark in note` is a cursor that stays before text inserted at its position; `cursor in` goes after it, as a caret does. Everything a cursor takes, a mark takes too. The notes example's mark is now one, and its reference model agrees: typing at the mark leaves it in place.
* Check that lent answers count against the budgeteunhhu2026-09-261-2/+44
| | | | | | | Two readers that stop reading keep one 1 MiB answer each waiting on their sockets; a third read must get 503 payload_budget until one of them goes.
* Check that reads lend a stable versioneunhhu2026-09-261-2/+35
| | | | | | A 1 MiB read sent over a slow socket must carry the version it read while the document is replaced five times meanwhile.
* Check the module server on three shardseunhhu2026-09-261-10/+13
| | | | | | Server parity and the kill -9 durability check also run with pure-serve --threads 3.
* Check pure-serve, pipelined connections includedeunhhu2026-09-261-6/+65
| | | | | | | | The server checks run pure-serve, which replaced the module mode of the old document server. A keep-alive client and pipelined requests (sent in one write, and in writes that cut heads and bodies) must get the same answers, in order, as separate connections.
* Check the module server and saving in burstseunhhu2026-09-261-3/+153
| | | | | | | | | | The HTTP document server running editor.aup must answer random requests exactly as the server running editor.pure (status, revision, error and body); concurrent edits must share commits; and every edit it acknowledged must survive kill -9. Every other stored run of the list app and the text editor saves in bursts and still matches its reference model across restarts.
* Check declared state across restartseunhhu2026-09-251-0/+60
| | | | | | | | The list app and the text editor run on a tree store through pure-run --store, restarting at random points, and must keep matching their reference models. The language notes state that a declared state is a stored state when the host gives a store.
* Add fns and librarieseunhhu2026-09-251-1/+66
| | | | | | | | | | | | | | | | fn name(params) = value declares one expression, inlined where it is called: arguments are computed once onto the stack and the body reads them with PICK, so a fn costs no runtime call and keeps Pure's bound on work. Parameters take any kind of value; recursion is a compile error. use name reads name.aup beside the source or from AUP_PATH. A library declares only fns and uses, sees only its parameters, and is called as name.fn(...). Diagnostics now carry the file they are in, and the compiler takes a loader so that sources come from the host. examples/words.aup is such a library; examples/tasks.aup uses it and still matches its reference model.
* Add conditional expressions and table viewseunhhu2026-09-251-6/+61
| | | | | | | | | | | | | | | | | if c { a } else { b }, with else-if chains, is an expression anywhere a value goes. Only the chosen branch runs, every branch gives the same type, and nesting that would pass Pure's limit of 8 value-carrying joins is a compile error. view name = each row in list { column = value ... } declares a table with a row per item; columns read their row as an index of the list. An index now reads and writes its item's fields directly (at.title, at.done = 1), so 'position' cannot name a record field. examples/tasks.aup gains conditional views and a board table and still matches its reference model; a new check confirms the unchosen branch is never computed.
* Add records, lists and indiceseunhhu2026-09-251-0/+133
| | | | | | | | | | | | | | A record declares named number and text fields with defaults. A list of a record is runtime-owned state, and an index of a list always names one of its items: it follows its item across inserts and removes and stops at the ends. Items are read and changed by field (tasks[at].title), appended or inserted as record values whose missing fields take defaults, and removed by index. Using an index of another list is a compile error. examples/tasks.aup matches a Python reference model over 4,800 random steps, including events that fail on an empty list. Replacing it with a module whose record gained and reordered fields keeps every item.
* Compile text, cursors and strings to module v3eunhhu2026-09-251-3/+127
| | | | | | | | | | | | | | | | | aup now emits Pure module v3 and adds text states with string initializers, cursors bound to a text, text inputs, string literals with escapes and {interpolation} of numbers and text, cursor distances in chars and lines, .start/.end, insert/remove, name.line(cursor), .chars/.lines/.bytes on text, .chars/.line on cursors, and text(bytes)/bytes(text). Replies and replace accept text as its UTF-8 bytes. Views are numbers or text. Up to 32 inputs. examples/notes.aup is a small editor. make check replays random typing (ASCII, Korean, emoji, combining marks, NUL, newlines), moves and deletions against a Python reference model: 4,800 snapshots of text, cursor, mark and views match. It also checks escapes and number text, 16 new diagnostics, a document loaded into text and saved back, and all earlier parity; the compiler and the Pure executor each pass under ASan/UBSan.
* Compile messages and keyed documents to module v2eunhhu2026-09-251-5/+111
| | | | | | | | | | | | | | | | | | aup now emits Pure module v2 and adds keyed byte collections (state documents: bytes by key), message inputs by key with u32 and a trailing bytes field, on-message handlers, field access, name[key] reads and .bytes sizes, replace(a .. b, value), reply and require, all checked for number/bytes types with file:line:column diagnostics. The document editor and its size-bounded variant are rewritten in aup. make check runs them through pure-edit-module against pure-edit running the original editor.pure programs: 1,280 random show/edit/apply operations, including conflicts, limits, missing documents, budgets and invalid keys, produce byte-identical stdout, stderr and exit codes, and each CLI reads the other's store identically. v0a parity with the workbench engine, 33 diagnostics and generated/damaged programs still pass, also with a sanitizer-built compiler.
* Compile v0a programs to verified Pure moduleseunhhu2026-09-254-0/+327
aup check/build parse states, key inputs, views and handlers (with if/else and else-if), resolve names, generate forward-only stack code and encode a Pure module v1 deterministically. Diagnostics carry file:line:column. make check loads every module with Pure's verifier, checks determinism, 20 diagnostics and accepted forms, replacement by name, 600 generated programs and damaged sources (every emitted module verifies), and replays random event scripts against the workbench Zig engine: 16,667 snapshots across counter, toggle, charge, else-if and fault programs matched, including 921 failed events. The sanitizer-built compiler passes the same checks.