diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 044b4af1..edb7a962 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1362,7 +1362,18 @@ jobs: set -euo pipefail sudo apt-get update sudo apt-get install -y --no-install-recommends \ - p7zip-full ffmpeg poppler-utils inkscape python3-pil python3-yaml gdal-bin + p7zip-full ffmpeg poppler-utils inkscape python3-pil python3-yaml gdal-bin pandoc + + # RTF is read by pandoc, the one of five readers measured that is + # an apt install here (docs/RTF-2026-10-15.md section 6.1). Its + # readings of good files - wrong letters in codepage, a dropped + # character after every letter written literal, hidden text left + # out - are held by the RTF guard as what the settings tell a user, + # and 3.1.3 and 3.7.0.2 read every file of that measurement alike. + # Asked for its version, so a pandoc that did not install stops this + # step rather than turning the RTF guard into a skip. Without a pipe: + # under pipefail a reader that stops early can fail a good install. + pandoc --version # GeoJSON is read by GDAL and its shapes judged by shapely, which is # GEOS underneath (docs/GEOJSON-2026-10-07.md). shapely goes in for diff --git a/CHANGELOG.md b/CHANGELOG.md index 639db696..5a82955b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,27 @@ because it turns other people's test suites red. ### Added +- **Documents: the `rtf` format.** A Rich Text Format document at the exact + size you ask for, read by LibreOffice, pandoc, the RichEdit control of + Windows, striprtf and Apache Tika. It holds headings, paragraphs with bold + and italic words, lists, tables and indented quotes, with the label as its + first paragraph and every line broken after a space - RTF ignores a line + end, so one between two letters would join two words in every reader. + `characters=international` adds paragraphs in Polish, Russian, Japanese and + Arabic, and one with emoji and the characters RTF escapes or names. + `text_encoding` writes their letters four ways, and readers do not agree on + two of them: pandoc shows `codepage` text in the wrong letters and drops + the character after every letter written `literal`. `elements=every` adds + every place a document keeps text a reader may show or leave out - + document properties, a page header and footer, a footnote, a comment, + hidden text, a link, a bookmark and groups a reader has to skip or does not + know - and each part says where it is. LibreOffice and striprtf returned the + same parts, and every other reader a set of its own, with two versions of + pandoc apart as well. `nesting` puts the content up to 10 000 000 groups deep. The + smallest document is 65 B, and the manifest records every setting and the + code page the header declares. A large document is a long one to read: + at 100 MiB pandoc took 95 s and 9.6 GB of memory, and LibreOffice had not + finished after 20 minutes. - **Films: the `webm` format.** A WebM video with an AV1 picture and no sound, at the exact size you ask for, like every other format. Its length is a setting of its own, independent of the size. The picture moves: every @@ -338,6 +359,15 @@ because it turns other people's test suites red. ### Changed +- **`empty-and-minimal` now includes `rtf`.** The preset builds the smallest + file of every format this build has, so with `formats` left at `all` it + gains an `rtf` target of 65 B, and the recipe `tfg preset eject + empty-and-minimal` prints is one target longer. A manifest from a run of + that preset records the hash of that recipe, so its `recipe_hash` differs + from one written before. Every file the preset wrote before is written as + it was, the `rtf` file is the only new one, and a run that names its + `formats` is untouched. + - **The `eml` settings say what Thunderbird and MimeKit do with them.** Measured with Thunderbird 157.0.1 and MimeKit 4.18.1. `charset` says that MimeKit with no code page provider tries UTF-8 and then Latin-1, and reads diff --git a/README.md b/README.md index 092b23c0..cede26e1 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ **Testing Files Generator** is a tool for QA engineers and developers who need real files to test against - an upload form, a parser, anything that takes a file and -has an opinion about it. You pick one of its 30 formats and the size you want, +has an opinion about it. You pick one of its 31 formats and the size you want, and you get **exactly that**: ask for a 10 MB PDF and you get a PDF that a reader will open, at 10 MB to the byte. Every run also leaves a manifest saying **what your system should do with each file**, which is the part other generators leave @@ -36,7 +36,7 @@ needs it finds out it exists. - **Hit an exact size, to the byte** - ask for 10485761 bytes and get exactly that, never a silently rounded file. -- **Write 30 real formats** - a generated PNG opens in an image viewer, a DOCX +- **Write 31 real formats** - a generated PNG opens in an image viewer, a DOCX opens in Word, a ZIP extracts. Not padded zeros with an extension. - **Say what should happen to each file** - the manifest carries an expected outcome, so your test reads the assertion instead of you writing it out. @@ -174,7 +174,7 @@ owns it, at the exact size you asked for: | group | formats | |---|---| -| 📄 **Documents** | `pdf`, `docx` (Word), `xlsx` (Excel), `pptx` (PowerPoint) | +| 📄 **Documents** | `pdf`, `docx` (Word), `xlsx` (Excel), `pptx` (PowerPoint), `rtf` (Rich Text Format) | | 🖼️ **Images** | `png`, `jpg`, `bmp`, `gif`, `ico`, `svg`, `tiff`, `webp`, `avif`, `jxl` | | 📝 **Text and markup** | `txt`, `md`, `csv`, `json`, `xml`, `html`, `log` | | ⚙️ **Configuration** | `yaml`, `toml` | @@ -627,6 +627,7 @@ recipe. `tfg formats ` prints the allowed range or list for each: | `docx` | `paragraphs` | | `xlsx` | `rows`, `columns` | | `pptx` | `slides` | +| `rtf` | `characters`, `text_encoding`, `elements`, `nesting` | | `csv` | `delimiter`, `line_ending`, `header`, `quote_style`, `columns` | | `log` | `entry_format`, `timestamps`, `rate`, `methods`, `status_mix`, `level_mix`, `ip_version`, `line_ending` | | `txt`, `md`, `xml` | `encoding`, `bom` | diff --git a/internal/format/all/all.go b/internal/format/all/all.go index 0f7adfb0..69c4f76a 100644 --- a/internal/format/all/all.go +++ b/internal/format/all/all.go @@ -26,6 +26,7 @@ import ( _ "github.com/donislawdev/TestingFilesGenerator/internal/format/pdf" _ "github.com/donislawdev/TestingFilesGenerator/internal/format/png" _ "github.com/donislawdev/TestingFilesGenerator/internal/format/pptx" + _ "github.com/donislawdev/TestingFilesGenerator/internal/format/rtf" _ "github.com/donislawdev/TestingFilesGenerator/internal/format/svgfile" _ "github.com/donislawdev/TestingFilesGenerator/internal/format/targz" _ "github.com/donislawdev/TestingFilesGenerator/internal/format/tiff" diff --git a/internal/format/rtf/blocks.go b/internal/format/rtf/blocks.go new file mode 100644 index 00000000..11636e00 --- /dev/null +++ b/internal/format/rtf/blocks.go @@ -0,0 +1,196 @@ +package rtf + +import ( + // D11 promises the same bytes from the same seed, so a deliberate, + // reproducible generator is the product rather than a weakness. Nothing + // here ever makes a secret. + // nosemgrep: go.lang.security.audit.crypto.math_random.math-random-used + "math/rand/v2" + "strconv" + + "github.com/donislawdev/TestingFilesGenerator/internal/core" +) + +// The blocks a document is filled with, and the words of the paragraph that +// closes it to the byte. +// +// Every block leaves the document the way it found it: its paragraph closed, +// the paragraph properties reset with \pard, and every change to the letters +// inside a group. So whatever follows starts from the defaults, and the closing +// paragraph can be words and nothing else - a paragraph without \par at the end +// of the document is shown by all five readers measured (docs/RTF-2026-10-15.md +// section 3), which is what lets the closing record be as short as nothing. +// +// A line ends only after a space or after a control word, never between two +// letters. RTF ignores a line end, so one between two letters joins two words +// in every reader - measured in the same section. + +const ( + // lineWidth is where a line of words is broken, well inside the 255 + // characters the specification suggests. + lineWidth = 72 + // endBlock closes a paragraph and resets its properties. + endBlock = `\par\pard` + "\r\n" + // lineBreak is what goes between two words where a line ends. + lineBreak = " \r\n" +) + +// blocks is the record the document is filled with. +type blocks struct{} + +// Append adds one whole block. +func (blocks) Append(dst []byte, rng *rand.Rand) []byte { + switch rng.IntN(6) { + case 0: + // A heading by its outline level, which pandoc and LibreOffice both + // read as a heading without a style sheet (measured 2026-10-15), so the + // header stays as small as it can be. + dst = append(dst, `\outlinelevel1{\b\fs28 `...) + dst = appendTitle(dst, rng, 3) + return append(dst, "}"+endBlock...) + case 1: + return appendList(dst, rng) + case 2: + return appendTable(dst, rng) + case 3: + dst = append(dst, `\li720 `...) + dst = appendWords(dst, rng, 8, false) + return append(dst, endBlock...) + case 4: + dst = appendWords(dst, rng, 20+rng.IntN(20), true) + return append(dst, endBlock...) + default: + dst = appendWords(dst, rng, 20+rng.IntN(20), false) + return append(dst, endBlock...) + } +} + +// AppendExact adds the words of the closing paragraph, exactly n bytes of them. +func (blocks) AppendExact(dst []byte, _ *rand.Rand, n int64) []byte { return appendProse(dst, n) } + +// Shortest is nothing at all: the closing paragraph can be empty. +func (blocks) Shortest() int64 { return 0 } + +// Discard has nothing to undo, since a block counts nothing. +func (blocks) Discard() {} + +// appendList is three to five items, each with the bullet Word writes in front +// of it for a reader that does not know lists. +func appendList(dst []byte, rng *rand.Rand) []byte { + for i, n := 0, 3+rng.IntN(3); i < n; i++ { + dst = append(dst, `{\pntext\bullet\tab}{\*\pn\pnlvlblt\pnindent360{\pntxtb\bullet}}\fi-360\li720 `...) + dst = appendWords(dst, rng, 4+rng.IntN(4), false) + dst = append(dst, `\par`+"\r\n"...) + } + return append(dst, `\pard`+"\r\n"...) +} + +// appendTable is a row of headings and two to four rows under it. +func appendTable(dst []byte, rng *rand.Rand) []byte { + dst = appendRow(dst, "id", "field", "value") + for i, n := 0, 2+rng.IntN(3); i < n; i++ { + dst = appendRow(dst, strconv.Itoa(i+1), word(rng), word(rng)) + } + return append(dst, `\pard`+"\r\n"...) +} + +func appendRow(dst []byte, cells ...string) []byte { + dst = append(dst, `\trowd\cellx3000\cellx6000\cellx9000\pard\intbl `...) + for _, c := range cells { + dst = append(dst, c...) + dst = append(dst, `\cell `...) + } + return append(dst, `\row`+"\r\n"...) +} + +// appendWords is n words, broken into lines at lineWidth, and with styled some +// of them bold or italic, each in a group of its own. +func appendWords(dst []byte, rng *rand.Rand, n int, styled bool) []byte { + col := 0 + for i := 0; i < n; i++ { + w := word(rng) + if i > 0 { + dst, col = appendSpace(dst, col, len(w)) + } + open, closing := styleOf(rng, styled) + dst = append(dst, open...) + dst = append(dst, w...) + dst = append(dst, closing...) + col += len(w) + } + return dst +} + +// styleOf is the group around a styled word, one word in five: bold or italic. +func styleOf(rng *rand.Rand, styled bool) (open, closing string) { + if !styled { + return "", "" + } + switch rng.IntN(10) { + case 0: + return `{\b `, "}" + case 1: + return `{\i `, "}" + } + return "", "" +} + +// appendSpace is what goes in front of a word of length next at column col: +// a space, or a space and a line end once the line is full. +func appendSpace(dst []byte, col, next int) ([]byte, int) { + if col+1+next > lineWidth { + return append(dst, lineBreak...), 0 + } + return append(dst, ' '), col + 1 +} + +// appendTitle is a phrase with each word capitalised, for a heading. +func appendTitle(dst []byte, rng *rand.Rand, n int) []byte { + for i := 0; i < n; i++ { + if i > 0 { + dst = append(dst, ' ') + } + w := word(rng) + // The vocabulary is lower case ASCII, so the first byte is the first + // letter. + dst = append(dst, w[0]-'a'+'A') + dst = append(dst, w[1:]...) + } + return dst +} + +// appendProse is n bytes of words, the lines broken the way appendWords breaks +// them. The cut can land on a space or inside a line end, and both are fine in +// front of the closing braces: RTF ignores the line end, and the space is the +// end of the last word. +func appendProse(dst []byte, n int64) []byte { + col := len(words[0]) + return core.AppendFiller(dst, words, n, func(i int) string { + next := len(words[i%len(words)]) + var sep []byte + sep, col = appendSpace(nil, col, next) + col += next + return string(sep) + }) +} + +func word(rng *rand.Rand) string { return words[rng.IntN(len(words))] } + +// words is the vocabulary: lower case ASCII, so no word holds a character RTF +// escapes and no word starts a control word. +var words = []string{ + "account", "after", "amount", "answer", "before", "between", "branch", + "buffer", "build", "cache", "change", "client", "column", "config", + "content", "create", "default", "delete", "detail", "device", "domain", + "effect", "engine", "entry", "error", "export", "field", "filter", + "folder", "format", "handle", "header", "import", "index", "input", + "insert", "invoice", "layer", "length", "level", "limit", "loader", + "market", "member", "method", "module", "notice", "number", "object", + "option", "output", "packet", "parent", "parser", "period", "policy", + "prefix", "process", "public", "query", "reason", "record", "region", + "report", "result", "return", "sample", "schema", "script", "search", + "sender", "server", "signal", "single", "source", "status", "stream", + "string", "switch", "system", "target", "thread", "ticket", "toggle", + "token", "update", "upload", "vendor", "verify", "version", "volume", + "window", "worker", "writer", +} diff --git a/internal/format/rtf/catalogue.go b/internal/format/rtf/catalogue.go new file mode 100644 index 00000000..c71caad9 --- /dev/null +++ b/internal/format/rtf/catalogue.go @@ -0,0 +1,34 @@ +package rtf + +// The parts elements=every adds - every place a document keeps text that a +// reader may show, leave out or show where it should not. Each sentence says +// where it is, so a test reading what an extractor returned knows which parts +// it took without knowing RTF. Measured on 2026-10-15: six readers, five +// different sets (docs/RTF-2026-10-15.md section 6.1 d). +// +// Two pieces, because RTF fixes where the first one goes: the document +// properties come before any text, and a page header and footer open the +// section they belong to. The rest are paragraphs after the label, each ending +// the way every block does - its paragraph closed and the properties reset - so +// whatever follows starts from the defaults. + +// catalogueHead is what goes in front of the label: the properties of the +// document, and the header and footer of its pages. +const catalogueHead = `{\info{\title This is the title of the document}{\author tfg}{\keywords catalogue rtf}` + + `{\doccomm This is the comment of the document}}` + "\r\n" + + `{\header\pard This sentence is in the page header.\par}` + "\r\n" + + `{\footer\pard This sentence is in the page footer.\par}` + "\r\n" + +// catalogueBody is the paragraphs after the label. The link goes to a domain +// kept for examples (RFC 2606), and a field is never fetched by opening the +// document - a reader that follows it is doing so on a click. +const catalogueBody = `A paragraph with a footnote{\super\chftn}{\footnote\pard\plain{\super\chftn} This sentence is in a footnote.}.\par\pard` + "\r\n" + + `A paragraph with a comment{\*\atnid tfg}{\*\atnauthor tfg}\chatn{\*\annotation\pard\plain This sentence is in a comment.}.\par\pard` + "\r\n" + + `Before hidden text {\v This sentence is hidden text.}and after it.\par\pard` + "\r\n" + + `A link {\field{\*\fldinst HYPERLINK "https://example.com/tfg/link"}{\fldrslt This sentence is the text of a link.}}\par\pard` + "\r\n" + + `A bookmark {\*\bkmkstart tfg_bookmark}around these words{\*\bkmkend tfg_bookmark}.\par\pard` + "\r\n" + + `A group {\*\tfgunknown This sentence is in a group every reader has to skip.}that ends here.\par\pard` + "\r\n" + + `A group {\tfgword This sentence follows a word no reader knows, which is why it shows.} that ends here.\par\pard` + "\r\n" + + `Before a line break\line after it, before a tab\tab after it.\par\pard` + "\r\n" + + `This paragraph ends with a page break.\par\page\pard` + "\r\n" + + `This paragraph ends a section.\par\sect\sectd\pard` + "\r\n" //nolint:misspell // \sect is the RTF control word of a section break, read by misspell as a backslash and "ect" diff --git a/internal/format/rtf/rtf.go b/internal/format/rtf/rtf.go new file mode 100644 index 00000000..7150515c --- /dev/null +++ b/internal/format/rtf/rtf.go @@ -0,0 +1,211 @@ +// Package rtf generates Rich Text Format documents. +// +// Analysed, measured with five readers and decided on 2026-10-15 +// (docs/RTF-2026-10-15.md). The padding channel is the words of the closing +// paragraph: every reader shows them, a system that writes the document again +// keeps them, and a file of a hundred megabytes is then a document that long - +// which is what costs a reader, and what the format card says. A group every +// reader has to skip held the size as well, and a system that rewrites RTF +// throws it away, the argument that decided against the epilogue of a mail +// message. +// +// The readers are tolerant by design: of twelve broken files, the one +// LibreOffice, pandoc and RichEdit all refused was a document without its +// closing brace. So the structure is held by the structural checker, and this +// generator never ends its text in a way that could take the brace away. +package rtf + +import ( + "context" + "fmt" + "io" + "strconv" + + "github.com/donislawdev/TestingFilesGenerator/internal/core" + "github.com/donislawdev/TestingFilesGenerator/internal/format" +) + +const generatorVersion = "1" + +func init() { + format.Register(format.Descriptor{ + ID: "rtf", + Name: "Rich Text Format", + Extension: ".rtf", + MediaType: "application/rtf", // IANA, registered by Paul Lindner, magic number {\rtf + Fidelity: format.FidelityFull, + Determinism: format.DeterminismByte, + + // The header and the font table, which is a whole document with no + // paragraph in it - every one of the five readers opened it. + MinBytes: minimumBytes(), + + Padding: format.PaddingChannel{ + Name: "the words of the closing paragraph", + Where: format.PlacementEnd, + Capacity: 0, + }, + Label: format.LabelVisible, + Oracle: "pandoc-rtf", + Properties: properties(), + GeneratorVersion: generatorVersion, + Generator: generator{}, + }) +} + +type generator struct{} + +type memo struct { + settings settings + seed uint64 + // labelLine is the paragraph that carries the label, empty when absent. + labelLine string +} + +func (generator) Plan(r format.Request) (format.Plan, error) { + s, err := settingsOf(r.Properties) + if err != nil { + return format.Plan{}, err + } + min := s.layout().fixedBytes() + if r.Bytes < min { + return format.Plan{}, belowMinimum(s, r.Bytes, min) + } + + p := format.Plan{ + Bytes: r.Bytes, + Exact: true, + Determinism: format.DeterminismByte, + Properties: s.manifest(), + } + m := memo{settings: s, seed: r.Seed} + if r.Label { + line := labelLine(core.Label("rtf", r.Bytes, r.Seed)) + if min+int64(len(line)) <= r.Bytes { + m.labelLine = line + } else { + p.Notes = append(p.Notes, format.Note{ + Code: "label_omitted", + Detail: core.Says("format.TheLabelNeedsBAndThe", "The label needs %d B and the file is %d B, so this file carries no label. Its name and the manifest still identify it.", core.A("Length", len(line)), core.A("Bytes", r.Bytes)), + }) + } + } + p.Properties[format.PropertyLabelEmbedded] = m.labelLine != "" + p.Memo = m + return p, nil +} + +// labelLine is the paragraph of the label, the first one of the body. Escaped +// the way all text is, so a label that ever held a brace or a backslash could +// not open or close a group. +func labelLine(label string) string { + return string(appendEncoded(nil, label, nil, Unicode)) + `\par` + "\r\n" +} + +// belowMinimum is the refusal of a size too small for these settings. +func belowMinimum(s settings, requested, min int64) error { + reason := core.Says("rtf.MinimumDocument", "a document holds its header and its font table, and the two need that much") + if s.adds() { + reason = core.Says("rtf.MinimumWithSettings", "a document holds its header and its font table and what %s, %s and %s add to them, and together they need that much", + core.A("Characters", core.LabelTerm(Characters)), core.A("Elements", core.LabelTerm(Elements)), core.A("Nesting", core.LabelTerm(Nesting))) + } + return &format.BelowMinimumError{ + Format: "RTF", + Requested: requested, + Minimum: min, + Reason: reason, + Hint: core.Says("format.AskForBOrMore", "Ask for %d B or more.", core.A("Min", min)), + } +} + +func (generator) Write(ctx context.Context, w io.Writer, p format.Plan) error { + m, ok := p.Memo.(memo) + if !ok { + return core.Defect(fmt.Errorf("rtf: the plan was not produced by this generator")) + } + // The label sits outside the groups of nesting, as it does in a page, so + // the file says what it is however deep the content is. + l := m.settings.layout() + if err := core.WriteAll(w, []byte(l.head+m.labelLine)); err != nil { + return err + } + if err := writeBraces(ctx, w, '{', l.levels); err != nil { + return err + } + if err := core.WriteAll(w, []byte(l.body)); err != nil { + return err + } + filled := p.Bytes - l.fixedBytes() - int64(len(m.labelLine)) + if err := core.FillRecords(ctx, w, core.NewRand(m.seed), filled, blocks{}); err != nil { + return err + } + if err := writeBraces(ctx, w, '}', l.levels); err != nil { + return err + } + return core.WriteAll(w, []byte{'}'}) +} + +// layout is what a document of these settings holds whatever its size: the +// header with the font table, and with every the properties, the page header +// and the footer, the groups of nesting, and the paragraphs the settings add. +// The blocks and the closing words go between the paragraphs and the braces +// that close the groups, and the last brace closes the document. +type layout struct { + head string + levels int + body string +} + +func (s settings) layout() layout { + fonts := plainFontTable + if s.international { + fonts = fontTable + } + l := layout{ + head: `{\rtf1\ansi\ansicpg` + strconv.Itoa(declaredCodePage) + `\deff0\uc1` + fonts + "\r\n", + levels: s.nesting, + } + if s.every { + l.head += catalogueHead + } + if s.international { + l.body += international(s.encoding) + } + if s.every { + l.body += catalogueBody + } + return l +} + +// fixedBytes is everything but the label, the blocks and the closing words: the +// smallest document of these settings without its label. +func (l layout) fixedBytes() int64 { + return int64(len(l.head)) + 2*int64(l.levels) + int64(len(l.body)) + 1 +} + +// minimumBytes is the smallest document, which is what the registry declares. +// Every combination of settings answers for its own. +func minimumBytes() int64 { return settings{encoding: Unicode}.layout().fixedBytes() } + +// braceChunk is how many braces are written at once, and so how often a stop +// is noticed - ten million levels are ten megabytes on each side. +const braceChunk = 32 * 1024 + +// writeBraces writes n copies of one brace. +func writeBraces(ctx context.Context, w io.Writer, brace byte, n int) error { + chunk := make([]byte, min(n, braceChunk)) + for i := range chunk { + chunk[i] = brace + } + for n > 0 { + if err := ctx.Err(); err != nil { + return err + } + k := min(n, len(chunk)) + if err := core.WriteAll(w, chunk[:k]); err != nil { + return err + } + n -= k + } + return nil +} diff --git a/internal/format/rtf/settings.go b/internal/format/rtf/settings.go new file mode 100644 index 00000000..e39d87e9 --- /dev/null +++ b/internal/format/rtf/settings.go @@ -0,0 +1,165 @@ +package rtf + +import ( + "strconv" + + "github.com/donislawdev/TestingFilesGenerator/internal/core" + "github.com/donislawdev/TestingFilesGenerator/internal/format" +) + +// The settings of a document and what each of them takes. The names and the +// manifest keys were approved by the owner on 2026-10-15, after the five +// readers behind every sentence below were measured (docs/RTF-2026-10-15.md +// sections 0 and 6.1). They are public names under rule 10. +const ( + Characters = "characters" + ASCII = "ascii" + International = "international" + + TextEncoding = "text_encoding" + Unicode = "unicode" + Both = "both" + Codepage = "codepage" + Literal = "literal" + + Elements = "elements" + Basic = "basic" + Every = "every" + + Nesting = "nesting" + // MaxNesting is where the readers' cost is, rather than where one of them + // loses the content - none did. At 10 000 000 levels LibreOffice took + // 18.5 GB and pandoc 14.5 GB, against about 2 GB each at 1 000 000, and a + // ceiling below that would leave the threshold impossible to order + // (docs/RTF-2026-10-15.md section 6.1 e, the owner's decision the same + // day). The same reasoning as the ceiling of nesting in HTML. + MaxNesting = 10_000_000 + + // CodePage is the manifest key of the code page the header declares. + CodePage = "code_page" +) + +// declaredCodePage is what \ansicpg says. With codepage the fonts carry code +// pages of their own, and this is the one a reader falls back on for a font +// that names none. +const declaredCodePage = 1252 + +// settings is what one document was asked for. +type settings struct { + international bool + // encoding is how the letters outside ASCII are written - one of the four + // values of text_encoding. + encoding string + every bool + nesting int +} + +// properties is the declaration of every setting, in the order both surfaces +// show them: what the text says, how it is written, what the document holds, +// and how deep. +func properties() []format.Property { + return []format.Property{{ + Name: Characters, Kind: format.PropertyChoice, + Choices: []string{ASCII, International}, + Default: ASCII, + Detail: "Whether the document carries text outside ASCII. international adds paragraphs in Polish, Russian, Japanese and Arabic, the Arabic right to left, " + + "and one with emoji, a letter written as two code points, the three characters RTF escapes and the ones it names, such as the dashes and the quotes. " + + "A program without a Japanese or Arabic font shows boxes in their place.", + }, { + Name: TextEncoding, Kind: format.PropertyChoice, + Choices: []string{Unicode, Both, Codepage, Literal}, + Default: Unicode, + Detail: "How the letters outside ASCII are written, which changes nothing while characters is ascii. " + + "unicode writes each one as a number with a question mark after it for a reader that does not know numbers. " + + "both puts the letter in the code page of its font after the number, two bytes for Japanese, the way Word writes it. " + + "codepage writes only the code page bytes, and the emoji still as numbers, since no code page holds them. " + + "literal writes the question mark as a plain character. " + + "LibreOffice, Tika and the RichEdit control of Windows read all four. " + + "pandoc shows codepage text in the wrong letters and drops the character after every letter written literal, and pandoc 3.1 and 3.7 drop the emoji in all four. " + + "striprtf returns an emoji as two halves, which Python refuses to write as UTF-8.", + }, { + Name: Elements, Kind: format.PropertyChoice, + Choices: []string{Basic, Every}, + Default: Basic, + Detail: "Which parts the document uses. basic is headings, paragraphs with bold and italic words, lists, tables and indented quotes. " + + "every adds document properties, a page header and footer, a footnote, a comment, hidden text, a link, a bookmark, " + + "a group every reader has to skip, a word no reader knows and line, tab, page and section breaks, and each part says where it is. " + + "Tika returns the most of them, the header, the footer and the comment among them. " + + "LibreOffice, striprtf and RichEdit return the hidden text as text, RichEdit with the address of the link, " + + "and pandoc returns the footnote and leaves the hidden text out.", + }, { + Name: Nesting, Kind: format.PropertyInt, + Min: 0, Max: MaxNesting, + Default: "0", + Detail: "How many groups the content sits inside, each one inside the last. 0 puts it straight in the document, and the label stays outside so the file still says what it is. " + + "No reader measured lost the content at 10 000 000 levels, but LibreOffice took 18.5 GB of memory over them and pandoc 14.5 GB, against about 2 GB each at 1 000 000.", + }} +} + +// settingsOf reads the settings. +// +// A value outside the declaration has already been refused by the registry, +// which checks every format in one place. The check stays here for the reason +// eml and geojson give: a guard calls Plan directly, and a generator that +// trusts its input is one registry change away from writing a document nobody +// ordered. +func settingsOf(props map[string]string) (settings, error) { + values := map[string]string{} + for _, p := range properties() { + v, err := valueOf(props, p) + if err != nil { + return settings{}, err + } + values[p.Name] = v + } + n, err := strconv.Atoi(values[Nesting]) + if err != nil { + // Allows has already said the value is a whole number in range, so a + // value that still does not parse is this package's mistake. + return settings{}, core.Defect(err) + } + return settings{ + international: values[Characters] == International, + encoding: values[TextEncoding], + every: values[Elements] == Every, + nesting: n, + }, nil +} + +// valueOf is one setting's value, or its default, refused in the declaration's +// own words when the declaration does not allow it. +func valueOf(props map[string]string, p format.Property) (string, error) { + v, ok := props[p.Name] + if !ok || v == "" { + return p.Default, nil + } + if bad := p.Allows(v); !bad.IsZero() { + return "", &format.PropertyValueError{Format: "rtf", Key: p.Name, Value: v, Reason: bad, Remedy: p.Instead()} + } + return v, nil +} + +// manifest is what the manifest records about the settings, every one of them +// whatever was asked, so a reader never has to know a default. +func (s settings) manifest() map[string]any { + chars, elements := ASCII, Basic + if s.international { + chars = International + } + if s.every { + elements = Every + } + return map[string]any{ + Characters: chars, + TextEncoding: s.encoding, + Elements: elements, + Nesting: s.nesting, + CodePage: declaredCodePage, + } +} + +// adds says the settings put something into the document beyond the header, +// which is what the refusal of a size too small has to name. +func (s settings) adds() bool { + return s.international || s.every || s.nesting > 0 +} diff --git a/internal/format/rtf/text.go b/internal/format/rtf/text.go new file mode 100644 index 00000000..db858c63 --- /dev/null +++ b/internal/format/rtf/text.go @@ -0,0 +1,185 @@ +package rtf + +import "strconv" + +// The paragraphs characters=international adds, and the four ways +// text_encoding writes their letters. Each was read by five readers on +// 2026-10-15 before a line of this was written (docs/RTF-2026-10-15.md section +// 6.1 c), and the file this writes is the file they read: the same fonts, the +// same code pages, the same fallback. +// +// Nothing here spells an escape that starts with a backslash and a u followed +// by digits. Those are built from the code point when the file is written, and +// the letters outside ASCII are runes given by number where they would turn a +// line around or vanish (the Arabic, the joiner, the accent), so no tool +// between this file and the compiler can turn an escape into something else. + +// script is one paragraph in another script, in the font that names its code +// page. +type script struct { + font int + text string + // rtl puts the paragraph right to left. + rtl bool + // page is how the font's code page writes each letter of text outside + // ASCII. A letter missing from it is one the code page does not hold. + page map[rune]string +} + +// fontTable is the font table of a document with these paragraphs: Arial in +// four code pages and a Japanese font, each saying its character set the way +// Word does - 0 Western, 238 Central European, 204 Cyrillic, 128 Shift JIS, +// 178 Arabic. +const fontTable = `{\fonttbl{\f0\fswiss\fcharset0 Arial;}{\f1\fswiss\fcharset238 Arial;}{\f2\fswiss\fcharset204 Arial;}` + + `{\f3\fmodern\fcharset128 MS Gothic;}{\f4\fswiss\fcharset178 Arial;}}` + +// plainFontTable is the one font of a document in ASCII. +const plainFontTable = `{\fonttbl{\f0\fswiss Arial;}}` + +func runes(r ...rune) string { return string(r) } + +// scripts are the paragraphs, in the order they are written. The code page +// bytes were taken from Python's codecs cp1250, cp1251, cp932, cp1256 and +// cp1252 on 2026-10-15 rather than from memory, and the structural checker +// decodes every file written in codepage or both with those codecs and holds +// the result to the sentence - so a wrong byte here is a refused file there +// (proven by mutation the same day). +var scripts = []script{ + {font: 1, text: "Zażółć gęślą jaźń.", page: map[rune]string{ + 'ż': "\xbf", 'ó': "\xf3", 'ł': "\xb3", 'ć': "\xe6", 'ę': "\xea", 'ś': "\x9c", 'ą': "\xb9", 'ź': "\x9f", 'ń': "\xf1", + }}, + {font: 2, text: "Это текст на русском языке.", page: map[rune]string{ + 'Э': "\xdd", 'т': "\xf2", 'о': "\xee", 'е': "\xe5", 'к': "\xea", 'с': "\xf1", 'н': "\xed", + 'а': "\xe0", 'р': "\xf0", 'у': "\xf3", 'м': "\xec", 'я': "\xff", 'з': "\xe7", 'ы': "\xfb", + }}, + {font: 3, text: "これは日本語のテキストです。", page: map[rune]string{ + 'こ': "\x82\xb1", 'れ': "\x82\xea", 'は': "\x82\xcd", '日': "\x93\xfa", '本': "\x96\x7b", '語': "\x8c\xea", + 'の': "\x82\xcc", 'テ': "\x83\x65", 'キ': "\x83\x4c", 'ス': "\x83\x58", 'ト': "\x83\x67", 'で': "\x82\xc5", + 'す': "\x82\xb7", '。': "\x81\x42", + }}, + {font: 4, rtl: true, + text: runes(0x647, 0x630, 0x627, ' ', 0x646, 0x635, ' ', 0x628, 0x627, 0x644, 0x644, 0x63A, 0x629, ' ', + 0x627, 0x644, 0x639, 0x631, 0x628, 0x64A, 0x629, '.'), + page: map[rune]string{ + 0x647: "\xe5", 0x630: "\xd0", 0x627: "\xc7", 0x646: "\xe4", 0x635: "\xd5", 0x628: "\xc8", + 0x644: "\xe1", 0x63A: "\xdb", 0x629: "\xc9", 0x639: "\xda", 0x631: "\xd1", 0x64A: "\xed", + }}, + {font: 0, text: "Emoji " + runes(0x1F600) + " and a sequence " + runes(0x1F469, 0x200D, 0x1F4BB) + + ", a letter in two code points e" + runes(0x301) + ", the characters RTF escapes " + `\ { }` + + " and the ones it names " + runes(0x2014, ' ', 0x2013, ' ', 0x2018) + "q" + runes(0x2019, ' ', 0x201C) + "qq" + + runes(0x201D, ' ', 0x2022) + ", a space that does not break" + runes(0xA0) + "and the euro " + runes(0x20AC) + ".", + page: map[rune]string{0x20AC: "\x80"}}, +} + +// named are the characters RTF has a word for. They are written as that word +// whatever text_encoding says, which is what Word does and what the readers +// were measured on. +var named = map[rune]string{ + 0x2014: `\emdash `, 0x2013: `\endash `, 0x2018: `\lquote `, 0x2019: `\rquote `, + 0x201C: `\ldblquote `, 0x201D: `\rdblquote `, 0x2022: `\bullet `, 0xA0: `\~`, +} + +// international is the paragraphs, written the way encoding says, each in a +// group of its own so the font and the count of fallback bytes end with it. +func international(encoding string) string { + var dst []byte + for _, sc := range scripts { + dst = append(dst, `{\pard`...) + if sc.rtl { + dst = append(dst, `\rtlpar`...) + } + dst = append(dst, `\f`...) + dst = strconv.AppendInt(dst, int64(sc.font), 10) + if sc.rtl { + dst = append(dst, `\rtlch`...) + } + dst = append(dst, ' ') + dst = appendEncoded(dst, sc.text, sc.page, encoding) + dst = append(dst, `\par}`+"\r\n"...) + } + return string(dst) +} + +// appendEncoded writes text in one of the four encodings. +func appendEncoded(dst []byte, text string, page map[rune]string, encoding string) []byte { + // The count of fallback bytes a reader skips after a number. Each paragraph + // starts at the 1 the header declares. + uc := 1 + for _, r := range text { + switch { + case r == '\\' || r == '{' || r == '}': + dst = append(dst, '\\', byte(r)) + case r < 0x80: + dst = append(dst, byte(r)) + case named[r] != "": + dst = append(dst, named[r]...) + default: + dst, uc = appendLetter(dst, r, page[r], encoding, uc) + } + } + return dst +} + +// appendLetter writes one letter outside ASCII, and says what the count of +// fallback bytes is after it. +func appendLetter(dst []byte, r rune, inPage, encoding string, uc int) ([]byte, int) { + switch { + case encoding == Codepage && inPage != "": + return appendHex(dst, inPage), uc + case encoding == Literal: + for _, u := range units(r) { + dst = appendNumber(dst, u) + dst = append(dst, '?') + } + return dst, uc + case encoding == Both && inPage != "" && r < 0x10000: + dst, uc = appendCount(dst, len(inPage), uc) + return appendHex(appendNumber(dst, r), inPage), uc + } + // unicode, and every letter no code page holds: the number and a question + // mark written as a byte, which is what LibreOffice writes itself. + dst, uc = appendCount(dst, 1, uc) + for _, u := range units(r) { + dst = appendHex(appendNumber(dst, u), "?") + } + return dst, uc +} + +// appendCount says a new count of fallback bytes, when it changes. +func appendCount(dst []byte, want, uc int) ([]byte, int) { + if want == uc { + return dst, uc + } + dst = append(dst, `\uc`...) + return strconv.AppendInt(dst, int64(want), 10), want +} + +// appendNumber is the backslash, the u and the 16 bit unit as a signed +// decimal - the specification says a value above 32767 is written negative. +func appendNumber(dst []byte, u rune) []byte { + if u > 32767 { + u -= 65536 + } + dst = append(dst, '\\', 'u') + return strconv.AppendInt(dst, int64(u), 10) +} + +// appendHex writes bytes as a backslash, an apostrophe and two lower case hex +// digits each. +func appendHex(dst []byte, b string) []byte { + const digits = "0123456789abcdef" + for i := 0; i < len(b); i++ { + dst = append(dst, '\\', '\'', digits[b[i]>>4], digits[b[i]&0xf]) + } + return dst +} + +// units is a code point as UTF-16 units: one, or a surrogate pair for a code +// point past the basic plane, which is how RTF writes an emoji. +func units(r rune) []rune { + if r < 0x10000 { + return []rune{r} + } + r -= 0x10000 + return []rune{0xD800 + r>>10, 0xDC00 + r&0x3FF} +} diff --git a/internal/guard/generatorbytes_test.go b/internal/guard/generatorbytes_test.go index 84291df9..36b2b9d9 100644 --- a/internal/guard/generatorbytes_test.go +++ b/internal/guard/generatorbytes_test.go @@ -395,7 +395,7 @@ func goldenCases() map[string]engine.Target { // have to agree to the byte. "targz_past_the_comment_limit": {ID: "g", Format: "targz", Sizes: engine.Uniform(1, 262144), Label: true}, } - for _, more := range []map[string]engine.Target{mapGoldenCases(), mailGoldenCases(), pageGoldenCases()} { + for _, more := range []map[string]engine.Target{mapGoldenCases(), mailGoldenCases(), pageGoldenCases(), rtfGoldenCases()} { for name, target := range more { cases[name] = target } @@ -403,6 +403,32 @@ func goldenCases() map[string]engine.Target { return cases } +// rtfGoldenCases are the golden cases of the rtf format, a table of their own +// for the reason mailGoldenCases gives. One for each path the bytes take: the +// default, each of the four ways text_encoding writes the letters of the +// paragraphs in other scripts, the catalogue of every part, groups of nesting, +// a document with no label at an odd size, and everything at once +// (docs/RTF-2026-10-15.md). +func rtfGoldenCases() map[string]engine.Target { + intl := func(encoding string) map[string]string { + return map[string]string{"characters": "international", "text_encoding": encoding} + } + return map[string]engine.Target{ + "rtf_8kib": {ID: "g", Format: "rtf", Sizes: engine.Uniform(1, 8192), Label: true}, + "rtf_8kib_unicode": {ID: "g", Format: "rtf", Sizes: engine.Uniform(1, 8192), Label: true, Properties: intl("unicode")}, + "rtf_8kib_both": {ID: "g", Format: "rtf", Sizes: engine.Uniform(1, 8192), Label: true, Properties: intl("both")}, + "rtf_8kib_codepage": {ID: "g", Format: "rtf", Sizes: engine.Uniform(1, 8192), Label: true, Properties: intl("codepage")}, + "rtf_8kib_literal": {ID: "g", Format: "rtf", Sizes: engine.Uniform(1, 8192), Label: true, Properties: intl("literal")}, + "rtf_16kib_every": {ID: "g", Format: "rtf", Sizes: engine.Uniform(1, 16384), Label: true, + Properties: map[string]string{"elements": "every"}}, + "rtf_8kib_nested": {ID: "g", Format: "rtf", Sizes: engine.Uniform(1, 8192), Label: true, + Properties: map[string]string{"nesting": "100"}}, + "rtf_odd_clean": {ID: "g", Format: "rtf", Sizes: engine.Uniform(1, 8193)}, + "rtf_32kib_everything": {ID: "g", Format: "rtf", Sizes: engine.Uniform(1, 32768), Label: true, + Properties: map[string]string{"characters": "international", "text_encoding": "both", "elements": "every", "nesting": "50"}}, + } +} + // mapGoldenCases are the golden cases of the geojson format, a table of their // own for the reason mailGoldenCases gives. func mapGoldenCases() map[string]engine.Target { diff --git a/internal/guard/layers_test.go b/internal/guard/layers_test.go index 4762e4c8..f4d084ac 100644 --- a/internal/guard/layers_test.go +++ b/internal/guard/layers_test.go @@ -51,6 +51,7 @@ var layer = map[string]int{ "internal/format/jsonfile": 1, "internal/format/geojson": 1, "internal/format/eml": 1, + "internal/format/rtf": 1, "internal/format/yamlfile": 1, "internal/format/tomlfile": 1, "internal/format/xmlfile": 1, @@ -158,6 +159,7 @@ var sameLayerAllowed = map[string][]string{ "internal/format/webm", "internal/format/mp4", "internal/format/eml", + "internal/format/rtf", }, "internal/format/imagelabel": {"internal/format"}, "internal/format/imagedim": {"internal/format"}, @@ -188,6 +190,7 @@ var sameLayerAllowed = map[string][]string{ "internal/format/zip": {"internal/format", "internal/format/imagelabel", "internal/format/archive"}, "internal/format/targz": {"internal/format", "internal/format/archive"}, "internal/format/eml": {"internal/format", "internal/format/archive", "internal/format/picture"}, + "internal/format/rtf": {"internal/format"}, "internal/format/tiff": {"internal/format", "internal/format/imagelabel", "internal/format/imagedim"}, "internal/format/webp": {"internal/format", "internal/format/imagelabel", "internal/format/imagedim"}, "internal/format/avif": {"internal/format", "internal/format/imagelabel", "internal/format/imagedim", "internal/format/isobmff"}, diff --git a/internal/guard/notelemetry_test.go b/internal/guard/notelemetry_test.go index 37d67358..5b93665a 100644 --- a/internal/guard/notelemetry_test.go +++ b/internal/guard/notelemetry_test.go @@ -174,6 +174,10 @@ var allowedURLs = map[string]string{ // (docs/EML-3-2026-10-15.md). "internal/format/eml/newsletter.go|https://example.com/newsletter": "a link written into a message, on a domain kept for examples", "internal/format/eml/newsletter.go|https://example.com/unsubscribe/": "a link written into a message, on a domain kept for examples", + // The link of the catalogue of every part of an RTF document, on a domain + // RFC 2606 keeps for examples. A field is never followed by opening the + // document, and this program never follows it (docs/RTF-2026-10-15.md). + "internal/format/rtf/catalogue.go|https://example.com/tfg/link": "a link written into a document, on a domain kept for examples", "internal/legal/companions.go|https://github.com/pal1000/mesa-dist-win/releases/download/26.2.0/mesa3d-26.2.0-release-msvc.7z": "where the software " + "renderer's bytes were downloaded FROM, by the release workflow and never by the program: written into the bill of " + "materials as the package's download location, and compared with the workflow's pin by a guard", diff --git a/internal/guard/oracle_test.go b/internal/guard/oracle_test.go index 7b061247..67172dc6 100644 --- a/internal/guard/oracle_test.go +++ b/internal/guard/oracle_test.go @@ -186,6 +186,11 @@ var structurallyChecked = map[string]bool{ // and only this layer knows where each name was ordered to be written // (docs/EML-2026-10-07.md section 5.1). "eml": true, + // Since 2026-10-15, from its first day: five readers took eleven of twelve + // broken documents, a control word of 40 letters and text after the last + // brace among them, and only this layer knows which fallback each letter + // was ordered to carry (docs/RTF-2026-10-15.md section 6.1). + "rtf": true, } func TestTheStructuralCheckerCoversEveryFormatItShould(t *testing.T) { diff --git a/internal/guard/parity_test.go b/internal/guard/parity_test.go index 47392236..b2170b90 100644 --- a/internal/guard/parity_test.go +++ b/internal/guard/parity_test.go @@ -126,6 +126,7 @@ var reachableFromTheWindow = []string{ "format:ico", "format:jpg", "format:pptx", + "format:rtf", "format:json", "format:geojson", "format:eml", @@ -178,6 +179,10 @@ var reachableFromTheWindow = []string{ "property:eml.recipients", "property:eml.text_encoding", "property:pptx.slides", + "property:rtf.characters", + "property:rtf.elements", + "property:rtf.nesting", + "property:rtf.text_encoding", "property:xlsx.columns", "property:xlsx.rows", "property:bmp.width", diff --git a/internal/guard/presetbytes_test.go b/internal/guard/presetbytes_test.go index 9f31d016..239ed663 100644 --- a/internal/guard/presetbytes_test.go +++ b/internal/guard/presetbytes_test.go @@ -101,7 +101,11 @@ func TestEjectingAPresetGivesTheBytesItAlwaysGave(t *testing.T) { // day to change bytes: the smallest html page went from 118 B to 122 B // when its empty title became Page (O277, docs/HTML-6-2026-10-15.md). // The recipe keeps its length, only the number in it moves. - {id: "empty-and-minimal", args: preset.Args{}, bytes: 10190, sum: "10a8d738e3c73b995e94e546256807a00c24cad1d01e4372a623618eb35afb44"}, + // Moved an eighth time on 2026-10-15, under the decision of 2026-10-06: + // rtf is a format more, so the set has its smallest document, 65 B - one + // target, minimal_rtf, and nothing else in the recipe moves + // (docs/RTF-2026-10-15.md). + {id: "empty-and-minimal", args: preset.Args{}, bytes: 10497, sum: "0853827d3b55354dbe34c80025e0f298731522704218ce09801dda90f8e04034"}, {id: "empty-and-minimal", args: preset.Args{"formats": "jpg,png,txt"}, bytes: 1472, sum: "19b12800372395ad3bf5cba6407ca654d7ed51eba3a5bc5436f76a94bc09253c"}, // The preset of unusual file names, measured 2026-09-25 on its first // build: the default, and a format whose extension is a byte longer, diff --git a/internal/guard/rtf_test.go b/internal/guard/rtf_test.go new file mode 100644 index 00000000..a37ee0c9 --- /dev/null +++ b/internal/guard/rtf_test.go @@ -0,0 +1,287 @@ +package guard + +import ( + "bytes" + "context" + "os" + "path/filepath" + "sort" + "strconv" + "strings" + "sync/atomic" + "testing" + + "golang.org/x/text/unicode/norm" + + "github.com/donislawdev/TestingFilesGenerator/internal/format" + "github.com/donislawdev/TestingFilesGenerator/internal/format/rtf" + "github.com/donislawdev/TestingFilesGenerator/internal/oracle" +) + +// rtfCases is every value of every setting, one at a time, then where they +// meet: text_encoding while characters is ascii, which has to change nothing, +// and everything at once (docs/RTF-2026-10-15.md). +var rtfCases = []map[string]string{ + {}, + {rtf.Characters: rtf.International}, + {rtf.Characters: rtf.International, rtf.TextEncoding: rtf.Both}, + {rtf.Characters: rtf.International, rtf.TextEncoding: rtf.Codepage}, + {rtf.Characters: rtf.International, rtf.TextEncoding: rtf.Literal}, + {rtf.TextEncoding: rtf.Literal}, + {rtf.Elements: rtf.Every}, + {rtf.Nesting: "1"}, + {rtf.Nesting: "1000"}, + {rtf.Characters: rtf.International, rtf.TextEncoding: rtf.Both, rtf.Elements: rtf.Every, rtf.Nesting: "50"}, + {rtf.Characters: rtf.International, rtf.TextEncoding: rtf.Codepage, rtf.Elements: rtf.Every}, +} + +// rtfPolish, rtfRussian, rtfJapanese and rtfArabic are the sentences +// characters=international adds, held here on their own rather than taken from +// the generator - a guard comparing the generator with itself agrees with any +// mistake it makes. The Arabic by code point, so it cannot turn the line round. +var ( + rtfPolish = "Zażółć gęślą jaźń." + rtfRussian = "Это текст на русском языке." + rtfJapanese = "これは日本語のテキストです。" + rtfArabic = string([]rune{0x647, 0x630, 0x627, ' ', 0x646, 0x635, ' ', 0x628, 0x627, 0x644, 0x644, 0x63A, 0x629, ' ', + 0x627, 0x644, 0x639, 0x631, 0x628, 0x64A, 0x629, '.'}) +) + +// The structural checker is told the settings and has to find the document made +// the way they say, and pandoc has to read it without a word of complaint. +// pandoc's own readings of good files are held as they were measured on three +// versions of it, 3.1.3, 3.7.0.2 and 3.12.1: the four scripts read right in +// unicode and both, the Polish line wrong in codepage and literal, the +// footnote kept and the hidden text left out. Those readings are what the +// sentences of text_encoding and elements tell a user, so this goes red the day +// pandoc reads differently, and the sentence is what has to change. Emoji and +// the text of a link differ between the three versions and are not asked. +// +// Every size from the smallest the settings allow, where the label does not fit +// and the document has no paragraph, through the next two, to a document with +// room for blocks - and the smallest again with no label asked. Named to match +// ReferenceTool, the one job in CI that installs pandoc. Anywhere without python +// it skips, and says so. +func TestEveryRTFSettingSurvivesItsReferenceTool(t *testing.T) { + d, err := format.Get("rtf") + if err != nil { + t.Fatal(err) + } + dir := t.TempDir() + var strict, byPandoc atomic.Int64 + t.Run("cases", func(t *testing.T) { + for i, props := range rtfCases { + t.Run(strconv.Itoa(i), func(t *testing.T) { + t.Parallel() + smallest := d.SmallestAccepted(format.Request{Properties: props, Label: true}) + for _, c := range []struct { + size int64 + label bool + }{{smallest, true}, {smallest + 1, true}, {smallest + 2, true}, {20000, true}, {smallest, false}} { + b, p := writeRTF(t, d, c.size, uint64(41+i), c.label, props) + path := filepath.Join(dir, strconv.Itoa(i)+"_"+strconv.FormatInt(c.size, 10)+"_"+strconv.FormatBool(c.label)+".rtf") + if err := os.WriteFile(path, b, 0o600); err != nil { + t.Fatal(err) + } + s, pd := rtfSurvivesReaders(t, path, props, p, c.size) + strict.Add(int64(s)) + byPandoc.Add(int64(pd)) + } + }) + } + }) + t.Logf("%d documents read by the structural checker, %d by pandoc", strict.Load(), byPandoc.Load()) + if strict.Load() == 0 { + t.Skip("python is not installed, so no document was checked - a skip, not a pass") + } +} + +// rtfSurvivesReaders asks the checker and pandoc about one document and says +// which of them read it. +func rtfSurvivesReaders(t *testing.T, path string, props map[string]string, p format.Plan, size int64) (strict, byPandoc int) { + t.Helper() + labelled, _ := p.Properties[format.PropertyLabelEmbedded].(bool) + s := oracle.Strict("rtf", path, rtfSettings(props, labelled)...) + if !s.Available { + return 0, 0 + } + if s.Err != nil { + t.Fatalf("%v at %d B: %v", props, size, s.Err) + } + text, warnings, res := oracle.PandocRTF(path) + if !res.Available { + return 1, 0 + } + if res.Err != nil || warnings != "" { + t.Fatalf("%v at %d B: pandoc %v %s", props, size, res.Err, warnings) + } + if got := strings.Contains(text, "tfg - rtf - "); got != labelled { + t.Fatalf("%v at %d B: the manifest says the label is there %v, and pandoc read it %v", props, size, labelled, got) + } + rtfPandocReadings(t, norm.NFC.String(text), props, size) + return 1, 1 +} + +// rtfPandocReadings is what pandoc was measured to make of the paragraphs in +// other scripts and of the catalogue of every part. +func rtfPandocReadings(t *testing.T, text string, props map[string]string, size int64) { + t.Helper() + if props[rtf.Characters] == rtf.International { + enc := props[rtf.TextEncoding] + if enc == "" || enc == rtf.Unicode || enc == rtf.Both { + for _, line := range []string{rtfPolish, rtfRussian, rtfJapanese, rtfArabic} { + if !strings.Contains(text, line) { + t.Fatalf("%v at %d B: pandoc did not read %q", props, size, line) + } + } + } else if strings.Contains(text, rtfPolish) { + t.Fatalf("%v at %d B: pandoc read the Polish line right, and text_encoding says it shows %s wrong - the sentence has to change", props, size, enc) + } + } + if props[rtf.Elements] == rtf.Every { + if !strings.Contains(text, "This sentence is in a footnote.") || strings.Contains(text, "This sentence is hidden text.") { + t.Fatalf("%v at %d B: elements says pandoc returns the footnote and leaves the hidden text out, and it read:\n%s", props, size, text) + } + } +} + +// rtfSettings is a case as the words the structural checker is told, with the +// label the manifest says the file carries. +func rtfSettings(props map[string]string, labelled bool) []string { + out := []string{"label=" + strconv.FormatBool(labelled)} + for k, v := range props { + out = append(out, k+"="+v) + } + sort.Strings(out) + return out +} + +// writeRTF plans and writes one document, and holds it to the size it was +// asked for. +func writeRTF(t *testing.T, d format.Descriptor, size int64, seed uint64, label bool, props map[string]string) ([]byte, format.Plan) { + t.Helper() + p, err := d.Generator.Plan(format.Request{Bytes: size, Seed: seed, Label: label, Properties: props}) + if err != nil { + t.Fatalf("planning %d B with %v: %v", size, props, err) + } + var buf bytes.Buffer + if err := d.Generator.Write(context.Background(), &buf, p); err != nil { + t.Fatalf("writing %d B with %v: %v", size, props, err) + } + if int64(buf.Len()) != size { + t.Fatalf("%v: asked for %d B and got %d", props, size, buf.Len()) + } + return buf.Bytes(), p +} + +// A document too small for its label goes without one and says so - the note +// and label_embedded, both - rather than being refused or rounded. The sizes are +// taken from either side of where the label starts to fit, so the guard is in +// the state it is about: it asserts the bare document fits and the labelled one +// does not, and then that one byte more is enough. +func TestAnRTFTooSmallForItsLabelSaysItCarriesNone(t *testing.T) { + d, err := format.Get("rtf") + if err != nil { + t.Fatal(err) + } + fits := int64(-1) + for size := d.MinBytes; size < d.MinBytes+200; size++ { + p, err := d.Generator.Plan(format.Request{Bytes: size, Seed: 7, Label: true}) + if err != nil { + t.Fatalf("%d B is above the minimum %d and was refused: %v", size, d.MinBytes, err) + } + if p.Properties[format.PropertyLabelEmbedded] == true { + fits = size + break + } + if len(p.Notes) != 1 || p.Notes[0].Code != "label_omitted" { + t.Fatalf("at %d B the label is left out and the notes are %+v", size, p.Notes) + } + } + if fits <= d.MinBytes { + t.Fatalf("the label fits at %d B, so no size between the minimum %d and it was ever asked about", fits, d.MinBytes) + } +} + +// The manifest records every setting whatever was asked, under the names the +// owner approved on 2026-10-15 - public names under rule 10, so a key that +// changed spelling is somebody's test failing. +func TestTheRTFManifestRecordsEverySetting(t *testing.T) { + d, err := format.Get("rtf") + if err != nil { + t.Fatal(err) + } + p, err := d.Generator.Plan(format.Request{Bytes: 4096, Seed: 7, Label: true}) + if err != nil { + t.Fatal(err) + } + want := map[string]any{ + "characters": "ascii", "text_encoding": "unicode", "elements": "basic", "nesting": 0, + "code_page": 1252, format.PropertyLabelEmbedded: true, + } + if len(p.Properties) != len(want) { + t.Errorf("the manifest carries %d keys, %v, and the approved list is %d", len(p.Properties), p.Properties, len(want)) + } + for k, v := range want { + if p.Properties[k] != v { + t.Errorf("%s is %v in the manifest, and %v by default", k, p.Properties[k], v) + } + } +} + +// Cut at any size, a document ends on the braces that close its groups and +// itself, with nothing that could escape them in front, and no line end stands +// between two letters - RTF ignores a line end, so one there joins two words in +// every reader (docs/RTF-2026-10-15.md section 3). Three hundred sizes in a row +// from the smallest, in the three shapes the end can take, with no tool outside +// this process, so it runs wherever the suite does. +func TestAnRTFCutAtAnySizeEndsOnItsBraces(t *testing.T) { + d, err := format.Get("rtf") + if err != nil { + t.Fatal(err) + } + for _, props := range []map[string]string{{}, {rtf.Nesting: "3"}, {rtf.Characters: rtf.International, rtf.Elements: rtf.Every}} { + smallest := d.SmallestAccepted(format.Request{Properties: props, Label: true}) + closing := 1 + if props[rtf.Nesting] != "" { + n, _ := strconv.Atoi(props[rtf.Nesting]) + closing += n + } + for size := smallest; size < smallest+300; size++ { + b, _ := writeRTF(t, d, size, 99, true, props) + rtfEndsOnItsBraces(t, b, closing, props, size) + } + } +} + +func rtfEndsOnItsBraces(t *testing.T, b []byte, closing int, props map[string]string, size int64) { + t.Helper() + body := bytes.TrimRight(b, "}") + if got := len(b) - len(body); got != closing { + t.Fatalf("%v at %d B ends with %d braces, and closes %d groups", props, size, got, closing) + } + if bytes.HasSuffix(body, []byte(`\`)) { + t.Fatalf("%v at %d B: a backslash right before the closing braces escapes the first of them", props, size) + } + for i := bytes.Index(b, []byte("\r\n")); i >= 0; i = nextLineEnd(b, i) { + start := i + for start > 0 && isLetterOrDigit(b[start-1]) { + start-- + } + if start < i && (start == 0 || b[start-1] != '\\') && i+2 < len(b) && isLetterOrDigit(b[i+2]) { + t.Fatalf("%v at %d B: a line end between %q and %q joins two words", props, size, b[start:i], b[i+2:min(i+10, len(b))]) + } + } +} + +func nextLineEnd(b []byte, i int) int { + j := bytes.Index(b[i+2:], []byte("\r\n")) + if j < 0 { + return -1 + } + return i + 2 + j +} + +func isLetterOrDigit(c byte) bool { + return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' +} diff --git a/internal/guard/testdata/generator-golden.json b/internal/guard/testdata/generator-golden.json index 199a5009..da1bfbb8 100644 --- a/internal/guard/testdata/generator-golden.json +++ b/internal/guard/testdata/generator-golden.json @@ -560,6 +560,51 @@ "bytes": 8192, "sha256": "5b4918a133ccb3708018ca9bc9c2e8882340d1073f408ae91a7c2ba164f2b528", "measured_on": "2026-10-15" + }, + "rtf_8kib": { + "bytes": 8192, + "sha256": "65bdb29a90bba1c17cb8e337f98aa51bc789a607412b61c86f94ca595c830902", + "measured_on": "2026-10-15" + }, + "rtf_8kib_unicode": { + "bytes": 8192, + "sha256": "472362d7ffd16045e7322f218dcd2d25d4f2e182b754f53974ef807e26a5b4bd", + "measured_on": "2026-10-15" + }, + "rtf_8kib_both": { + "bytes": 8192, + "sha256": "6f8372d5dfbfe4a9864d48a35f3ec55442359f9989ad10cbb51699812e8f75a2", + "measured_on": "2026-10-15" + }, + "rtf_8kib_codepage": { + "bytes": 8192, + "sha256": "445da631bd16790527c509f770b0c0a4d278f7cebf7c2656800477113bd5021e", + "measured_on": "2026-10-15" + }, + "rtf_8kib_literal": { + "bytes": 8192, + "sha256": "80ccd723dd1306fffee140349be4e702475c72a220b4293264228f515c318e9e", + "measured_on": "2026-10-15" + }, + "rtf_16kib_every": { + "bytes": 16384, + "sha256": "8aca70153633a5828b349a1af14359b79cc18f55ba4b1a93f1e8bcae48c67747", + "measured_on": "2026-10-15" + }, + "rtf_8kib_nested": { + "bytes": 8192, + "sha256": "85c22389d3a64fb1d5ae02255e56d2f0effded912fc8497e82f0e17214f37488", + "measured_on": "2026-10-15" + }, + "rtf_odd_clean": { + "bytes": 8193, + "sha256": "686ea1e1ce69c3403a93a5b4771229989bb904c91841d934a4af40c71d44234e", + "measured_on": "2026-10-15" + }, + "rtf_32kib_everything": { + "bytes": 32768, + "sha256": "6451c067b5a67e9a8707228d3782aa0a9abca538cfa5bd0be4ece2dbf26a9c5d", + "measured_on": "2026-10-15" } }, "remeasured": [ diff --git a/internal/guard/testdata/screens/catalogue.png b/internal/guard/testdata/screens/catalogue.png index 66e80b50..67dca6ff 100644 Binary files a/internal/guard/testdata/screens/catalogue.png and b/internal/guard/testdata/screens/catalogue.png differ diff --git a/internal/guard/testdata/screens/catalogue.xml b/internal/guard/testdata/screens/catalogue.xml index 9c04e26f..a1f1e67f 100644 --- a/internal/guard/testdata/screens/catalogue.xml +++ b/internal/guard/testdata/screens/catalogue.xml @@ -1338,7 +1338,7 @@ - + Archives · 2 @@ -1357,7 +1357,7 @@ - Documents · 4 + Documents · 5 @@ -1378,171 +1378,177 @@ PowerPoint (Office Open XML) + + + rtf + Rich Text Format + + xlsx Excel (Office Open XML) - + Mail · 1 - + eml Email message - + Pictures · 10 - + avif AV1 Image File Format - + bmp Windows Bitmap - + gif Graphics Interchange Format - + ico Windows Icon - + jpg JPEG - + jxl JPEG XL - + png Portable Network Graphics - + svg Scalable Vector Graphics - + tiff Tagged Image File Format - + webp WebP - + Sound · 1 - + wav Waveform Audio - + Text and data · 10 - + csv Comma-Separated Values - + geojson GeoJSON - + html HyperText Markup Language - + json JavaScript Object Notation - + log Server and application log - + md Markdown - + toml TOML - + txt Plain text - + xml Extensible Markup Language - + yaml YAML - + Video · 2 - + mp4 MP4 video - + webm @@ -1553,8 +1559,8 @@ - - + + diff --git a/internal/guard/testdata/screens/generate-menu-hovered.png b/internal/guard/testdata/screens/generate-menu-hovered.png index 064811be..6944fa71 100644 Binary files a/internal/guard/testdata/screens/generate-menu-hovered.png and b/internal/guard/testdata/screens/generate-menu-hovered.png differ diff --git a/internal/guard/testdata/screens/generate-menu-hovered.xml b/internal/guard/testdata/screens/generate-menu-hovered.xml index 7455a897..bb2351d8 100644 --- a/internal/guard/testdata/screens/generate-menu-hovered.xml +++ b/internal/guard/testdata/screens/generate-menu-hovered.xml @@ -511,7 +511,7 @@ - + Archives · 2 @@ -530,7 +530,7 @@ - Documents · 4 + Documents · 5 @@ -551,171 +551,177 @@ PowerPoint (Office Open XML) + + + rtf + Rich Text Format + + xlsx Excel (Office Open XML) - + Mail · 1 - + eml Email message - + Pictures · 10 - + avif AV1 Image File Format - + bmp Windows Bitmap - + gif Graphics Interchange Format - + ico Windows Icon - + jpg JPEG - + jxl JPEG XL - + png Portable Network Graphics - + svg Scalable Vector Graphics - + tiff Tagged Image File Format - + webp WebP - + Sound · 1 - + wav Waveform Audio - + Text and data · 10 - + csv Comma-Separated Values - + geojson GeoJSON - + html HyperText Markup Language - + json JavaScript Object Notation - + log Server and application log - + md Markdown - + toml TOML - + txt Plain text - + xml Extensible Markup Language - + yaml YAML - + Video · 2 - + mp4 MP4 video - + webm @@ -726,8 +732,8 @@ - - + + diff --git a/internal/guard/testdata/screens/generate-menu-keyed.png b/internal/guard/testdata/screens/generate-menu-keyed.png index e45f9608..1bf933ae 100644 Binary files a/internal/guard/testdata/screens/generate-menu-keyed.png and b/internal/guard/testdata/screens/generate-menu-keyed.png differ diff --git a/internal/guard/testdata/screens/generate-menu-keyed.xml b/internal/guard/testdata/screens/generate-menu-keyed.xml index 5653abe4..1d178eb1 100644 --- a/internal/guard/testdata/screens/generate-menu-keyed.xml +++ b/internal/guard/testdata/screens/generate-menu-keyed.xml @@ -511,7 +511,7 @@ - + Archives · 2 @@ -530,7 +530,7 @@ - Documents · 4 + Documents · 5 @@ -551,171 +551,177 @@ PowerPoint (Office Open XML) + + + rtf + Rich Text Format + + xlsx Excel (Office Open XML) - + Mail · 1 - + eml Email message - + Pictures · 10 - + avif AV1 Image File Format - + bmp Windows Bitmap - + gif Graphics Interchange Format - + ico Windows Icon - + jpg JPEG - + jxl JPEG XL - + png Portable Network Graphics - + svg Scalable Vector Graphics - + tiff Tagged Image File Format - + webp WebP - + Sound · 1 - + wav Waveform Audio - + Text and data · 10 - + csv Comma-Separated Values - + geojson GeoJSON - + html HyperText Markup Language - + json JavaScript Object Notation - + log Server and application log - + md Markdown - + toml TOML - + txt Plain text - + xml Extensible Markup Language - + yaml YAML - + Video · 2 - + mp4 MP4 video - + webm @@ -726,8 +732,8 @@ - - + + diff --git a/internal/guard/testdata/screens/generate-menu.png b/internal/guard/testdata/screens/generate-menu.png index be493ce4..f94e0623 100644 Binary files a/internal/guard/testdata/screens/generate-menu.png and b/internal/guard/testdata/screens/generate-menu.png differ diff --git a/internal/guard/testdata/screens/generate-menu.xml b/internal/guard/testdata/screens/generate-menu.xml index 36185c86..9f0d5027 100644 --- a/internal/guard/testdata/screens/generate-menu.xml +++ b/internal/guard/testdata/screens/generate-menu.xml @@ -511,7 +511,7 @@ - + Archives · 2 @@ -530,7 +530,7 @@ - Documents · 4 + Documents · 5 @@ -551,171 +551,177 @@ PowerPoint (Office Open XML) + + + rtf + Rich Text Format + + xlsx Excel (Office Open XML) - + Mail · 1 - + eml Email message - + Pictures · 10 - + avif AV1 Image File Format - + bmp Windows Bitmap - + gif Graphics Interchange Format - + ico Windows Icon - + jpg JPEG - + jxl JPEG XL - + png Portable Network Graphics - + svg Scalable Vector Graphics - + tiff Tagged Image File Format - + webp WebP - + Sound · 1 - + wav Waveform Audio - + Text and data · 10 - + csv Comma-Separated Values - + geojson GeoJSON - + html HyperText Markup Language - + json JavaScript Object Notation - + log Server and application log - + md Markdown - + toml TOML - + txt Plain text - + xml Extensible Markup Language - + yaml YAML - + Video · 2 - + mp4 MP4 video - + webm @@ -726,8 +732,8 @@ - - + + diff --git a/internal/guard/testdata/screens/preset-menu-setting.png b/internal/guard/testdata/screens/preset-menu-setting.png index 044ac061..db75b8d6 100644 Binary files a/internal/guard/testdata/screens/preset-menu-setting.png and b/internal/guard/testdata/screens/preset-menu-setting.png differ diff --git a/internal/guard/testdata/screens/preset-menu-setting.xml b/internal/guard/testdata/screens/preset-menu-setting.xml index 762847fe..bf666242 100644 --- a/internal/guard/testdata/screens/preset-menu-setting.xml +++ b/internal/guard/testdata/screens/preset-menu-setting.xml @@ -474,7 +474,7 @@ - + Archives · 2 @@ -493,7 +493,7 @@ - Documents · 4 + Documents · 5 @@ -515,170 +515,176 @@ PowerPoint (Office Open XML) + + + rtf + Rich Text Format + + xlsx Excel (Office Open XML) - + Mail · 1 - + eml Email message - + Pictures · 10 - + avif AV1 Image File Format - + bmp Windows Bitmap - + gif Graphics Interchange Format - + ico Windows Icon - + jpg JPEG - + jxl JPEG XL - + png Portable Network Graphics - + svg Scalable Vector Graphics - + tiff Tagged Image File Format - + webp WebP - + Sound · 1 - + wav Waveform Audio - + Text and data · 10 - + csv Comma-Separated Values - + geojson GeoJSON - + html HyperText Markup Language - + json JavaScript Object Notation - + log Server and application log - + md Markdown - + toml TOML - + txt Plain text - + xml Extensible Markup Language - + yaml YAML - + Video · 2 - + mp4 MP4 video - + webm @@ -689,8 +695,8 @@ - - + + diff --git a/internal/guard/testdata/screens/preset-menu.png b/internal/guard/testdata/screens/preset-menu.png index 5285c6c9..6dbda3f1 100644 Binary files a/internal/guard/testdata/screens/preset-menu.png and b/internal/guard/testdata/screens/preset-menu.png differ diff --git a/internal/guard/testdata/screens/preset-menu.xml b/internal/guard/testdata/screens/preset-menu.xml index 20ded2b6..1a8363fe 100644 --- a/internal/guard/testdata/screens/preset-menu.xml +++ b/internal/guard/testdata/screens/preset-menu.xml @@ -370,7 +370,7 @@ - 32 files · 39.5 KB (40 431 B) · 30 formats · will go to /tfg/out + 33 files · 39.5 KB (40 496 B) · 31 formats · will go to /tfg/out diff --git a/internal/guard/testdata/screens/preset.png b/internal/guard/testdata/screens/preset.png index fc0e45ee..2cd7cc33 100644 Binary files a/internal/guard/testdata/screens/preset.png and b/internal/guard/testdata/screens/preset.png differ diff --git a/internal/guard/testdata/screens/preset.xml b/internal/guard/testdata/screens/preset.xml index 186d52f4..199b8b2d 100644 --- a/internal/guard/testdata/screens/preset.xml +++ b/internal/guard/testdata/screens/preset.xml @@ -370,7 +370,7 @@ - 32 files · 39.5 KB (40 431 B) · 30 formats · will go to /tfg/out + 33 files · 39.5 KB (40 496 B) · 31 formats · will go to /tfg/out diff --git a/internal/guard/testdata/screens/recipe-on-a-preset.png b/internal/guard/testdata/screens/recipe-on-a-preset.png index aa671880..92f39378 100644 Binary files a/internal/guard/testdata/screens/recipe-on-a-preset.png and b/internal/guard/testdata/screens/recipe-on-a-preset.png differ diff --git a/internal/guard/testdata/screens/recipe-on-a-preset.xml b/internal/guard/testdata/screens/recipe-on-a-preset.xml index e7c07fb7..1bc4a9de 100644 --- a/internal/guard/testdata/screens/recipe-on-a-preset.xml +++ b/internal/guard/testdata/screens/recipe-on-a-preset.xml @@ -658,7 +658,7 @@ - 33 files · 10.0 MB (10 526 191 B) · 30 formats · will go to /tfg/out + 34 files · 10.0 MB (10 526 256 B) · 31 formats · will go to /tfg/out diff --git a/internal/guard/textformats_test.go b/internal/guard/textformats_test.go index c6c3c035..80c3080f 100644 --- a/internal/guard/textformats_test.go +++ b/internal/guard/textformats_test.go @@ -444,7 +444,7 @@ func TestAnSVGDrawingCarriesRealShapes(t *testing.T) { // This is the shape docs/OBSERVATIONS.md now calls out: an audit of // completeness has to run FROM THE SOURCE towards the list. Walking the entries // already written down cannot, by construction, find what is missing from them. -var textFormats = []string{"txt", "md", "log", "csv", "json", "xml", "html", "svg", "yaml", "toml", "geojson", "eml"} +var textFormats = []string{"txt", "md", "log", "csv", "json", "xml", "html", "svg", "yaml", "toml", "geojson", "eml", "rtf"} var binaryFormats = []string{"avif", "bmp", "docx", "gif", "ico", "jpg", "jxl", "mp4", "pdf", "png", "pptx", "targz", "tiff", "wav", "webm", "webp", "xlsx", "zip"} diff --git a/internal/gui/parts/filekind.go b/internal/gui/parts/filekind.go index d7174251..cab583b5 100644 --- a/internal/gui/parts/filekind.go +++ b/internal/gui/parts/filekind.go @@ -155,6 +155,7 @@ var fileKinds = map[string]fileKind{ "docx": kindDocument, "pdf": kindDocument, "pptx": kindDocument, + "rtf": kindDocument, "xlsx": kindDocument, "targz": kindArchive, "zip": kindArchive, diff --git a/internal/gui/text/locale/registry/en.json b/internal/gui/text/locale/registry/en.json index 478c6af0..cdc3dd7f 100644 --- a/internal/gui/text/locale/registry/en.json +++ b/internal/gui/text/locale/registry/en.json @@ -644,6 +644,11 @@ "hash": "sha256-1512e97a4b84", "other": "pptx" }, + "Choice.format.rtf": { + "description": "One entry of the format list, as the list shows it. A recipe and the command line write the value itself, so a token such as utf-8, a4, sha256 or 644 stays as it is.", + "hash": "sha256-b97d62f2e9e5", + "other": "rtf" + }, "Choice.format.svg": { "description": "One entry of the format list, as the list shows it. A recipe and the command line write the value itself, so a token such as utf-8, a4, sha256 or 644 stays as it is.", "hash": "sha256-acdb1373d176", @@ -1084,11 +1089,31 @@ "hash": "sha256-371a286d5872", "other": "base64" }, + "Choice.text_encoding.both": { + "description": "One entry of the text_encoding list, as the list shows it. A recipe and the command line write the value itself, so a token such as utf-8, a4, sha256 or 644 stays as it is.", + "hash": "sha256-ff7772053abf", + "other": "both" + }, + "Choice.text_encoding.codepage": { + "description": "One entry of the text_encoding list, as the list shows it. A recipe and the command line write the value itself, so a token such as utf-8, a4, sha256 or 644 stays as it is.", + "hash": "sha256-0b653bac8180", + "other": "codepage" + }, + "Choice.text_encoding.literal": { + "description": "One entry of the text_encoding list, as the list shows it. A recipe and the command line write the value itself, so a token such as utf-8, a4, sha256 or 644 stays as it is.", + "hash": "sha256-829f8d848b44", + "other": "literal" + }, "Choice.text_encoding.quoted-printable": { "description": "One entry of the text_encoding list, as the list shows it. A recipe and the command line write the value itself, so a token such as utf-8, a4, sha256 or 644 stays as it is.", "hash": "sha256-7956a9e2a40b", "other": "quoted-printable" }, + "Choice.text_encoding.unicode": { + "description": "One entry of the text_encoding list, as the list shows it. A recipe and the command line write the value itself, so a token such as utf-8, a4, sha256 or 644 stays as it is.", + "hash": "sha256-2fcf76a4c3c7", + "other": "unicode" + }, "Choice.timestamps.advancing": { "description": "One entry of the timestamps list, as the list shows it. A recipe and the command line write the value itself, so a token such as utf-8, a4, sha256 or 644 stays as it is.", "hash": "sha256-3656fa4d5539", @@ -1599,6 +1624,26 @@ "hash": "sha256-b62241b390bf", "other": "How many slides the presentation holds. The rest of the size you asked for is carried by a part of the package that is not shown." }, + "Detail.format/rtf.characters": { + "description": "The sentence under the characters setting of the rtf format, after what it takes.", + "hash": "sha256-a66dbdb2f6f9", + "other": "Whether the document carries text outside ASCII. international adds paragraphs in Polish, Russian, Japanese and Arabic, the Arabic right to left, and one with emoji, a letter written as two code points, the three characters RTF escapes and the ones it names, such as the dashes and the quotes. A program without a Japanese or Arabic font shows boxes in their place." + }, + "Detail.format/rtf.elements": { + "description": "The sentence under the elements setting of the rtf format, after what it takes.", + "hash": "sha256-b0177e3841f3", + "other": "Which parts the document uses. basic is headings, paragraphs with bold and italic words, lists, tables and indented quotes. every adds document properties, a page header and footer, a footnote, a comment, hidden text, a link, a bookmark, a group every reader has to skip, a word no reader knows and line, tab, page and section breaks, and each part says where it is. Tika returns the most of them, the header, the footer and the comment among them. LibreOffice, striprtf and RichEdit return the hidden text as text, RichEdit with the address of the link, and pandoc returns the footnote and leaves the hidden text out." + }, + "Detail.format/rtf.nesting": { + "description": "The sentence under the nesting setting of the rtf format, after what it takes.", + "hash": "sha256-e1d640adb186", + "other": "How many groups the content sits inside, each one inside the last. 0 puts it straight in the document, and the label stays outside so the file still says what it is. No reader measured lost the content at 10 000 000 levels, but LibreOffice took 18.5 GB of memory over them and pandoc 14.5 GB, against about 2 GB each at 1 000 000." + }, + "Detail.format/rtf.text_encoding": { + "description": "The sentence under the text_encoding setting of the rtf format, after what it takes.", + "hash": "sha256-e6a5e55837f3", + "other": "How the letters outside ASCII are written, which changes nothing while characters is ascii. unicode writes each one as a number with a question mark after it for a reader that does not know numbers. both puts the letter in the code page of its font after the number, two bytes for Japanese, the way Word writes it. codepage writes only the code page bytes, and the emoji still as numbers, since no code page holds them. literal writes the question mark as a plain character. LibreOffice, Tika and the RichEdit control of Windows read all four. pandoc shows codepage text in the wrong letters and drops the character after every letter written literal, and pandoc 3.1 and 3.7 drop the emoji in all four. striprtf returns an emoji as two halves, which Python refuses to write as UTF-8." + }, "Detail.format/svg.height": { "description": "The sentence under the height setting of the svg format, after what it takes.", "hash": "sha256-093ec883d633", @@ -1964,6 +2009,11 @@ "hash": "sha256-33f651fb2245", "other": "PowerPoint (Office Open XML)" }, + "Format.rtf": { + "description": "What the rtf format is called, beside its id in a list of formats. The name of a standard stays as it is - only a name that describes the file is translated.", + "hash": "sha256-57bbafd25bb0", + "other": "Rich Text Format" + }, "Format.svg": { "description": "What the svg format is called, beside its id in a list of formats. The name of a standard stays as it is - only a name that describes the file is translated.", "hash": "sha256-ccd66e031e79", diff --git a/internal/gui/text/locale/registry/pl.json b/internal/gui/text/locale/registry/pl.json index e899c7c7..bd8998d0 100644 --- a/internal/gui/text/locale/registry/pl.json +++ b/internal/gui/text/locale/registry/pl.json @@ -128,6 +128,7 @@ "Choice.format.pdf": { "hash": "sha256-c35b21d6ca39", "other": "pdf" }, "Choice.format.png": { "hash": "sha256-8f8cbb7dcf46", "other": "png" }, "Choice.format.pptx": { "hash": "sha256-1512e97a4b84", "other": "pptx" }, + "Choice.format.rtf": { "hash": "sha256-b97d62f2e9e5", "other": "rtf" }, "Choice.format.svg": { "hash": "sha256-acdb1373d176", "other": "svg" }, "Choice.format.targz": { "hash": "sha256-fc53fb509109", "other": "targz" }, "Choice.format.tiff": { "hash": "sha256-904749a4869b", "other": "tiff" }, @@ -216,7 +217,11 @@ "Choice.text_encoding.7bit": { "hash": "sha256-af6ec1d82852", "other": "7bit" }, "Choice.text_encoding.8bit": { "hash": "sha256-e318653d2946", "other": "8bit" }, "Choice.text_encoding.base64": { "hash": "sha256-371a286d5872", "other": "base64" }, + "Choice.text_encoding.both": { "hash": "sha256-ff7772053abf", "other": "oba" }, + "Choice.text_encoding.codepage": { "hash": "sha256-0b653bac8180", "other": "strona kodowa" }, + "Choice.text_encoding.literal": { "hash": "sha256-829f8d848b44", "other": "dosłowny" }, "Choice.text_encoding.quoted-printable": { "hash": "sha256-7956a9e2a40b", "other": "quoted-printable" }, + "Choice.text_encoding.unicode": { "hash": "sha256-2fcf76a4c3c7", "other": "unicode" }, "Choice.timestamps.advancing": { "hash": "sha256-3656fa4d5539", "other": "rosnące" }, "Choice.timestamps.fixed": { "hash": "sha256-992a93455c71", "other": "stałe" }, "Choice.unlocated.all": { "hash": "sha256-5ef5ef0364b6", "other": "wszystkie" }, @@ -319,6 +324,10 @@ "Detail.format/png.height": { "hash": "sha256-4b336c279584", "other": "Jak wysoki jest obraz. Gdy pole zostaje puste, wybierany jest rozmiar, który mieści się w zamówionych bajtach." }, "Detail.format/png.width": { "hash": "sha256-3085ac44f0e0", "other": "Jak szeroki jest obraz. Gdy pole zostaje puste, wybierany jest rozmiar, który mieści się w zamówionych bajtach." }, "Detail.format/pptx.slides": { "hash": "sha256-b62241b390bf", "other": "Ile slajdów zawiera prezentacja. Resztę zamówionego rozmiaru niesie niewidoczna część paczki." }, + "Detail.format/rtf.characters": { "hash": "sha256-a66dbdb2f6f9", "other": "Czy dokument zawiera tekst spoza ASCII. międzynarodowe dokłada akapity po polsku, rosyjsku, japońsku i arabsku, arabski od prawej do lewej, oraz jeden z emoji, literą zapisaną dwoma punktami kodowymi, trzema znakami, które RTF poprzedza ukośnikiem, i tymi, które nazywa słowem, jak myślniki i cudzysłowy. Program bez fontu japońskiego albo arabskiego pokazuje w ich miejscu kwadraty." }, + "Detail.format/rtf.elements": { "hash": "sha256-b0177e3841f3", "other": "Których części używa dokument. podstawowe to nagłówki, akapity ze słowami pogrubionymi i pochylonymi, listy, tabele i cytaty z wcięciem. wszystkie dokłada właściwości dokumentu, nagłówek i stopkę strony, przypis, komentarz, tekst ukryty, odnośnik, zakładkę, grupę, którą każdy czytnik musi pominąć, słowo, którego nie zna żaden czytnik, oraz podział wiersza, tabulator, podział strony i sekcji, a każda część mówi, gdzie jest. Tika oddaje ich najwięcej, w tym nagłówek, stopkę i komentarz. LibreOffice, striprtf i RichEdit oddają tekst ukryty jako tekst, RichEdit razem z adresem odnośnika, a pandoc oddaje przypis i pomija tekst ukryty." }, + "Detail.format/rtf.nesting": { "hash": "sha256-e1d640adb186", "other": "W ilu grupach, jedna w drugiej, siedzi treść. 0 umieszcza ją wprost w dokumencie, a etykieta zostaje na zewnątrz, więc plik dalej mówi, czym jest. Żaden zmierzony czytnik nie zgubił treści przy 10 000 000 poziomów, ale LibreOffice zużył na nie 18,5 GB pamięci, a pandoc 14,5 GB, wobec około 2 GB każdy przy 1 000 000." }, + "Detail.format/rtf.text_encoding": { "hash": "sha256-e6a5e55837f3", "other": "Jak zapisane są litery spoza ASCII. Gdy Znaki to ascii, nic to nie zmienia. unicode zapisuje każdą jako liczbę ze znakiem zapytania po niej dla czytnika, który nie zna liczb. oba dopisuje po liczbie literę w stronie kodowej jej fontu, dla japońskiego dwa bajty, tak jak zapisuje ją Word. strona kodowa zapisuje tylko bajty strony kodowej, a emoji dalej jako liczby, bo żadna strona kodowa ich nie ma. dosłowny zapisuje znak zapytania jako zwykły znak. LibreOffice, Tika i kontrolka RichEdit z Windows czytają wszystkie cztery. pandoc pokazuje tekst ze strony kodowej złymi literami i gubi znak po każdej literze zapisanej dosłownie, a pandoc 3.1 i 3.7 gubią emoji we wszystkich czterech. striprtf oddaje emoji jako dwie połówki, których Python nie zapisze w UTF-8." }, "Detail.format/svg.height": { "hash": "sha256-093ec883d633", "other": "Jaką wysokość deklaruje rysunek. Etykieta biegnie wzdłuż dolnej krawędzi, więc rysunek niższy od tego pasa nie ma widocznej etykiety." }, "Detail.format/svg.width": { "hash": "sha256-5dc327958f8d", "other": "Jaką szerokość deklaruje rysunek. Nic nie jest tu rysowane w pikselach, więc duża liczba kosztuje kilka bajtów w pliku i bardzo dużo pamięci w tym, co go otworzy." }, "Detail.format/targz.compression": { "hash": "sha256-82bb36e51fe2", "other": "Jak mocno ściskane są pliki w środku. Archiwum i tak ma zamówiony rozmiar - zmienia się to, ile z niego jest prawdziwą treścią, a ile dopełnieniem." }, @@ -392,6 +401,7 @@ "Format.pdf": { "hash": "sha256-ccf9cd24dc07", "other": "Portable Document Format" }, "Format.png": { "hash": "sha256-016d63e71b45", "other": "Portable Network Graphics" }, "Format.pptx": { "hash": "sha256-33f651fb2245", "other": "PowerPoint (Office Open XML)" }, + "Format.rtf": { "hash": "sha256-57bbafd25bb0", "other": "Rich Text Format" }, "Format.svg": { "hash": "sha256-ccd66e031e79", "other": "Scalable Vector Graphics" }, "Format.targz": { "hash": "sha256-57446f685bff", "other": "tar + gzip" }, "Format.tiff": { "hash": "sha256-0a835e8afa67", "other": "Tagged Image File Format" }, diff --git a/internal/gui/text/locale/said/en.json b/internal/gui/text/locale/said/en.json index 2db0133d..cb8c8d0d 100644 --- a/internal/gui/text/locale/said/en.json +++ b/internal/gui/text/locale/said/en.json @@ -3251,6 +3251,16 @@ "hash": "sha256-6b426dee7162", "other": "write version: {{.SchemaVersion}}" }, + "rtf.MinimumDocument": { + "description": "Said by internal/format/rtf - a refusal under the box it is about or at the foot of the form, or a note after a run.", + "hash": "sha256-0dd8e6a8cceb", + "other": "a document holds its header and its font table, and the two need that much" + }, + "rtf.MinimumWithSettings": { + "description": "Said by internal/format/rtf - a refusal under the box it is about or at the foot of the form, or a note after a run. Carries {{.Characters}}, {{.Elements}}, {{.Nesting}}, written the way the program writes them - keep each spelled exactly that way.", + "hash": "sha256-576cd6d8e42b", + "other": "a document holds its header and its font table and what {{.Characters}}, {{.Elements}} and {{.Nesting}} add to them, and together they need that much" + }, "textenc.HasToBeEncoding": { "description": "Said by internal/format/textenc - a refusal under the box it is about or at the foot of the form, or a note after a run. Carries {{.UTF8}}, {{.UTF16LE}}, {{.UTF16BE}}, written the way the program writes them - keep each spelled exactly that way.", "hash": "sha256-cf8214cf1fa6", diff --git a/internal/gui/text/locale/said/pl.json b/internal/gui/text/locale/said/pl.json index 0ae4cc80..ae1479eb 100644 --- a/internal/gui/text/locale/said/pl.json +++ b/internal/gui/text/locale/said/pl.json @@ -647,6 +647,8 @@ "recipe.WriteTheNameAsAWord": { "hash": "sha256-effad2028c85", "other": "zapisz nazwę jako słowo" }, "recipe.WriteTheNameOnItsOwn": { "hash": "sha256-da431c8ff106", "other": "zapisz samą nazwę albo mapę zaczynającą się od type" }, "recipe.WriteVersion": { "hash": "sha256-6b426dee7162", "other": "wpisz version: {{.SchemaVersion}}" }, + "rtf.MinimumDocument": { "hash": "sha256-0dd8e6a8cceb", "other": "dokument zawiera nagłówek i tablicę fontów, a te dwa potrzebują tyle" }, + "rtf.MinimumWithSettings": { "hash": "sha256-576cd6d8e42b", "other": "dokument zawiera nagłówek i tablicę fontów oraz to, co dokładają do nich {{.Characters}}, {{.Elements}} i {{.Nesting}}, a razem potrzebują tyle" }, "textenc.HasToBeEncoding": { "hash": "sha256-cf8214cf1fa6", "other": "musi to być {{.UTF8}}, {{.UTF16LE}} albo {{.UTF16BE}}" }, "tool.AToolIsNamedExactlyAnd": { "hash": "sha256-756a78c6f204", "other": "narzędzie podaje się dokładną nazwą, a najbliższa nazwa do pomylonej może robić coś innego" }, "tool.NameTheToWorkOn": { "hash": "sha256-3dac06c6319b", "other": "wskaż, na czym narzędzie ma pracować: {{.Kind}}" }, diff --git a/internal/oracle/oracle.go b/internal/oracle/oracle.go index 79841a26..8427deda 100644 --- a/internal/oracle/oracle.go +++ b/internal/oracle/oracle.go @@ -354,6 +354,9 @@ var checkers = map[string]Checker{ // Python's email package. See mailscripts.go. "python-email": pythonEmail, + + // pandoc's RTF reader. See rtfscripts.go. + "pandoc-rtf": pandocRTF, } // DecodedFrames is how many frames the libaom oracle decoded, read from what @@ -565,7 +568,12 @@ func StrictKnows(formatID string) bool { // The second, from the day it arrived (2026-10-07). The sample tables // say how long every sample is, and only reading them against the // media data says the tables and the samples agree. - "mp4": + // + // And rtf, from its first day, for the reason mail gave: five readers + // took eleven of twelve broken documents (docs/RTF-2026-10-15.md + // section 6.1 f), and none of them says whether a fallback agrees + // with the count before it. + "mp4", "rtf": return true } return false diff --git a/internal/oracle/rtfscripts.go b/internal/oracle/rtfscripts.go new file mode 100644 index 00000000..a56c7c50 --- /dev/null +++ b/internal/oracle/rtfscripts.go @@ -0,0 +1,50 @@ +package oracle + +import ( + "fmt" + "strings" +) + +// pandocRTF is pandoc's RTF reader, writing the text it read. Chosen for CI on +// 2026-10-15 from five readers measured (docs/RTF-2026-10-15.md section 6.1): +// it is one apt install on the runner, it refuses a document without its +// closing brace and a \' without two hex digits, and it is neither our code nor +// our language. +// +// It is also the strictest reader in a way that is not a virtue - it shows +// codepage text in the wrong letters and drops a character after every letter +// written literal. Those are its readings of good files, which the guard of the +// format holds as such, so this checker asks only whether it read the file and +// said nothing about it. A warning on standard error counts as a complaint, +// the way it does for ffprobe. +var pandocRTF = Checker{ + Name: "pandoc", + find: inPath("pandoc"), + args: func(p string) []string { return []string{"-f", "rtf", "-t", "plain", "--wrap=none", p} }, + accept: func(stdout, stderr string, code int) error { + if code != 0 { + return fmt.Errorf("pandoc refused the document: %s", strings.TrimSpace(stderr)) + } + if s := strings.TrimSpace(stderr); s != "" { + return fmt.Errorf("pandoc complained: %s", s) + } + return nil + }, +} + +// PandocRTF is the same reader with what it printed kept apart from what it +// complained of, for a guard that reads the text: standard output as it was, +// and the warnings, which codepage is measured to bring. +func PandocRTF(path string) (text, warnings string, res Result) { + c := pandocRTF + var out, errOut string + c.accept = func(stdout, stderr string, code int) error { + out, errOut = stdout, stderr + if code != 0 { + return fmt.Errorf("pandoc refused the document: %s", strings.TrimSpace(stderr)) + } + return nil + } + res = c.Check(path) + return out, strings.TrimSpace(errOut), res +} diff --git a/internal/oracle/strict.py b/internal/oracle/strict.py index 9d36d3d1..57eae8b2 100644 --- a/internal/oracle/strict.py +++ b/internal/oracle/strict.py @@ -18,6 +18,7 @@ import re import struct import sys +import unicodedata import zlib from html.parser import HTMLParser @@ -3537,6 +3538,360 @@ def eml_quoted(value, encoded): return b"".join(base64.b64decode(w) for w in words).decode("utf-8") +# RTF, written against the specification (RTF 1.6, read 2026-10-15) and the +# measurement in docs/RTF-2026-10-15.md section 6.1. Five readers took eleven of +# twelve broken files, so this is the layer that refuses them. + +RTF_BS = chr(92) +# The code page each \fcharset the generator declares stands for. +RTF_CHARSETS = {0: "cp1252", 238: "cp1250", 204: "cp1251", 128: "cp932", 178: "cp1256"} +RTF_NAMED = {"emdash": chr(0x2014), "endash": chr(0x2013), "lquote": chr(0x2018), "rquote": chr(0x2019), + "ldblquote": chr(0x201C), "rdblquote": chr(0x201D), "bullet": chr(0x2022), "tab": "\t", + "line": "\n"} +# The sentences characters=international adds, built from their code points +# here rather than taken from the generator. +RTF_ARABIC = "".join(chr(c) for c in (0x647, 0x630, 0x627, 0x20, 0x646, 0x635, 0x20, 0x628, 0x627, 0x644, + 0x644, 0x63A, 0x629, 0x20, 0x627, 0x644, 0x639, 0x631, 0x628, 0x64A, + 0x629, 0x2E)) +RTF_SCRIPTS = [ + "Za" + chr(0x17C) + chr(0xF3) + chr(0x142) + chr(0x107) + " g" + chr(0x119) + chr(0x15B) + "l" + chr(0x105) + + " ja" + chr(0x17A) + chr(0x144) + ".", + "".join(chr(c) for c in (0x42D, 0x442, 0x43E)) + " " + "".join(chr(c) for c in (0x442, 0x435, 0x43A, 0x441, 0x442)) + + " " + chr(0x43D) + chr(0x430) + " " + "".join(chr(c) for c in (0x440, 0x443, 0x441, 0x441, 0x43A, 0x43E, 0x43C)) + + " " + "".join(chr(c) for c in (0x44F, 0x437, 0x44B, 0x43A, 0x435)) + ".", + "".join(chr(c) for c in (0x3053, 0x308C, 0x306F, 0x65E5, 0x672C, 0x8A9E, 0x306E, 0x30C6, 0x30AD, 0x30B9, + 0x30C8, 0x3067, 0x3059, 0x3002)), + RTF_ARABIC, + "Emoji " + chr(0x1F600) + " and a sequence " + chr(0x1F469) + chr(0x200D) + chr(0x1F4BB) + + ", a letter in two code points e" + chr(0x301) + ", the characters RTF escapes " + RTF_BS + " { }" + + " and the ones it names " + chr(0x2014) + " " + chr(0x2013) + " " + chr(0x2018) + "q" + chr(0x2019) + + " " + chr(0x201C) + "qq" + chr(0x201D) + " " + chr(0x2022) + ", a space that does not break" + chr(0xA0) + + "and the euro " + chr(0x20AC) + ".", +] +# Every control word the generator writes, by what asks for it. A word outside +# these is a typo a tolerant reader would skip in silence. +RTF_WORDS = {"rtf", "ansi", "ansicpg", "deff", "uc", "fonttbl", "f", "fswiss", "par", "pard", + "outlinelevel", "b", "i", "fs", "li", "fi", "pntext", "bullet", "tab", "pn", "pnlvlblt", + "pnindent", "pntxtb", "trowd", "cellx", "intbl", "cell", "row"} +RTF_WORDS_INTERNATIONAL = {"fcharset", "fmodern", "rtlpar", "rtlch", "u", "emdash", "endash", "lquote", + "rquote", "ldblquote", "rdblquote"} +RTF_WORDS_EVERY = {"info", "title", "author", "keywords", "doccomm", "header", "footer", "super", "chftn", + "footnote", "plain", "atnid", "atnauthor", "chatn", "annotation", "v", "field", "fldinst", + "fldrslt", "bkmkstart", "bkmkend", "tfgunknown", "tfgword", "line", "page", "sect", "sectd"} +RTF_EVERY_PIECES = ["{" + RTF_BS + "info{" + RTF_BS + "title ", "{" + RTF_BS + "header" + RTF_BS + "pard ", + "{" + RTF_BS + "footer" + RTF_BS + "pard ", "{" + RTF_BS + "footnote" + RTF_BS + "pard", + RTF_BS + "*" + RTF_BS + "annotation", "{" + RTF_BS + "v ", + RTF_BS + "fldinst HYPERLINK \"https://example.com/", RTF_BS + "*" + RTF_BS + "bkmkstart ", + "{" + RTF_BS + "*" + RTF_BS + "tfgunknown ", "{" + RTF_BS + "tfgword ", + RTF_BS + "line ", RTF_BS + "page", RTF_BS + "sect" + RTF_BS + "sectd"] + + +def rtf_tokens(text): + """The tokens of the document, in order: ("{",), ("}",), ("word", name, + parameter or None), ("hex", byte), ("sym", character), ("text", character) + and ("eol", character). A word longer than the 32 letters the + specification allows, a parameter outside a signed 16 bit number and a + \\' without two hex digits end the check.""" + i, n = 0, len(text) + while i < n: + c = text[i] + if c in "{}": + yield (c,) + i += 1 + elif c in "\r\n": + yield ("eol", c) + i += 1 + elif c != RTF_BS: + yield ("text", c) + i += 1 + else: + i = yield from rtf_control(text, i + 1) + + +def rtf_control(text, i): + """One control word or control symbol after its backslash, and where the + next token starts.""" + m = re.match(r"([a-z]+)(-?[0-9]+)? ?", text[i:i + 64]) + if m: + name = m.group(1) + if len(name) > 32: + fail(f"a control word of {len(name)} letters, past the 32 the specification allows: {name[:40]}") + param = int(m.group(2)) if m.group(2) is not None else None + if param is not None and not -32768 <= param <= 32767: + fail(f"\\{name} carries {param}, outside a signed 16 bit number") + yield ("word", name, param) + return i + m.end() + if text[i:i + 1] == "'": + h = text[i + 1:i + 3] + if not re.fullmatch(r"[0-9a-f]{2}", h): + fail(f"\\' is followed by {h!r} rather than two lower case hex digits") + yield ("hex", int(h, 16)) + return i + 3 + if i >= len(text): + fail("the document ends with a backslash, which escapes nothing") + yield ("sym", text[i]) + return i + 1 + + +class RtfState: + """What the reader has to remember per group: the font, the count of + fallback characters after a \\u, and whether the group is a destination + whose text is not the body.""" + + def __init__(self, font=0, uc=1, hidden=False): + self.font, self.uc, self.hidden = font, uc, hidden + + def copy(self): + return RtfState(self.font, self.uc, self.hidden) + + +def rtf_fonts(data): + """The fonts the table declares, number to code page. + + Read entry by entry rather than with one expression for the whole table: + a repeated group of entries whose inside can also match a semicolon backs + off exponentially on a long table that never closes (CodeQL py/redos on + the first version, review of #191). Every entry is one group with no + group inside it, so the table ends at the first two closing braces.""" + start = data.find("{" + RTF_BS + "fonttbl{") + end = data.find("}}", start) + if start < 0 or end < 0: + fail("no font table, which the header of every document has to carry") + fonts = {} + for entry in data[start + len("{" + RTF_BS + "fonttbl"):end + 1].split("}")[:-1]: + m = re.fullmatch(r"\{\\f([0-9]+)([^{};]*);", entry) + if not m: + fail(f"a font table entry the generator never writes: {entry[:60]!r}") + num, rest = m.group(1), m.group(2) + cs = re.search(r"\\fcharset([0-9]+)", rest) + fonts[int(num)] = RTF_CHARSETS.get(int(cs.group(1)) if cs else 0) + if fonts[int(num)] is None: + fail(f"font {num} declares a character set this check does not know: {rest!r}") + return fonts + + +def rtf_read(data, settings): + """Walk the document once: the groups balance and close at the last byte, + every word is one the settings ask for, every \\u is followed by the + fallback text_encoding says, and no line end joins two words. Returns the + body paragraphs as text and the deepest group.""" + allowed = set(RTF_WORDS) + if settings.get("characters") == "international": + allowed |= RTF_WORDS_INTERNATIONAL + if settings.get("elements") == "every": + allowed |= RTF_WORDS_EVERY + fonts = rtf_fonts(data) + toks = list(rtf_tokens(data)) + stack, state, depth, deepest = [], RtfState(), 0, 0 + paras, cur, pending = [], [], [] + last, eol = None, False + k = 0 + while k < len(toks): + t = toks[k] + k += 1 + if t[0] == "{": + stack.append(state.copy()) + depth += 1 + deepest = max(deepest, depth) + if k < len(toks) and toks[k] == ("sym", "*"): + state.hidden = True + elif t[0] == "}": + if depth == 0: + fail("a closing brace with no group open") + rtf_flush(pending, fonts, state, cur) + state = stack.pop() + depth -= 1 + if depth == 0 and k != len(toks): + fail(f"{len(toks) - k} token(s) after the brace that closes the document") + elif t[0] == "eol": + eol = True + continue + elif t[0] == "word": + rtf_flush(pending, fonts, state, cur) + name, param = t[1], t[2] + if name not in allowed: + fail(f"\\{name}, which these settings never write") + if name in ("fonttbl", "info", "header", "footer", "footnote", "pntext", "pn", "fldinst", "atnid", + "atnauthor", "v"): + state.hidden = True + elif name == "f": + if param not in fonts: + fail(f"\\f{param} names a font the table does not declare") + state.font = param + elif name == "uc": + state.uc = param + elif name == "u": + k = rtf_fallback(toks, k, param, fonts, state, settings, cur) + elif name == "par" and not state.hidden: + paras.append("".join(cur)) + cur.clear() + elif name in RTF_NAMED and not state.hidden: + cur.append(RTF_NAMED[name]) + elif t[0] == "hex": + # Only codepage writes a letter as its bytes alone. The other three + # write a byte only as the fallback after a number, which the \u + # branch has already taken. + if settings.get("text_encoding", "unicode") != "codepage": + fail(f"a code page byte {t[1]:#04x} outside the fallback of a \\u, which {settings.get('text_encoding', 'unicode')} never writes") + pending.append(t[1]) + else: + if eol and last is not None and last[0] == "text" and last[1] != " " and t[0] == "text": + fail(f"a line end between {last[1]!r} and {t[1]!r}, which joins two words in every reader") + rtf_flush(pending, fonts, state, cur) + if not state.hidden: + cur.append(chr(0xA0) if t == ("sym", "~") else t[1]) + last, eol = t, False + if depth != 0: + fail(f"{depth} group(s) still open at the end of the document - five readers measured, three refuse it") + paras.append("".join(cur)) + return paras, deepest + + +def rtf_flush(pending, fonts, state, cur): + """Decode the code page bytes gathered so far in the font's code page.""" + if not pending: + return + raw = bytes(pending) + pending.clear() + try: + s = raw.decode(fonts[state.font]) + except UnicodeDecodeError: + fail(f"the bytes {raw.hex()} are not text in {fonts[state.font]}, the code page of font {state.font}") + if not state.hidden: + cur.append(s) + + +def rtf_fallback(toks, k, unit, fonts, state, settings, cur): + """A \\u and the uc characters after it: what they have to be under the + text_encoding the file was ordered in. Returns where the next token is.""" + unit = unit + 65536 if unit < 0 else unit + back = toks[k:k + state.uc] + if len(back) < state.uc or any(b[0] not in ("hex", "text") for b in back): + fail(f"\\u{unit} is followed by {back} rather than {state.uc} fallback character(s)") + k += state.uc + enc = settings.get("text_encoding", "unicode") + if 0xD800 <= unit < 0xDC00: + nxt = toks[k] if k < len(toks) else None + if nxt is None or nxt[0] != "word" or nxt[1] != "u" or not 0xDC00 <= (nxt[2] + 65536 if nxt[2] < 0 else nxt[2]) < 0xE000: + fail(f"the first half of a surrogate pair, {unit:#06x}, is not followed by the second") + if enc == "literal": + if back != [("text", "?")]: + fail(f"literal writes a question mark after \\u{unit}, and found {back}") + elif enc == "unicode" or 0xD800 <= unit < 0xE000: + if back != [("hex", 0x3F)]: + fail(f"{enc} writes \\'3f after \\u{unit}, and found {back}") + else: + rtf_page_fallback(unit, back, fonts[state.font], enc) + if state.hidden: + return k + # The second half of a pair joins the first into the code point the two + # stand for. Kept apart they compare unequal to the emoji, which is the + # mistake striprtf makes (section 6.1 c). + if 0xDC00 <= unit < 0xE000 and cur and 0xD800 <= ord(cur[-1][-1]) < 0xDC00: + high = ord(cur[-1][-1]) + cur[-1] = cur[-1][:-1] + chr(0x10000 + ((high - 0xD800) << 10) + (unit - 0xDC00)) + else: + cur.append(chr(unit)) + return k + + +def rtf_page_fallback(unit, back, page, enc): + """The fallback of both, or a \\u under codepage: the letter in the font's + code page, or \\'3f for a letter the code page does not hold.""" + try: + want = chr(unit).encode(page) + except UnicodeEncodeError: + want = None + got = bytes(b[1] for b in back if b[0] == "hex") + if want is None: + if back != [("hex", 0x3F)]: + fail(f"{chr(unit)!r} is not in {page}, so its fallback is \\'3f, and found {back}") + return + if enc == "codepage": + fail(f"codepage writes {chr(unit)!r} as its {page} bytes, and found it as \\u{unit}") + if got != want or len(got) != len(back): + fail(f"the fallback of \\u{unit} is {got.hex()} and {page} writes {want.hex()}") + + +def check_rtf(data, settings=None): + """The document is 7 bit text, its groups balance and close at the last + byte, and it holds what characters, text_encoding, elements, nesting and + the label ordered - read here by a reader of its own.""" + settings = settings or {} + bad = [b for b in data if b > 0x7E or (b < 0x20 and b not in (0x0D, 0x0A))] + if bad: + fail(f"{len(bad)} byte(s) outside 7 bit text, the first {bad[0]:#04x} - the generator writes every letter outside ASCII as an escape") + text = data.decode("ascii") + head = "{" + RTF_BS + "rtf1" + RTF_BS + "ansi" + RTF_BS + "ansicpg1252" + RTF_BS + "deff0" + RTF_BS + "uc1{" + RTF_BS + "fonttbl" + if not text.startswith(head): + fail(f"the header is not the one the generator writes: {text[:60]!r}") + if not text.endswith("}"): + fail("the document does not end with the brace that closes it") + paras, deepest = rtf_read(text, settings) + # Told before it is read, the way html_settings is: a value that is not a + # number is a verdict, not a traceback (review of #191). + raw = settings.get("nesting", "0") + if not re.fullmatch(r"[0-9]{1,8}", raw) or int(raw) > 10000000: + fail(f"the rtf check was told nesting={raw!r}, which is not a whole number from 0 to 10000000") + nesting = int(raw) + trailing = len(text) - len(text.rstrip("}")) + if trailing != nesting + 1: + fail(f"the document ends with {trailing} closing brace(s), and nesting {nesting} closes {nesting + 1}") + if not nesting + 1 <= deepest <= nesting + 4: + fail(f"the deepest group is {deepest} deep, and nesting {nesting} puts the content at {nesting + 1}") + rtf_label(paras, settings) + rtf_international(paras, text, settings) + rtf_every(text, settings) + ok(f"{len(paras)} paragraph(s), {deepest} group(s) deep") + + +def rtf_label(paras, settings): + """The label is the first paragraph of the body when the file carries it.""" + if settings.get("label") == "true" and not (paras and paras[0].startswith("tfg - rtf - ")): + fail(f"the first paragraph is {paras[0][:40] if paras else ''!r}, not the label") + if settings.get("label") == "false" and any(p.startswith("tfg - rtf - ") for p in paras): + fail("the document carries a label it was asked to go without") + + +def rtf_international(paras, text, settings): + """The five paragraphs in other scripts, each read back to the sentence, + when characters is international, and no escape at all when it is ascii.""" + if settings.get("characters") != "international": + # A number and a right to left paragraph are words rtf_read does not + # allow an ascii document, so they are refused there. A code page byte + # is not a word, and under codepage rtf_read lets it through - so it + # is the one mark asked here (review of #191). + if RTF_BS + "'" in text: + fail("characters ascii, and the document carries a code page byte") + return + norm = [unicodedata.normalize("NFC", p) for p in paras] + for sentence in RTF_SCRIPTS: + if unicodedata.normalize("NFC", sentence) not in norm: + close = [p for p in paras if p[:6] == sentence[:6]] + fail(f"no paragraph reads {sentence[:30]!r}, the nearest is {close[0][:40] if close else None!r}") + if settings.get("text_encoding") == "codepage" and RTF_BS + "'" not in text: + fail("codepage, and no code page byte in the document") + + +def rtf_every(text, settings): + """With every, each part where text hides, the properties and the page + header and footer in front of the label. + + With basic there is nothing to ask here: every word of those parts is + missing from the words rtf_read allows a basic document, so a basic file + carrying one is refused there, and a second check of the same words could + never fail (review of #191).""" + if settings.get("elements") != "every": + return + for piece in RTF_EVERY_PIECES: + if piece not in text: + fail(f"elements every, and no {piece!r}") + first = text.find("tfg - rtf - ") if "tfg - rtf - " in text else len(text) + for piece in RTF_EVERY_PIECES[:3]: + if text.find(piece) > first: + fail(f"{piece!r} comes after the first paragraph, and RTF puts it in front of the text") + + CHECKS = {"png": check_png, "wav": check_wav, "pdf": check_pdf, "zip": check_zip, "log": check_log, "csv": check_csv, "json": check_json, "xml": check_xml, "svg": check_svg, "html": check_html, "targz": check_targz, @@ -3546,12 +3901,12 @@ def eml_quoted(value, encoded): "docx": check_docx, "xlsx": check_xlsx, "pptx": check_pptx, "txt": check_txt, "md": check_md, "yaml": check_yaml, "toml": check_toml, "geojson": check_geojson, - "eml": check_eml} + "eml": check_eml, "rtf": check_rtf} # Checks that take the shape of the file as well as its bytes. Everything else # is handed the bytes alone, so adding a setting to one check cannot change how # any other one is called. -TAKES_SETTINGS = {"csv", "txt", "md", "json", "xml", "html", "geojson", "eml"} +TAKES_SETTINGS = {"csv", "txt", "md", "json", "xml", "html", "geojson", "eml", "rtf"} if __name__ == "__main__": if len(sys.argv) < 3 or sys.argv[1] not in CHECKS: diff --git a/web/assets/social-preview.png b/web/assets/social-preview.png index 88c924b1..d0ec5700 100644 Binary files a/web/assets/social-preview.png and b/web/assets/social-preview.png differ diff --git a/web/public/ar/corrupt-test-files/index.html b/web/public/ar/corrupt-test-files/index.html index fccd0d48..de5abb0d 100644 --- a/web/public/ar/corrupt-test-files/index.html +++ b/web/public/ar/corrupt-test-files/index.html @@ -198,7 +198,7 @@

الملف التالف يبقى بالحجم الذي طلبته

tfg generate --format pdf --size 1mb --count 5 --damage zero-head:bytes=16 --out ./broken

تُكتب الإعدادات بعد النقطتين. يمكن تكرار الخيار، وتُطبَّق أنواع التلف بالترتيب الذي تكتبه. ويعمل مع - كل واحدة من 30 صيغة. + كل واحدة من 31 صيغة.

diff --git a/web/public/ar/faq/index.html b/web/public/ar/faq/index.html index a1568437..761eef5f 100644 --- a/web/public/ar/faq/index.html +++ b/web/public/ar/faq/index.html @@ -205,7 +205,7 @@

الأسئلة الشائعة

ما الصيغ القادمة؟

-

7z وmp3. تعمل اليوم 30 صيغة من البداية إلى النهاية.

+

7z وmp3. تعمل اليوم 31 صيغة من البداية إلى النهاية.

@@ -276,7 +276,7 @@

الأسئلة الشائعة

{ "@type": "Question", "name": "ما الصيغ القادمة؟", - "acceptedAnswer": { "@type": "Answer", "text": "7z وmp3. تعمل اليوم 30 صيغة من البداية إلى النهاية." } + "acceptedAnswer": { "@type": "Answer", "text": "7z وmp3. تعمل اليوم 31 صيغة من البداية إلى النهاية." } }, { "@type": "Question", diff --git a/web/public/ar/formats/index.html b/web/public/ar/formats/index.html index 47679aca..94620c2f 100644 --- a/web/public/ar/formats/index.html +++ b/web/public/ar/formats/index.html @@ -4,8 +4,8 @@ -30 صيغة ملف مدعومة - PDF وDOCX وPNG وZIP وغيرها - +31 صيغة ملف مدعومة - PDF وDOCX وPNG وZIP وغيرها + @@ -33,8 +33,8 @@ - - + + @@ -62,8 +62,8 @@ - - + + @@ -144,7 +144,7 @@
-

30 صيغة ملف، كلٌّ منها يُولَّد بحجم دقيق

+

31 صيغة ملف، كلٌّ منها يُولَّد بحجم دقيق

كلٌّ منها ملف حقيقي من تلك الصيغة. يُفتح في البرنامج الذي يملكه، وعدد بايتاته هو ما طلبته بالضبط. ولا واحد منها أصفار حشوية أُلصق بها امتداد. @@ -307,6 +307,14 @@

30 صيغة ملف، كلٌّ منها يُولَّد بحجم دقيق

full libreoffice + + rtf + Rich Text Format + .rtf + 65 + full + pandoc-rtf + svg Scalable Vector Graphics @@ -926,6 +934,26 @@

الإعدادات التي تقبلها كل صيغة

slides 1 - 500 شرائح + + rtf + characters + ascii, international + + + + text_encoding + both, codepage, literal, unicode + + + + elements + basic, every + + + + nesting + 0 - 10000000 + svg width diff --git a/web/public/ar/index.html b/web/public/ar/index.html index bf807768..97240a09 100644 --- a/web/public/ar/index.html +++ b/web/public/ar/index.html @@ -4,7 +4,7 @@ -مولّد ملفات الاختبار لضمان الجودة - حجم دقيق، 30 صيغة حقيقية +مولّد ملفات الاختبار لضمان الجودة - حجم دقيق، 31 صيغة حقيقية @@ -33,7 +33,7 @@ - + @@ -62,7 +62,7 @@ - + @@ -76,7 +76,7 @@ "@type": "SoftwareApplication", "name": "Testing Files Generator", "alternateName": "tfg", - "description": "مولّد ملفات اختبار مجاني ومفتوح المصدر لضمان الجودة. ينتج ملفات حقيقية بـ 30 صيغة وبحجم دقيق، ويكتب بيانًا يحدد كيف يجب أن يتفاعل النظام قيد الاختبار مع كل ملف.", + "description": "مولّد ملفات اختبار مجاني ومفتوح المصدر لضمان الجودة. ينتج ملفات حقيقية بـ 31 صيغة وبحجم دقيق، ويكتب بيانًا يحدد كيف يجب أن يتفاعل النظام قيد الاختبار مع كل ملف.", "url": "https:\/\/testingfilesgenerator.donislawdev.com/", "applicationCategory": "DeveloperApplication", "applicationSubCategory": "Software Testing", @@ -157,7 +157,7 @@

ولّد ملفات اختبار حقيقية بحجم دقيق

- PDF وPNG وDOCX وZIP، 30 صيغة في المجمل، وكلٌّ منها ملف حقيقي + PDF وPNG وDOCX وZIP، 31 صيغة في المجمل، وكلٌّ منها ملف حقيقي يُفتح في البرنامج الذي يملكه، وبـالحجم الذي طلبته تمامًا. كما يدوّن كل تشغيل ما يجب أن يفعله تطبيقك بكل ملف. سطر أوامر ونافذة سطح مكتب، مجاني ومفتوح المصدر، ويعمل بالكامل على جهازك. @@ -179,7 +179,7 @@

ولّد ملفات اختبار حقيقية بحجم دقيق

  • - 30 + 31

    صيغة حقيقية، وكلٌّ منها يُفتح في البرنامج الذي يملكه

  • @@ -340,7 +340,7 @@

    مبني لمجموعة اختبارات تعمل دون إشراف

    اطلب 10485761 بايتًا واحصل على هذا العدد بالضبط. الحجم الذي لا تستطيع الصيغة بلوغه خطأ مع سبب، وليس ملفًا بحجم خاطئ أبدًا.

  • -

    30 صيغة حقيقية

    +

    31 صيغة حقيقية

    ليست أصفارًا حشوية بامتداد. يُفتح ملف PNG المولَّد في عارض الصور، ويُفتح DOCX في Word، ويُفك ضغط ZIP. وتُفحص كل صيغة بقرّاء مستقلين قبل إصدارها.

  • diff --git a/web/public/ar/presets/empty-and-minimal/index.html b/web/public/ar/presets/empty-and-minimal/index.html index 651fb2d0..49d4b149 100644 --- a/web/public/ar/presets/empty-and-minimal/index.html +++ b/web/public/ar/presets/empty-and-minimal/index.html @@ -5,7 +5,7 @@ أصغر ملفات اختبار صالحة وفارغة في كل صيغة - + @@ -34,7 +34,7 @@ - + @@ -63,7 +63,7 @@ - + @@ -178,10 +178,10 @@

    ماذا في المجموعة؟

    - - - - + + + +
    الملفات32
    الأهداف في وصفته32
    الحجم الإجمالي40 431 B
    الصيغavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
    الملفات33
    الأهداف في وصفته33
    الحجم الإجمالي40 496 B
    الصيغavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, rtf, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
    @@ -192,7 +192,7 @@

    ماذا في المجموعة؟

    المتوقعالمعنىالملفات - acceptينبغي أن يقبل نظامك الملف.30 + acceptينبغي أن يقبل نظامك الملف.31 unspecifiedيعتمد على قواعد نظامك. أنت من يقرر، ثم تتحقق من أن ما يحدث هو ما قصدته.2 diff --git a/web/public/assets/social-preview.png b/web/public/assets/social-preview.png index 88c924b1..d0ec5700 100644 Binary files a/web/public/assets/social-preview.png and b/web/public/assets/social-preview.png differ diff --git a/web/public/corrupt-test-files/index.html b/web/public/corrupt-test-files/index.html index 5061535d..61c9665d 100644 --- a/web/public/corrupt-test-files/index.html +++ b/web/public/corrupt-test-files/index.html @@ -201,7 +201,7 @@

    A damaged file is still the size you asked for

    tfg generate --format pdf --size 1mb --count 5 --damage zero-head:bytes=16 --out ./broken

    Settings go after a colon. The flag can be repeated, and the damages are applied in the order you - write them. It works with every one of the 30 formats. + write them. It works with every one of the 31 formats.

    diff --git a/web/public/cs/faq/index.html b/web/public/cs/faq/index.html index b8d75221..8cf64a6c 100644 --- a/web/public/cs/faq/index.html +++ b/web/public/cs/faq/index.html @@ -206,7 +206,7 @@

    Často kladené otázky

    Které formáty přijdou dál?

    -

    7z a mp3. Dnes funguje od začátku do konce 30 formátů.

    +

    7z a mp3. Dnes funguje od začátku do konce 31 formátů.

    @@ -277,7 +277,7 @@

    Často kladené otázky

    { "@type": "Question", "name": "Které formáty přijdou dál?", - "acceptedAnswer": { "@type": "Answer", "text": "7z a mp3. Dnes funguje od začátku do konce 30 formátů." } + "acceptedAnswer": { "@type": "Answer", "text": "7z a mp3. Dnes funguje od začátku do konce 31 formátů." } }, { "@type": "Question", diff --git a/web/public/cs/formaty/index.html b/web/public/cs/formaty/index.html index dc4b1397..a27b2eeb 100644 --- a/web/public/cs/formaty/index.html +++ b/web/public/cs/formaty/index.html @@ -4,8 +4,8 @@ -30 podporovaných formátů souborů - PDF, DOCX, PNG, ZIP a další - +31 podporovaných formátů souborů - PDF, DOCX, PNG, ZIP a další + @@ -33,8 +33,8 @@ - - + + @@ -62,8 +62,8 @@ - - + + @@ -144,7 +144,7 @@
    -

    30 formátů souborů, každý generovaný v přesné velikosti

    +

    31 formátů souborů, každý generovaný v přesné velikosti

    Každý z nich je skutečný soubor toho formátu. Otevře se v programu, kam patří, a má přesně tolik bajtů, kolik jste požádali. Žádný není vycpávka z nul s přilepenou příponou. @@ -307,6 +307,14 @@

    30 formátů souborů, každý generovaný v přesné velikosti

    full libreoffice + + rtf + Rich Text Format + .rtf + 65 + full + pandoc-rtf + svg Scalable Vector Graphics @@ -927,6 +935,26 @@

    Nastavení, která každý formát přijímá

    slides 1 - 500 snímků + + rtf + characters + ascii, international + + + + text_encoding + both, codepage, literal, unicode + + + + elements + basic, every + + + + nesting + 0 - 10000000 + svg width diff --git a/web/public/cs/index.html b/web/public/cs/index.html index 0c16aad0..6d4e4158 100644 --- a/web/public/cs/index.html +++ b/web/public/cs/index.html @@ -4,7 +4,7 @@ -Generátor testovacích souborů - přesná velikost, 30 formátů +Generátor testovacích souborů - přesná velikost, 31 formátů @@ -33,7 +33,7 @@ - + @@ -62,7 +62,7 @@ - + @@ -76,7 +76,7 @@ "@type": "SoftwareApplication", "name": "Testing Files Generator", "alternateName": "tfg", - "description": "Bezplatný open source generátor testovacích souborů pro QA. Vytváří skutečné soubory v 30 formátech v přesné velikosti a zapisuje manifest, který říká, jak má testovaný systém na každý z nich reagovat.", + "description": "Bezplatný open source generátor testovacích souborů pro QA. Vytváří skutečné soubory v 31 formátech v přesné velikosti a zapisuje manifest, který říká, jak má testovaný systém na každý z nich reagovat.", "url": "https:\/\/testingfilesgenerator.donislawdev.com/", "applicationCategory": "DeveloperApplication", "applicationSubCategory": "Software Testing", @@ -157,7 +157,7 @@

    Generujte skutečné testovací soubory v přesné velikosti

    - PDF, PNG, DOCX, ZIP - celkem 30 formátů a každý je skutečný + PDF, PNG, DOCX, ZIP - celkem 31 formátů a každý je skutečný soubor, který se otevře v programu, kam patří, v přesně té velikosti, o kterou jste požádali. Každý běh také zapisuje, co má vaše aplikace s každým souborem udělat. Příkazový řádek a desktopové okno, zdarma a open source, celé na vašem počítači. @@ -179,7 +179,7 @@

    Generujte skutečné testovací soubory v přesné velikosti

    • - 30 + 31

      skutečných formátů, každý se otevře v programu, kam patří

    • @@ -341,7 +341,7 @@

      Vytvořeno pro sadu testů, která běží bez dozoru

      Požádejte o 10485761 bajtů a dostanete přesně tolik. Velikost, které formát nedosáhne, je chyba s důvodem, nikdy soubor špatné velikosti.

    • -

      30 skutečných formátů

      +

      31 skutečných formátů

      Ne vycpávkové nuly s příponou. Vygenerované PNG se otevře v prohlížeči obrázků, DOCX ve Wordu, ZIP se rozbalí. Každý formát je před vydáním ověřen nezávislými čtečkami.

    • diff --git a/web/public/cs/poskozene-testovaci-soubory/index.html b/web/public/cs/poskozene-testovaci-soubory/index.html index 0c9691a0..c95ef78f 100644 --- a/web/public/cs/poskozene-testovaci-soubory/index.html +++ b/web/public/cs/poskozene-testovaci-soubory/index.html @@ -200,7 +200,7 @@

      Poškozený soubor má stále velikost, kterou jste chtěli

      tfg generate --format pdf --size 1mb --count 5 --damage zero-head:bytes=16 --out ./broken

      Nastavení se píše za dvojtečku. Přepínač lze opakovat a poškození se použijí v pořadí, v jakém je - zapíšete. Funguje s každým z 30 formátů. + zapíšete. Funguje s každým z 31 formátů.

      diff --git a/web/public/cs/predvolby/empty-and-minimal/index.html b/web/public/cs/predvolby/empty-and-minimal/index.html index c94e5e1b..5e39e3ca 100644 --- a/web/public/cs/predvolby/empty-and-minimal/index.html +++ b/web/public/cs/predvolby/empty-and-minimal/index.html @@ -5,7 +5,7 @@ Nejmenší platné a prázdné testovací soubory v každém formátu - + @@ -34,7 +34,7 @@ - + @@ -63,7 +63,7 @@ - + @@ -178,10 +178,10 @@

      Co je v sadě?

      - - - - + + + +
      Soubory32
      Targety v receptu32
      Celková velikost40 431 B
      Formátyavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
      Soubory33
      Targety v receptu33
      Celková velikost40 496 B
      Formátyavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, rtf, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
      @@ -192,7 +192,7 @@

      Co je v sadě?

      OčekávánoVýznamSoubory - acceptVáš systém má soubor přijmout.30 + acceptVáš systém má soubor přijmout.31 unspecifiedZáleží na pravidlech vašeho systému. Rozhodnete vy, a pak ověříte, že to, co se stane, je to, co jste chtěli.2 diff --git a/web/public/de/beschaedigte-testdateien/index.html b/web/public/de/beschaedigte-testdateien/index.html index cd61d4eb..c1c32b01 100644 --- a/web/public/de/beschaedigte-testdateien/index.html +++ b/web/public/de/beschaedigte-testdateien/index.html @@ -203,7 +203,7 @@

      Eine beschädigte Datei hat trotzdem die verlangte Größe

      Einstellungen stehen nach einem Doppelpunkt. Die Option lässt sich wiederholen, und die Beschädigungen werden in der Reihenfolge angewendet, in der Sie sie schreiben. Es funktioniert - mit allen 30 Formaten. + mit allen 31 Formaten.

      diff --git a/web/public/de/faq/index.html b/web/public/de/faq/index.html index 62890443..bfaa7d1c 100644 --- a/web/public/de/faq/index.html +++ b/web/public/de/faq/index.html @@ -206,7 +206,7 @@

      Häufig gestellte Fragen

      Welche Formate kommen als Nächstes?

      -

      7z und mp3. 30 Formate funktionieren heute durchgängig.

      +

      7z und mp3. 31 Formate funktionieren heute durchgängig.

      @@ -277,7 +277,7 @@

      Häufig gestellte Fragen

      { "@type": "Question", "name": "Welche Formate kommen als Nächstes?", - "acceptedAnswer": { "@type": "Answer", "text": "7z und mp3. 30 Formate funktionieren heute durchgängig." } + "acceptedAnswer": { "@type": "Answer", "text": "7z und mp3. 31 Formate funktionieren heute durchgängig." } }, { "@type": "Question", diff --git a/web/public/de/formate/index.html b/web/public/de/formate/index.html index 933b836e..d4c18450 100644 --- a/web/public/de/formate/index.html +++ b/web/public/de/formate/index.html @@ -4,8 +4,8 @@ -30 unterstützte Dateiformate - PDF, DOCX, PNG, ZIP und mehr - +31 unterstützte Dateiformate - PDF, DOCX, PNG, ZIP und mehr + @@ -33,8 +33,8 @@ - - + + @@ -62,8 +62,8 @@ - - + + @@ -144,7 +144,7 @@
      -

      30 Dateiformate, jedes in exakter Größe erzeugt

      +

      31 Dateiformate, jedes in exakter Größe erzeugt

      Jedes davon ist eine echte Datei dieses Formats. Sie öffnet sich in der Software, zu der sie gehört, und hat genau die Byte-Zahl, die du verlangt hast. Keines davon besteht aus @@ -308,6 +308,14 @@

      30 Dateiformate, jedes in exakter Größe erzeugt

      full libreoffice + + rtf + Rich Text Format + .rtf + 65 + full + pandoc-rtf + svg Scalable Vector Graphics @@ -929,6 +937,26 @@

      Einstellungen, die jedes Format kennt

      slides 1 - 500 Folien + + rtf + characters + ascii, international + + + + text_encoding + both, codepage, literal, unicode + + + + elements + basic, every + + + + nesting + 0 - 10000000 + svg width diff --git a/web/public/de/index.html b/web/public/de/index.html index 3e5f1832..9b3d5553 100644 --- a/web/public/de/index.html +++ b/web/public/de/index.html @@ -4,7 +4,7 @@ -Testdatei-Generator für QA - exakte Größe, 30 echte Formate +Testdatei-Generator für QA - exakte Größe, 31 echte Formate @@ -33,7 +33,7 @@ - + @@ -62,7 +62,7 @@ - + @@ -76,7 +76,7 @@ "@type": "SoftwareApplication", "name": "Testing Files Generator", "alternateName": "tfg", - "description": "Ein kostenloser Open-Source-Generator für Testdateien in der QA. Er erzeugt echte Dateien in 30 Formaten in jeder exakten Größe und schreibt ein Manifest, das beschreibt, wie das getestete System auf jede Datei reagieren soll.", + "description": "Ein kostenloser Open-Source-Generator für Testdateien in der QA. Er erzeugt echte Dateien in 31 Formaten in jeder exakten Größe und schreibt ein Manifest, das beschreibt, wie das getestete System auf jede Datei reagieren soll.", "url": "https:\/\/testingfilesgenerator.donislawdev.com/", "applicationCategory": "DeveloperApplication", "applicationSubCategory": "Software Testing", @@ -157,7 +157,7 @@

      Echte Testdateien in jeder exakten Größe erzeugen

      - PDF, PNG, DOCX, ZIP - insgesamt 30 Formate, und jedes ist + PDF, PNG, DOCX, ZIP - insgesamt 31 Formate, und jedes ist eine echte Datei, die sich in der Software öffnet, zu der sie gehört, in genau der Größe, die du verlangt hast. Jeder Lauf hält außerdem fest, was deine Anwendung mit jeder Datei tun soll. Kommandozeile und Desktop-Fenster, kostenlos und Open Source, vollständig @@ -180,7 +180,7 @@

      Echte Testdateien in jeder exakten Größe erzeugen

      • - 30 + 31

        echte Formate, jedes öffnet sich in der Software, zu der es gehört

      • @@ -345,7 +345,7 @@

        Gebaut für eine Testsuite, die unbeaufsichtigt läuft

        Verlange 10485761 Bytes und bekomme genau das. Eine Größe, die ein Format nicht erreichen kann, ist ein Fehler mit Begründung, nie eine Datei in der falschen Größe.

      • -

        30 echte Formate

        +

        31 echte Formate

        Keine aufgefüllten Nullen mit einer Endung. Ein erzeugtes PNG öffnet sich im Bildbetrachter, ein DOCX in Word, ein ZIP lässt sich entpacken. Jedes wird vor der Auslieferung mit unabhängigen Readern geprüft.

      • diff --git a/web/public/de/presets/empty-and-minimal/index.html b/web/public/de/presets/empty-and-minimal/index.html index 7acb505e..88578262 100644 --- a/web/public/de/presets/empty-and-minimal/index.html +++ b/web/public/de/presets/empty-and-minimal/index.html @@ -5,7 +5,7 @@ Kleinste gültige und leere Testdateien in jedem Format - + @@ -34,7 +34,7 @@ - + @@ -63,7 +63,7 @@ - + @@ -178,10 +178,10 @@

        Was steckt im Set?

        - - - - + + + +
        Dateien32
        Targets in seinem Rezept32
        Gesamtgröße40 431 B
        Formateavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
        Dateien33
        Targets in seinem Rezept33
        Gesamtgröße40 496 B
        Formateavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, rtf, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
        @@ -192,7 +192,7 @@

        Was steckt im Set?

        ErwartetBedeutungDateien - acceptDein System soll die Datei annehmen.30 + acceptDein System soll die Datei annehmen.31 unspecifiedDas hängt von den Regeln deines Systems ab. Du entscheidest, dann prüfst du, ob das Ergebnis dem entspricht, was du gemeint hast.2 diff --git a/web/public/es/archivos-de-prueba-corruptos/index.html b/web/public/es/archivos-de-prueba-corruptos/index.html index e41dfb87..d616eb80 100644 --- a/web/public/es/archivos-de-prueba-corruptos/index.html +++ b/web/public/es/archivos-de-prueba-corruptos/index.html @@ -201,7 +201,7 @@

        Un archivo dañado conserva el tamaño que pediste

        tfg generate --format pdf --size 1mb --count 5 --damage zero-head:bytes=16 --out ./broken

        Los ajustes van después de dos puntos. La opción se puede repetir, y los daños se aplican en el - orden en que los escribes. Funciona con cada uno de los 30 formatos. + orden en que los escribes. Funciona con cada uno de los 31 formatos.

        diff --git a/web/public/es/formatos/index.html b/web/public/es/formatos/index.html index b932d993..864213c6 100644 --- a/web/public/es/formatos/index.html +++ b/web/public/es/formatos/index.html @@ -4,8 +4,8 @@ -30 formatos de archivo - PDF, DOCX, PNG, ZIP y más - +31 formatos de archivo - PDF, DOCX, PNG, ZIP y más + @@ -33,8 +33,8 @@ - - + + @@ -62,8 +62,8 @@ - - + + @@ -144,7 +144,7 @@
        -

        30 formatos de archivo, cada uno generado a un tamaño exacto

        +

        31 formatos de archivo, cada uno generado a un tamaño exacto

        Cada uno es un archivo real de ese formato. Se abre en el programa que le corresponde y tiene exactamente el número de bytes que pediste. Ninguno es relleno de ceros con @@ -308,6 +308,14 @@

        30 formatos de archivo, cada uno generado a un tamaño exacto

        full libreoffice + + rtf + Rich Text Format + .rtf + 65 + full + pandoc-rtf + svg Scalable Vector Graphics @@ -930,6 +938,26 @@

        Ajustes que admite cada formato

        slides 1 - 500 diapositivas + + rtf + characters + ascii, international + + + + text_encoding + both, codepage, literal, unicode + + + + elements + basic, every + + + + nesting + 0 - 10000000 + svg width diff --git a/web/public/es/index.html b/web/public/es/index.html index be15f7c0..2408cf1a 100644 --- a/web/public/es/index.html +++ b/web/public/es/index.html @@ -4,7 +4,7 @@ -Generador de archivos de prueba - tamaño exacto, 30 formatos +Generador de archivos de prueba - tamaño exacto, 31 formatos @@ -33,7 +33,7 @@ - + @@ -62,7 +62,7 @@ - + @@ -76,7 +76,7 @@ "@type": "SoftwareApplication", "name": "Testing Files Generator", "alternateName": "tfg", - "description": "Un generador gratuito y de código abierto de archivos de prueba para QA. Produce archivos reales de 30 formatos al tamaño exacto y escribe un manifiesto que dice cómo debe reaccionar el sistema bajo prueba a cada uno.", + "description": "Un generador gratuito y de código abierto de archivos de prueba para QA. Produce archivos reales de 31 formatos al tamaño exacto y escribe un manifiesto que dice cómo debe reaccionar el sistema bajo prueba a cada uno.", "url": "https:\/\/testingfilesgenerator.donislawdev.com/", "applicationCategory": "DeveloperApplication", "applicationSubCategory": "Software Testing", @@ -157,7 +157,7 @@

        Genera archivos de prueba reales al tamaño exacto

        - PDF, PNG, DOCX, ZIP - 30 formatos en total, y cada uno es un + PDF, PNG, DOCX, ZIP - 31 formatos en total, y cada uno es un archivo real que se abre en el programa que le corresponde, con exactamente el tamaño que pediste. Cada ejecución también anota qué debe hacer tu aplicación con cada archivo. Línea de comandos y ventana de escritorio, gratis y de código abierto, funcionando por @@ -180,7 +180,7 @@

        Genera archivos de prueba reales al tamaño exacto

        • - 30 + 31

          formatos reales, cada uno se abre en el programa que le corresponde

        • @@ -345,7 +345,7 @@

          Pensado para un conjunto de pruebas que corre sin supervisión

          Pide 10485761 bytes y obtén exactamente eso. Un tamaño que un formato no puede alcanzar es un error con un motivo, nunca un archivo del tamaño equivocado.

        • -

          30 formatos reales

          +

          31 formatos reales

          No ceros de relleno con una extensión. Un PNG generado se abre en un visor de imágenes, un DOCX se abre en Word, un ZIP se extrae. Cada uno se comprueba con lectores independientes antes de publicarse.

        • diff --git a/web/public/es/preguntas-frecuentes/index.html b/web/public/es/preguntas-frecuentes/index.html index f8c5687d..77e7ac40 100644 --- a/web/public/es/preguntas-frecuentes/index.html +++ b/web/public/es/preguntas-frecuentes/index.html @@ -206,7 +206,7 @@

          Preguntas frecuentes

          ¿Qué formatos vienen después?

          -

          7z y mp3. Hoy funcionan de principio a fin 30 formatos.

          +

          7z y mp3. Hoy funcionan de principio a fin 31 formatos.

          @@ -277,7 +277,7 @@

          Preguntas frecuentes

          { "@type": "Question", "name": "¿Qué formatos vienen después?", - "acceptedAnswer": { "@type": "Answer", "text": "7z y mp3. Hoy funcionan de principio a fin 30 formatos." } + "acceptedAnswer": { "@type": "Answer", "text": "7z y mp3. Hoy funcionan de principio a fin 31 formatos." } }, { "@type": "Question", diff --git a/web/public/es/presets/empty-and-minimal/index.html b/web/public/es/presets/empty-and-minimal/index.html index b1c76363..cfd55acf 100644 --- a/web/public/es/presets/empty-and-minimal/index.html +++ b/web/public/es/presets/empty-and-minimal/index.html @@ -5,7 +5,7 @@ Archivos de prueba válidos mínimos y vacíos en cada formato - + @@ -34,7 +34,7 @@ - + @@ -63,7 +63,7 @@ - + @@ -179,10 +179,10 @@

          ¿Qué hay en el conjunto?

          - - - - + + + +
          Archivos32
          Targets en su receta32
          Tamaño total40 431 B
          Formatosavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
          Archivos33
          Targets en su receta33
          Tamaño total40 496 B
          Formatosavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, rtf, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
          @@ -193,7 +193,7 @@

          ¿Qué hay en el conjunto?

          EsperadoSignificadoArchivos - acceptTu sistema debe aceptar el archivo.30 + acceptTu sistema debe aceptar el archivo.31 unspecifiedDepende de las reglas de tu sistema. Tú decides y después compruebas que lo que ocurre es lo que querías.2 diff --git a/web/public/faq/index.html b/web/public/faq/index.html index 6087fa77..7a26714d 100644 --- a/web/public/faq/index.html +++ b/web/public/faq/index.html @@ -205,7 +205,7 @@

          Frequently asked questions

          Which formats are coming next?

          -

          7z and mp3. 30 formats work end to end today.

          +

          7z and mp3. 31 formats work end to end today.

          @@ -276,7 +276,7 @@

          Frequently asked questions

          { "@type": "Question", "name": "Which formats are coming next?", - "acceptedAnswer": { "@type": "Answer", "text": "7z and mp3. 30 formats work end to end today." } + "acceptedAnswer": { "@type": "Answer", "text": "7z and mp3. 31 formats work end to end today." } }, { "@type": "Question", diff --git a/web/public/formats/index.html b/web/public/formats/index.html index a4def76a..1112f510 100644 --- a/web/public/formats/index.html +++ b/web/public/formats/index.html @@ -4,8 +4,8 @@ -30 Supported File Formats - PDF, DOCX, PNG, ZIP and More - +31 Supported File Formats - PDF, DOCX, PNG, ZIP and More + @@ -33,8 +33,8 @@ - - + + @@ -62,8 +62,8 @@ - - + + @@ -144,7 +144,7 @@
          -

          30 file formats, every one generated at an exact size

          +

          31 file formats, every one generated at an exact size

          Each of these is a real file of that format. It opens in the software that owns it, and it is exactly the number of bytes you asked for. None of them is padded zeros with an extension @@ -308,6 +308,14 @@

          30 file formats, every one generated at an exact size

          full libreoffice + + rtf + Rich Text Format + .rtf + 65 + full + pandoc-rtf + svg Scalable Vector Graphics @@ -928,6 +936,26 @@

          Settings each format accepts

          slides 1 - 500 slides + + rtf + characters + ascii, international + + + + text_encoding + both, codepage, literal, unicode + + + + elements + basic, every + + + + nesting + 0 - 10000000 + svg width diff --git a/web/public/fr/faq/index.html b/web/public/fr/faq/index.html index 47551aa6..63098df3 100644 --- a/web/public/fr/faq/index.html +++ b/web/public/fr/faq/index.html @@ -206,7 +206,7 @@

          Questions fréquentes

          Quels formats arrivent ensuite ?

          -

          7z et mp3. 30 formats fonctionnent de bout en bout aujourd'hui.

          +

          7z et mp3. 31 formats fonctionnent de bout en bout aujourd'hui.

          @@ -277,7 +277,7 @@

          Questions fréquentes

          { "@type": "Question", "name": "Quels formats arrivent ensuite ?", - "acceptedAnswer": { "@type": "Answer", "text": "7z et mp3. 30 formats fonctionnent de bout en bout aujourd\u0027hui." } + "acceptedAnswer": { "@type": "Answer", "text": "7z et mp3. 31 formats fonctionnent de bout en bout aujourd\u0027hui." } }, { "@type": "Question", diff --git a/web/public/fr/fichiers-de-test-corrompus/index.html b/web/public/fr/fichiers-de-test-corrompus/index.html index 95c4002d..1c0fae63 100644 --- a/web/public/fr/fichiers-de-test-corrompus/index.html +++ b/web/public/fr/fichiers-de-test-corrompus/index.html @@ -202,7 +202,7 @@

          Un fichier abîmé garde la taille demandée

          tfg generate --format pdf --size 1mb --count 5 --damage zero-head:bytes=16 --out ./broken

          Les réglages se placent après deux-points. L'option peut être répétée, et les dommages s'appliquent - dans l'ordre où vous les écrivez. Ça marche avec chacun des 30 formats. + dans l'ordre où vous les écrivez. Ça marche avec chacun des 31 formats.

          diff --git a/web/public/fr/formats/index.html b/web/public/fr/formats/index.html index 4eef541c..75631a1d 100644 --- a/web/public/fr/formats/index.html +++ b/web/public/fr/formats/index.html @@ -4,8 +4,8 @@ -30 formats de fichiers - PDF, DOCX, PNG, ZIP et plus - +31 formats de fichiers - PDF, DOCX, PNG, ZIP et plus + @@ -33,8 +33,8 @@ - - + + @@ -62,8 +62,8 @@ - - + + @@ -144,7 +144,7 @@
          -

          30 formats de fichiers, chacun généré à une taille exacte

          +

          31 formats de fichiers, chacun généré à une taille exacte

          Chacun est un vrai fichier de ce format. Il s'ouvre dans le logiciel qui lui correspond et fait exactement le nombre d'octets que vous avez demandé. Aucun n'est du remplissage @@ -308,6 +308,14 @@

          30 formats de fichiers, chacun généré à une taille exacte

          full libreoffice + + rtf + Rich Text Format + .rtf + 65 + full + pandoc-rtf + svg Scalable Vector Graphics @@ -930,6 +938,26 @@

          Réglages que chaque format accepte

          slides 1 - 500 diapositives + + rtf + characters + ascii, international + + + + text_encoding + both, codepage, literal, unicode + + + + elements + basic, every + + + + nesting + 0 - 10000000 + svg width diff --git a/web/public/fr/index.html b/web/public/fr/index.html index 6bc27da2..f26b49c5 100644 --- a/web/public/fr/index.html +++ b/web/public/fr/index.html @@ -4,7 +4,7 @@ -Générateur de fichiers de test - taille exacte, 30 vrais formats +Générateur de fichiers de test - taille exacte, 31 vrais formats @@ -33,7 +33,7 @@ - + @@ -62,7 +62,7 @@ - + @@ -76,7 +76,7 @@ "@type": "SoftwareApplication", "name": "Testing Files Generator", "alternateName": "tfg", - "description": "Un générateur gratuit et open source de fichiers de test pour la QA. Il produit de vrais fichiers dans 30 formats, à la taille exacte, et écrit un manifeste qui dit comment le système testé doit réagir à chacun.", + "description": "Un générateur gratuit et open source de fichiers de test pour la QA. Il produit de vrais fichiers dans 31 formats, à la taille exacte, et écrit un manifeste qui dit comment le système testé doit réagir à chacun.", "url": "https:\/\/testingfilesgenerator.donislawdev.com/", "applicationCategory": "DeveloperApplication", "applicationSubCategory": "Software Testing", @@ -157,7 +157,7 @@

          Générez de vrais fichiers de test à la taille exacte

          - PDF, PNG, DOCX, ZIP - 30 formats au total, et chacun est un + PDF, PNG, DOCX, ZIP - 31 formats au total, et chacun est un vrai fichier qui s'ouvre dans le logiciel qui lui correspond, à la taille exacte que vous avez demandée. Chaque exécution note aussi ce que votre application doit faire de chaque fichier. Ligne de commande et fenêtre de bureau, gratuit et open source, entièrement sur @@ -180,7 +180,7 @@

          Générez de vrais fichiers de test à la taille exacte

          • - 30 + 31

            vrais formats, chacun s'ouvrant dans le logiciel qui lui correspond

          • @@ -345,7 +345,7 @@

            Conçu pour une suite qui tourne sans surveillance

            Demandez 10485761 octets et obtenez exactement cela. Une taille qu'un format ne peut pas atteindre est une erreur avec une raison, jamais un fichier de mauvaise taille.

          • -

            30 vrais formats

            +

            31 vrais formats

            Pas des zéros de remplissage avec une extension. Un PNG généré s'ouvre dans une visionneuse d'images, un DOCX s'ouvre dans Word, un ZIP se décompresse. Chacun est vérifié avec des lecteurs indépendants avant d'être livré.

          • diff --git a/web/public/fr/prereglages/empty-and-minimal/index.html b/web/public/fr/prereglages/empty-and-minimal/index.html index 5dc8df76..74f440aa 100644 --- a/web/public/fr/prereglages/empty-and-minimal/index.html +++ b/web/public/fr/prereglages/empty-and-minimal/index.html @@ -5,7 +5,7 @@ Fichiers de test valides minimaux et vides, dans chaque format - + @@ -34,7 +34,7 @@ - + @@ -63,7 +63,7 @@ - + @@ -179,10 +179,10 @@

            Que contient le jeu ?

            - - - - + + + +
            Fichiers32
            Cibles dans sa recette32
            Taille totale40 431 B
            Formatsavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
            Fichiers33
            Cibles dans sa recette33
            Taille totale40 496 B
            Formatsavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, rtf, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
            @@ -193,7 +193,7 @@

            Que contient le jeu ?

            AttenduSignificationFichiers - acceptVotre système doit accepter le fichier.30 + acceptVotre système doit accepter le fichier.31 unspecifiedCela dépend des règles de votre système. Vous décidez, puis vous vérifiez que ce qui se passe est ce que vous aviez voulu.2 diff --git a/web/public/hi/corrupt-test-files/index.html b/web/public/hi/corrupt-test-files/index.html index 6b607e03..7b3f32f5 100644 --- a/web/public/hi/corrupt-test-files/index.html +++ b/web/public/hi/corrupt-test-files/index.html @@ -200,7 +200,7 @@

            खराब फ़ाइल का आकार वही रहता ह tfg generate --format pdf --size 1mb --count 5 --damage zero-head:bytes=16 --out ./broken

            सेटिंग कोलन के बाद लिखी जाती है। विकल्प दोहराया जा सकता है, और बिगाड़ आपके लिखे क्रम में लागू होते - हैं। यह सभी 30 फ़ॉर्मैट के साथ चलता है। + हैं। यह सभी 31 फ़ॉर्मैट के साथ चलता है।

            diff --git a/web/public/hi/faq/index.html b/web/public/hi/faq/index.html index a5b24e01..65008b9d 100644 --- a/web/public/hi/faq/index.html +++ b/web/public/hi/faq/index.html @@ -205,7 +205,7 @@

            अक्सर पूछे जाने वाले सवाल

            आगे कौन से फ़ॉर्मैट आ रहे हैं?

            -

            7z और mp3। आज 30 फ़ॉर्मैट शुरू से अंत तक काम करते हैं।

            +

            7z और mp3। आज 31 फ़ॉर्मैट शुरू से अंत तक काम करते हैं।

            @@ -276,7 +276,7 @@

            अक्सर पूछे जाने वाले सवाल

            { "@type": "Question", "name": "आगे कौन से फ़ॉर्मैट आ रहे हैं?", - "acceptedAnswer": { "@type": "Answer", "text": "7z और mp3। आज 30 फ़ॉर्मैट शुरू से अंत तक काम करते हैं।" } + "acceptedAnswer": { "@type": "Answer", "text": "7z और mp3। आज 31 फ़ॉर्मैट शुरू से अंत तक काम करते हैं।" } }, { "@type": "Question", diff --git a/web/public/hi/formats/index.html b/web/public/hi/formats/index.html index eeed2ca9..b847911e 100644 --- a/web/public/hi/formats/index.html +++ b/web/public/hi/formats/index.html @@ -4,8 +4,8 @@ -30 समर्थित फ़ाइल फ़ॉर्मैट - PDF, DOCX, PNG, ZIP और अन्य - +31 समर्थित फ़ाइल फ़ॉर्मैट - PDF, DOCX, PNG, ZIP और अन्य + @@ -33,8 +33,8 @@ - - + + @@ -62,8 +62,8 @@ - - + + @@ -144,7 +144,7 @@
            -

            30 फ़ाइल फ़ॉर्मैट, हर एक सटीक आकार में बनाया गया

            +

            31 फ़ाइल फ़ॉर्मैट, हर एक सटीक आकार में बनाया गया

            इनमें से हर एक उस फ़ॉर्मैट की असली फ़ाइल है। वह अपने सॉफ़्टवेयर में खुलती है और उसमें ठीक उतने बाइट हैं जितने आपने माँगे। इनमें से कोई भी एक्सटेंशन चिपकाए गए भराव के शून्य नहीं @@ -308,6 +308,14 @@

            30 फ़ाइल फ़ॉर्मैट, हर एक सटीक आ full libreoffice + + rtf + Rich Text Format + .rtf + 65 + full + pandoc-rtf + svg Scalable Vector Graphics @@ -928,6 +936,26 @@

            हर फ़ॉर्मैट की स्वीकार की जा slides 1 - 500 स्लाइड + + rtf + characters + ascii, international + + + + text_encoding + both, codepage, literal, unicode + + + + elements + basic, every + + + + nesting + 0 - 10000000 + svg width diff --git a/web/public/hi/index.html b/web/public/hi/index.html index 645c0bb1..24df521d 100644 --- a/web/public/hi/index.html +++ b/web/public/hi/index.html @@ -4,7 +4,7 @@ -QA के लिए टेस्ट फ़ाइल जनरेटर - सटीक आकार, 30 असली फ़ॉर्मैट +QA के लिए टेस्ट फ़ाइल जनरेटर - सटीक आकार, 31 असली फ़ॉर्मैट @@ -33,7 +33,7 @@ - + @@ -62,7 +62,7 @@ - + @@ -76,7 +76,7 @@ "@type": "SoftwareApplication", "name": "Testing Files Generator", "alternateName": "tfg", - "description": "QA के लिए मुफ़्त और ओपन सोर्स टेस्ट फ़ाइल जनरेटर। यह 30 फ़ॉर्मैट में सटीक आकार की असली फ़ाइलें बनाता है और एक मैनिफ़ेस्ट लिखता है जो बताता है कि जाँचे जा रहे सिस्टम को हर फ़ाइल पर क्या प्रतिक्रिया देनी चाहिए।", + "description": "QA के लिए मुफ़्त और ओपन सोर्स टेस्ट फ़ाइल जनरेटर। यह 31 फ़ॉर्मैट में सटीक आकार की असली फ़ाइलें बनाता है और एक मैनिफ़ेस्ट लिखता है जो बताता है कि जाँचे जा रहे सिस्टम को हर फ़ाइल पर क्या प्रतिक्रिया देनी चाहिए।", "url": "https:\/\/testingfilesgenerator.donislawdev.com/", "applicationCategory": "DeveloperApplication", "applicationSubCategory": "Software Testing", @@ -157,7 +157,7 @@

            सटीक आकार की असली टेस्ट फ़ाइलें बनाएँ

            - PDF, PNG, DOCX, ZIP - कुल 30 फ़ॉर्मैट, और हर एक असली फ़ाइल है + PDF, PNG, DOCX, ZIP - कुल 31 फ़ॉर्मैट, और हर एक असली फ़ाइल है जो अपने सॉफ़्टवेयर में खुलती है, ठीक उसी आकार में जो आपने माँगा। हर रन यह भी लिखता है कि आपके एप्लिकेशन को हर फ़ाइल के साथ क्या करना चाहिए। कमांड लाइन और डेस्कटॉप विंडो, मुफ़्त और ओपन सोर्स, पूरी तरह आपकी मशीन पर चलता है। @@ -179,7 +179,7 @@

            सटीक आकार की असली टेस्ट फ़ाइ
            • - 30 + 31

              असली फ़ॉर्मैट, हर एक अपने सॉफ़्टवेयर में खुलता है

            • @@ -341,7 +341,7 @@

              बिना निगरानी के चलने वाले सू

              10485761 बाइट माँगें और ठीक वही पाएँ। जिस आकार तक कोई फ़ॉर्मैट नहीं पहुँच सकता, वह कारण सहित त्रुटि है, गलत आकार की फ़ाइल कभी नहीं।

            • -

              30 असली फ़ॉर्मैट

              +

              31 असली फ़ॉर्मैट

              एक्सटेंशन वाले भराव के शून्य नहीं। बनाई गई PNG इमेज व्यूअर में खुलती है, DOCX Word में खुलता है, ZIP खुल जाता है। हर एक को भेजने से पहले स्वतंत्र रीडरों से जाँचा जाता है।

            • diff --git a/web/public/hi/presets/empty-and-minimal/index.html b/web/public/hi/presets/empty-and-minimal/index.html index 8ca4679e..10531dd8 100644 --- a/web/public/hi/presets/empty-and-minimal/index.html +++ b/web/public/hi/presets/empty-and-minimal/index.html @@ -5,7 +5,7 @@ हर फ़ॉर्मैट की सबसे छोटी वैध और खाली टेस्ट फ़ाइलें - + @@ -34,7 +34,7 @@ - + @@ -63,7 +63,7 @@ - + @@ -178,10 +178,10 @@

              सेट में क्या है?

              - - - - + + + +
              फ़ाइलें32
              इसकी रेसिपी में टार्गेट32
              कुल आकार40 431 B
              फ़ॉर्मैटavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
              फ़ाइलें33
              इसकी रेसिपी में टार्गेट33
              कुल आकार40 496 B
              फ़ॉर्मैटavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, rtf, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
              @@ -192,7 +192,7 @@

              सेट में क्या है?

              अपेक्षितअर्थफ़ाइलें - acceptआपके सिस्टम को फ़ाइल मंज़ूर करनी चाहिए।30 + acceptआपके सिस्टम को फ़ाइल मंज़ूर करनी चाहिए।31 unspecifiedयह आपके सिस्टम के नियमों पर निर्भर है। आप तय करें, फिर जाँचें कि जो होता है वही है जो आप चाहते थे।2 diff --git a/web/public/id/faq/index.html b/web/public/id/faq/index.html index 510d8da9..504f979b 100644 --- a/web/public/id/faq/index.html +++ b/web/public/id/faq/index.html @@ -206,7 +206,7 @@

              Pertanyaan yang sering diajukan

              Format apa yang akan hadir berikutnya?

              -

              7z dan mp3. Saat ini 30 format bekerja dari ujung ke ujung.

              +

              7z dan mp3. Saat ini 31 format bekerja dari ujung ke ujung.

              @@ -277,7 +277,7 @@

              Pertanyaan yang sering diajukan

              { "@type": "Question", "name": "Format apa yang akan hadir berikutnya?", - "acceptedAnswer": { "@type": "Answer", "text": "7z dan mp3. Saat ini 30 format bekerja dari ujung ke ujung." } + "acceptedAnswer": { "@type": "Answer", "text": "7z dan mp3. Saat ini 31 format bekerja dari ujung ke ujung." } }, { "@type": "Question", diff --git a/web/public/id/file-uji-rusak/index.html b/web/public/id/file-uji-rusak/index.html index b0965d06..6dc37fc9 100644 --- a/web/public/id/file-uji-rusak/index.html +++ b/web/public/id/file-uji-rusak/index.html @@ -201,7 +201,7 @@

              File yang rusak tetap berukuran seperti yang Anda minta

              tfg generate --format pdf --size 1mb --count 5 --damage zero-head:bytes=16 --out ./broken

              Pengaturan ditulis setelah titik dua. Opsi ini bisa diulang, dan kerusakan diterapkan menurut urutan - yang Anda tulis. Berlaku untuk semua 30 format. + yang Anda tulis. Berlaku untuk semua 31 format.

              diff --git a/web/public/id/format/index.html b/web/public/id/format/index.html index 59f55747..bbd9ea0a 100644 --- a/web/public/id/format/index.html +++ b/web/public/id/format/index.html @@ -4,8 +4,8 @@ -30 Format File yang Didukung - PDF, DOCX, PNG, ZIP, dan Lainnya - +31 Format File yang Didukung - PDF, DOCX, PNG, ZIP, dan Lainnya + @@ -33,8 +33,8 @@ - - + + @@ -62,8 +62,8 @@ - - + + @@ -144,7 +144,7 @@
              -

              30 format file, masing-masing dibuat dengan ukuran tepat

              +

              31 format file, masing-masing dibuat dengan ukuran tepat

              Masing-masing adalah file asli dari format itu. File terbuka di aplikasi yang memilikinya dan persis berjumlah byte yang Anda minta. Tidak ada yang berupa nol pengisi dengan @@ -308,6 +308,14 @@

              30 format file, masing-masing dibuat dengan ukuran tepat

              full libreoffice + + rtf + Rich Text Format + .rtf + 65 + full + pandoc-rtf + svg Scalable Vector Graphics @@ -928,6 +936,26 @@

              Pengaturan yang diterima setiap format

              slides 1 - 500 slide + + rtf + characters + ascii, international + + + + text_encoding + both, codepage, literal, unicode + + + + elements + basic, every + + + + nesting + 0 - 10000000 + svg width diff --git a/web/public/id/index.html b/web/public/id/index.html index 49523b2a..abbd2efe 100644 --- a/web/public/id/index.html +++ b/web/public/id/index.html @@ -4,7 +4,7 @@ -Generator File Uji untuk QA - Ukuran Tepat, 30 Format Asli +Generator File Uji untuk QA - Ukuran Tepat, 31 Format Asli @@ -33,7 +33,7 @@ - + @@ -62,7 +62,7 @@ - + @@ -76,7 +76,7 @@ "@type": "SoftwareApplication", "name": "Testing Files Generator", "alternateName": "tfg", - "description": "Generator file uji untuk QA yang gratis dan open source. Alat ini membuat file asli dalam 30 format dengan ukuran tepat dan menulis manifes yang menyatakan bagaimana sistem yang diuji harus bereaksi terhadap tiap file.", + "description": "Generator file uji untuk QA yang gratis dan open source. Alat ini membuat file asli dalam 31 format dengan ukuran tepat dan menulis manifes yang menyatakan bagaimana sistem yang diuji harus bereaksi terhadap tiap file.", "url": "https:\/\/testingfilesgenerator.donislawdev.com/", "applicationCategory": "DeveloperApplication", "applicationSubCategory": "Software Testing", @@ -157,7 +157,7 @@

              Buat file uji asli dengan ukuran tepat

              - PDF, PNG, DOCX, ZIP - 30 format seluruhnya, dan setiap file + PDF, PNG, DOCX, ZIP - 31 format seluruhnya, dan setiap file adalah file asli yang terbuka di aplikasi yang memilikinya, dengan ukuran persis seperti yang Anda minta. Setiap run juga mencatat apa yang harus dilakukan aplikasi Anda terhadap tiap file. Baris perintah dan jendela desktop, gratis dan open source, bekerja @@ -180,7 +180,7 @@

              Buat file uji asli dengan ukuran tepat

              • - 30 + 31

                format asli, masing-masing terbuka di aplikasi yang memilikinya

              • @@ -344,7 +344,7 @@

                Dibuat untuk suite yang berjalan tanpa pengawasan

                Minta 10485761 byte dan dapatkan persis itu. Ukuran yang tidak dapat dicapai format adalah galat dengan alasan, tidak pernah file berukuran salah.

              • -

                30 format asli

                +

                31 format asli

                Bukan nol pengisi dengan ekstensi. PNG yang dihasilkan terbuka di penampil gambar, DOCX terbuka di Word, ZIP bisa diekstrak. Masing-masing diperiksa dengan pembaca independen sebelum dirilis.

              • diff --git a/web/public/id/preset/empty-and-minimal/index.html b/web/public/id/preset/empty-and-minimal/index.html index 3044cf2b..82bb5b57 100644 --- a/web/public/id/preset/empty-and-minimal/index.html +++ b/web/public/id/preset/empty-and-minimal/index.html @@ -5,7 +5,7 @@ File Uji Valid Terkecil dan Kosong di Setiap Format - + @@ -34,7 +34,7 @@ - + @@ -63,7 +63,7 @@ - + @@ -179,10 +179,10 @@

                Apa isi set?

                - - - - + + + +
                File32
                Target dalam resepnya32
                Ukuran total40 431 B
                Formatavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                File33
                Target dalam resepnya33
                Ukuran total40 496 B
                Formatavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, rtf, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                @@ -193,7 +193,7 @@

                Apa isi set?

                DiharapkanArtiFile - acceptSistem Anda harus menerima file ini.30 + acceptSistem Anda harus menerima file ini.31 unspecifiedTergantung pada aturan sistem Anda. Anda yang memutuskan, lalu memeriksa apakah yang terjadi sesuai maksud Anda.2 diff --git a/web/public/index.html b/web/public/index.html index edca72a4..435ae95a 100644 --- a/web/public/index.html +++ b/web/public/index.html @@ -4,7 +4,7 @@ -Test File Generator for QA - Exact Size, 30 Real Formats +Test File Generator for QA - Exact Size, 31 Real Formats @@ -33,7 +33,7 @@ - + @@ -62,7 +62,7 @@ - + @@ -76,7 +76,7 @@ "@type": "SoftwareApplication", "name": "Testing Files Generator", "alternateName": "tfg", - "description": "A free and open source generator of test files for QA. It produces real files of 30 formats at any exact size and writes a manifest saying how the system under test should react to each one.", + "description": "A free and open source generator of test files for QA. It produces real files of 31 formats at any exact size and writes a manifest saying how the system under test should react to each one.", "url": "https:\/\/testingfilesgenerator.donislawdev.com/", "applicationCategory": "DeveloperApplication", "applicationSubCategory": "Software Testing", @@ -157,7 +157,7 @@

                Generate real test files at any exact size

                - PDF, PNG, DOCX, ZIP - 30 formats in all, and every one is a + PDF, PNG, DOCX, ZIP - 31 formats in all, and every one is a real file that opens in the software that owns it, at exactly the size you asked for. Each run also writes down what your application is supposed to do with each file. Command line and desktop window, free and open source, working entirely on your machine. @@ -179,7 +179,7 @@

                Generate real test files at any exact size

                • - 30 + 31

                  real formats, each one opening in the software that owns it

                • @@ -342,7 +342,7 @@

                  Built for a suite that runs unattended

                  Ask for 10485761 bytes and get exactly that. A size a format cannot reach is an error with a reason, never a file of the wrong size.

                • -

                  30 real formats

                  +

                  31 real formats

                  Not padded zeros with an extension. A generated PNG opens in an image viewer, a DOCX opens in Word, a ZIP extracts. Each one is checked against independent readers before it ships.

                • diff --git a/web/public/it/domande-frequenti/index.html b/web/public/it/domande-frequenti/index.html index b9ef6621..b5d02855 100644 --- a/web/public/it/domande-frequenti/index.html +++ b/web/public/it/domande-frequenti/index.html @@ -206,7 +206,7 @@

                  Domande frequenti

                  Quali formati arrivano dopo?

                  -

                  7z e mp3. Oggi 30 formati funzionano da un capo all'altro.

                  +

                  7z e mp3. Oggi 31 formati funzionano da un capo all'altro.

                  @@ -277,7 +277,7 @@

                  Domande frequenti

                  { "@type": "Question", "name": "Quali formati arrivano dopo?", - "acceptedAnswer": { "@type": "Answer", "text": "7z e mp3. Oggi 30 formati funzionano da un capo all\u0027altro." } + "acceptedAnswer": { "@type": "Answer", "text": "7z e mp3. Oggi 31 formati funzionano da un capo all\u0027altro." } }, { "@type": "Question", diff --git a/web/public/it/file-di-test-corrotti/index.html b/web/public/it/file-di-test-corrotti/index.html index 502f4378..e73abd25 100644 --- a/web/public/it/file-di-test-corrotti/index.html +++ b/web/public/it/file-di-test-corrotti/index.html @@ -201,7 +201,7 @@

                  Un file danneggiato ha ancora la dimensione richiesta

                  tfg generate --format pdf --size 1mb --count 5 --damage zero-head:bytes=16 --out ./broken

                  Le impostazioni vanno dopo i due punti. L'opzione si può ripetere, e i danni vengono applicati - nell'ordine in cui li scrivi. Funziona con ognuno dei 30 formati. + nell'ordine in cui li scrivi. Funziona con ognuno dei 31 formati.

                  diff --git a/web/public/it/formati/index.html b/web/public/it/formati/index.html index e644763e..a038fbde 100644 --- a/web/public/it/formati/index.html +++ b/web/public/it/formati/index.html @@ -4,8 +4,8 @@ -30 formati di file supportati - PDF, DOCX, PNG, ZIP e altri - +31 formati di file supportati - PDF, DOCX, PNG, ZIP e altri + @@ -33,8 +33,8 @@ - - + + @@ -62,8 +62,8 @@ - - + + @@ -144,7 +144,7 @@
                  -

                  30 formati di file, ognuno generato a una dimensione esatta

                  +

                  31 formati di file, ognuno generato a una dimensione esatta

                  Ognuno è un file reale di quel formato. Si apre nel programma che gli appartiene ed è esattamente il numero di byte che hai chiesto. Nessuno è riempimento di zeri con un'estensione @@ -308,6 +308,14 @@

                  30 formati di file, ognuno generato a una dimensione esatta

                  full libreoffice + + rtf + Rich Text Format + .rtf + 65 + full + pandoc-rtf + svg Scalable Vector Graphics @@ -930,6 +938,26 @@

                  Impostazioni che ogni formato accetta

                  slides 1 - 500 diapositive + + rtf + characters + ascii, international + + + + text_encoding + both, codepage, literal, unicode + + + + elements + basic, every + + + + nesting + 0 - 10000000 + svg width diff --git a/web/public/it/index.html b/web/public/it/index.html index 372b0de2..7cd59cfe 100644 --- a/web/public/it/index.html +++ b/web/public/it/index.html @@ -4,7 +4,7 @@ -Generatore di file di test - dimensione esatta, 30 formati reali +Generatore di file di test - dimensione esatta, 31 formati reali @@ -33,7 +33,7 @@ - + @@ -62,7 +62,7 @@ - + @@ -76,7 +76,7 @@ "@type": "SoftwareApplication", "name": "Testing Files Generator", "alternateName": "tfg", - "description": "Un generatore gratuito e open source di file di test per la QA. Produce file reali in 30 formati della dimensione esatta e scrive un manifest che dice come il sistema sotto test deve reagire a ciascuno.", + "description": "Un generatore gratuito e open source di file di test per la QA. Produce file reali in 31 formati della dimensione esatta e scrive un manifest che dice come il sistema sotto test deve reagire a ciascuno.", "url": "https:\/\/testingfilesgenerator.donislawdev.com/", "applicationCategory": "DeveloperApplication", "applicationSubCategory": "Software Testing", @@ -157,7 +157,7 @@

                  Genera file di test reali della dimensione esatta

                  - PDF, PNG, DOCX, ZIP - 30 formati in tutto, e ognuno è un file + PDF, PNG, DOCX, ZIP - 31 formati in tutto, e ognuno è un file reale che si apre nel programma che gli appartiene, di esattamente la dimensione che hai chiesto. Ogni esecuzione annota anche cosa la tua applicazione deve fare con ogni file. Riga di comando e finestra desktop, gratuito e open source, interamente sulla tua macchina. @@ -179,7 +179,7 @@

                  Genera file di test reali della dimensione esatta

                  • - 30 + 31

                    formati reali, ognuno si apre nel programma che gli appartiene

                  • @@ -344,7 +344,7 @@

                    Costruito per una suite che gira senza supervisione

                    Chiedi 10485761 byte e ottieni esattamente quelli. Una dimensione che un formato non può raggiungere è un errore con un motivo, mai un file della dimensione sbagliata.

                  • -

                    30 formati reali

                    +

                    31 formati reali

                    Non zeri di riempimento con un'estensione. Un PNG generato si apre in un visualizzatore di immagini, un DOCX si apre in Word, uno ZIP si estrae. Ognuno è verificato con lettori indipendenti prima del rilascio.

                  • diff --git a/web/public/it/preset/empty-and-minimal/index.html b/web/public/it/preset/empty-and-minimal/index.html index 3eb08498..8ec01129 100644 --- a/web/public/it/preset/empty-and-minimal/index.html +++ b/web/public/it/preset/empty-and-minimal/index.html @@ -5,7 +5,7 @@ File di test validi minimi e vuoti in ogni formato - + @@ -34,7 +34,7 @@ - + @@ -63,7 +63,7 @@ - + @@ -179,10 +179,10 @@

                    Cosa c'è nel set?

                    - - - - + + + +
                    File32
                    Target nella sua ricetta32
                    Dimensione totale40 431 B
                    Formatiavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                    File33
                    Target nella sua ricetta33
                    Dimensione totale40 496 B
                    Formatiavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, rtf, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                    @@ -193,7 +193,7 @@

                    Cosa c'è nel set?

                    AttesoSignificatoFile - acceptIl tuo sistema deve accettare il file.30 + acceptIl tuo sistema deve accettare il file.31 unspecifiedDipende dalle regole del tuo sistema. Decidi tu, poi controlli che ciò che accade sia ciò che intendevi.2 diff --git a/web/public/ja/corrupt-test-files/index.html b/web/public/ja/corrupt-test-files/index.html index 0e5f81f6..1e9d0a8b 100644 --- a/web/public/ja/corrupt-test-files/index.html +++ b/web/public/ja/corrupt-test-files/index.html @@ -189,7 +189,7 @@

                    破損したファイルも、求めたサイズのままです

                    tfg generate --format png --size 2mb --damage zero-head --out ./out
                     tfg generate --format pdf --size 1mb --count 5 --damage zero-head:bytes=16 --out ./broken

                    - 設定はコロンの後ろに書きます。オプションは繰り返せて、破損は書いた順に適用されます。30種類すべての形式で使えます。 + 設定はコロンの後ろに書きます。オプションは繰り返せて、破損は書いた順に適用されます。31種類すべての形式で使えます。

                    diff --git a/web/public/ja/faq/index.html b/web/public/ja/faq/index.html index cbf4b6d7..b3af6917 100644 --- a/web/public/ja/faq/index.html +++ b/web/public/ja/faq/index.html @@ -204,7 +204,7 @@

                    よくある質問

                    次に対応する形式は何ですか。

                    -

                    7zとmp3です。現在、30種類の形式がエンドツーエンドで動作します。

                    +

                    7zとmp3です。現在、31種類の形式がエンドツーエンドで動作します。

                    @@ -275,7 +275,7 @@

                    よくある質問

                    { "@type": "Question", "name": "次に対応する形式は何ですか。", - "acceptedAnswer": { "@type": "Answer", "text": "7zとmp3です。現在、30種類の形式がエンドツーエンドで動作します。" } + "acceptedAnswer": { "@type": "Answer", "text": "7zとmp3です。現在、31種類の形式がエンドツーエンドで動作します。" } }, { "@type": "Question", diff --git a/web/public/ja/formats/index.html b/web/public/ja/formats/index.html index 62b4f67a..c646d94a 100644 --- a/web/public/ja/formats/index.html +++ b/web/public/ja/formats/index.html @@ -4,8 +4,8 @@ -対応する30種類のファイル形式 - PDF、DOCX、PNG、ZIPほか - +対応する31種類のファイル形式 - PDF、DOCX、PNG、ZIPほか + @@ -33,8 +33,8 @@ - - + + @@ -62,8 +62,8 @@ - - + + @@ -144,7 +144,7 @@
                    -

                    30種類のファイル形式、どれも正確なサイズで生成

                    +

                    31種類のファイル形式、どれも正確なサイズで生成

                    どれもその形式の本物のファイルです。対応するソフトウェアで開け、要求したバイト数とぴったり一致します。拡張子を貼り付けただけのゼロ埋めはひとつもありません。

                    @@ -306,6 +306,14 @@

                    30種類のファイル形式、どれも正確なサイズで生成

                    full libreoffice + + rtf + Rich Text Format + .rtf + 65 + full + pandoc-rtf + svg Scalable Vector Graphics @@ -920,6 +928,26 @@

                    形式ごとに受け付ける設定

                    slides 1 - 500 スライド + + rtf + characters + ascii, international + + + + text_encoding + both, codepage, literal, unicode + + + + elements + basic, every + + + + nesting + 0 - 10000000 + svg width diff --git a/web/public/ja/index.html b/web/public/ja/index.html index 140968ce..beee4e1b 100644 --- a/web/public/ja/index.html +++ b/web/public/ja/index.html @@ -4,7 +4,7 @@ -テストファイル生成ツール - 正確なサイズ、30種類の本物の形式 +テストファイル生成ツール - 正確なサイズ、31種類の本物の形式 @@ -33,7 +33,7 @@ - + @@ -62,7 +62,7 @@ - + @@ -76,7 +76,7 @@ "@type": "SoftwareApplication", "name": "Testing Files Generator", "alternateName": "tfg", - "description": "QA向けの無料オープンソースのテストファイル生成ツールです。30種類の形式で正確なサイズの本物のファイルを作り、テスト対象のシステムが各ファイルにどう反応すべきかを示すマニフェストを書き出します。", + "description": "QA向けの無料オープンソースのテストファイル生成ツールです。31種類の形式で正確なサイズの本物のファイルを作り、テスト対象のシステムが各ファイルにどう反応すべきかを示すマニフェストを書き出します。", "url": "https:\/\/testingfilesgenerator.donislawdev.com/", "applicationCategory": "DeveloperApplication", "applicationSubCategory": "Software Testing", @@ -157,7 +157,7 @@

                    正確なサイズの本物のテストファイルを生成

                    - PDF、PNG、DOCX、ZIPなど、全30種類の形式に対応し、どれも対応するソフトウェアで開ける本物のファイルで、サイズは要求したとおりちょうどです。各実行では、アプリが各ファイルをどう扱うべきかも書き出します。コマンドラインとデスクトップウィンドウの両方に対応し、無料のオープンソースで、すべてあなたのマシン上で動きます。 + PDF、PNG、DOCX、ZIPなど、全31種類の形式に対応し、どれも対応するソフトウェアで開ける本物のファイルで、サイズは要求したとおりちょうどです。各実行では、アプリが各ファイルをどう扱うべきかも書き出します。コマンドラインとデスクトップウィンドウの両方に対応し、無料のオープンソースで、すべてあなたのマシン上で動きます。

                    @@ -176,7 +176,7 @@

                    正確なサイズの本物のテストファイルを生成

                    • - 30 + 31

                      種類の本物の形式、どれも対応するソフトウェアで開けます

                    • @@ -328,7 +328,7 @@

                      無人で動くテストスイートのために作られています

                      10485761バイトを要求すれば、ちょうどその大きさになります。形式が到達できないサイズは理由付きのエラーになり、サイズの違うファイルが作られることはありません。

                    • -

                      30種類の本物の形式

                      +

                      31種類の本物の形式

                      拡張子を付けただけのゼロ埋めではありません。生成したPNGは画像ビューアーで開け、DOCXはWordで開け、ZIPは展開できます。どれも出荷前に独立したリーダーで検証されます。

                    • diff --git a/web/public/ja/presets/empty-and-minimal/index.html b/web/public/ja/presets/empty-and-minimal/index.html index 355f27c0..ba5f5c08 100644 --- a/web/public/ja/presets/empty-and-minimal/index.html +++ b/web/public/ja/presets/empty-and-minimal/index.html @@ -5,7 +5,7 @@ 全形式の最小の有効ファイルと空ファイル - + @@ -34,7 +34,7 @@ - + @@ -63,7 +63,7 @@ - + @@ -176,10 +176,10 @@

                      セットには何が入っていますか。

                      - - - - + + + +
                      ファイル数32
                      レシピ内のターゲット数32
                      合計サイズ40 431 B
                      形式avif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                      ファイル数33
                      レシピ内のターゲット数33
                      合計サイズ40 496 B
                      形式avif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, rtf, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                      @@ -190,7 +190,7 @@

                      セットには何が入っていますか。

                      期待意味ファイル数 - acceptシステムはこのファイルを受け入れるべきです。30 + acceptシステムはこのファイルを受け入れるべきです。31 unspecifiedシステムのルール次第です。あなたが決め、実際に起きることが意図どおりかを確認してください。2 diff --git a/web/public/ko/corrupt-test-files/index.html b/web/public/ko/corrupt-test-files/index.html index 34e8f9d5..33f3015c 100644 --- a/web/public/ko/corrupt-test-files/index.html +++ b/web/public/ko/corrupt-test-files/index.html @@ -194,7 +194,7 @@

                      손상된 파일도 요청한 크기를 유지합니다

                      tfg generate --format png --size 2mb --damage zero-head --out ./out
                       tfg generate --format pdf --size 1mb --count 5 --damage zero-head:bytes=16 --out ./broken

                      - 설정은 콜론 뒤에 씁니다. 옵션은 반복할 수 있고, 손상은 쓴 순서대로 적용됩니다. 30개 형식 모두에서 동작합니다. + 설정은 콜론 뒤에 씁니다. 옵션은 반복할 수 있고, 손상은 쓴 순서대로 적용됩니다. 31개 형식 모두에서 동작합니다.

                      diff --git a/web/public/ko/faq/index.html b/web/public/ko/faq/index.html index 06508ba1..bc6b0d8d 100644 --- a/web/public/ko/faq/index.html +++ b/web/public/ko/faq/index.html @@ -205,7 +205,7 @@

                      자주 묻는 질문

                      다음에는 어떤 형식이 추가되나요?

                      -

                      7z와 mp3입니다. 현재 30가지 형식이 처음부터 끝까지 동작합니다.

                      +

                      7z와 mp3입니다. 현재 31가지 형식이 처음부터 끝까지 동작합니다.

                      @@ -276,7 +276,7 @@

                      자주 묻는 질문

                      { "@type": "Question", "name": "다음에는 어떤 형식이 추가되나요?", - "acceptedAnswer": { "@type": "Answer", "text": "7z와 mp3입니다. 현재 30가지 형식이 처음부터 끝까지 동작합니다." } + "acceptedAnswer": { "@type": "Answer", "text": "7z와 mp3입니다. 현재 31가지 형식이 처음부터 끝까지 동작합니다." } }, { "@type": "Question", diff --git a/web/public/ko/formats/index.html b/web/public/ko/formats/index.html index ac84c169..8f2d5d28 100644 --- a/web/public/ko/formats/index.html +++ b/web/public/ko/formats/index.html @@ -4,8 +4,8 @@ -지원하는 파일 형식 30종 - PDF, DOCX, PNG, ZIP 등 - +지원하는 파일 형식 31종 - PDF, DOCX, PNG, ZIP 등 + @@ -33,8 +33,8 @@ - - + + @@ -62,8 +62,8 @@ - - + + @@ -144,7 +144,7 @@
                      -

                      파일 형식 30가지, 모두 정확한 크기로 생성됩니다

                      +

                      파일 형식 31가지, 모두 정확한 크기로 생성됩니다

                      이들은 모두 해당 형식의 실제 파일입니다. 해당 소프트웨어에서 열리며 요청한 바이트 수와 정확히 같습니다. 확장자만 붙인 채운 0은 하나도 없습니다.

                      @@ -306,6 +306,14 @@

                      파일 형식 30가지, 모두 정확한 크기로 생성됩니다

                      full libreoffice + + rtf + Rich Text Format + .rtf + 65 + full + pandoc-rtf + svg Scalable Vector Graphics @@ -921,6 +929,26 @@

                      각 형식이 받는 설정

                      slides 1 - 500 슬라이드 + + rtf + characters + ascii, international + + + + text_encoding + both, codepage, literal, unicode + + + + elements + basic, every + + + + nesting + 0 - 10000000 + svg width diff --git a/web/public/ko/index.html b/web/public/ko/index.html index e4391c7d..f1dc0e19 100644 --- a/web/public/ko/index.html +++ b/web/public/ko/index.html @@ -4,7 +4,7 @@ -테스트 파일 생성기 - 정확한 크기, 실제 형식 30종 +테스트 파일 생성기 - 정확한 크기, 실제 형식 31종 @@ -33,7 +33,7 @@ - + @@ -62,7 +62,7 @@ - + @@ -76,7 +76,7 @@ "@type": "SoftwareApplication", "name": "Testing Files Generator", "alternateName": "tfg", - "description": "QA를 위한 무료 오픈 소스 테스트 파일 생성기입니다. 30가지 형식의 정확한 크기의 실제 파일을 만들고, 테스트 대상 시스템이 각 파일에 어떻게 반응해야 하는지 알려 주는 매니페스트를 작성합니다.", + "description": "QA를 위한 무료 오픈 소스 테스트 파일 생성기입니다. 31가지 형식의 정확한 크기의 실제 파일을 만들고, 테스트 대상 시스템이 각 파일에 어떻게 반응해야 하는지 알려 주는 매니페스트를 작성합니다.", "url": "https:\/\/testingfilesgenerator.donislawdev.com/", "applicationCategory": "DeveloperApplication", "applicationSubCategory": "Software Testing", @@ -157,7 +157,7 @@

                      정확한 크기의 실제 테스트 파일을 만드세요

                      - PDF, PNG, DOCX, ZIP 등 모두 30가지 형식이며, 모두 해당 소프트웨어에서 열리는 실제 파일로 + PDF, PNG, DOCX, ZIP 등 모두 31가지 형식이며, 모두 해당 소프트웨어에서 열리는 실제 파일로 요청한 크기와 정확히 같습니다. 매 실행마다 애플리케이션이 각 파일을 어떻게 처리해야 하는지도 함께 기록합니다. 명령줄과 데스크톱 창, 무료 오픈 소스이며, 모두 여러분의 컴퓨터에서 동작합니다.

                      @@ -178,7 +178,7 @@

                      정확한 크기의 실제 테스트 파일을 만드세요

                      • - 30 + 31

                        가지 실제 형식, 각각 해당 소프트웨어에서 열립니다

                      • @@ -335,7 +335,7 @@

                        무인으로 실행되는 테스트 묶음을 위해 만들었습니다

                        10485761바이트를 요청하면 정확히 그 크기가 나옵니다. 형식이 도달할 수 없는 크기는 이유가 붙은 오류가 되며, 크기가 틀린 파일이 되는 일은 없습니다.

                      • -

                        실제 형식 30가지

                        +

                        실제 형식 31가지

                        확장자만 붙인 채운 0이 아닙니다. 생성된 PNG는 이미지 뷰어에서 열리고, DOCX는 Word에서 열리며, ZIP은 풀립니다. 모든 형식은 출시 전에 독립적인 리더로 검증됩니다.

                      • diff --git a/web/public/ko/presets/empty-and-minimal/index.html b/web/public/ko/presets/empty-and-minimal/index.html index fe13520d..880791ae 100644 --- a/web/public/ko/presets/empty-and-minimal/index.html +++ b/web/public/ko/presets/empty-and-minimal/index.html @@ -5,7 +5,7 @@ 모든 형식의 가장 작은 유효 파일과 빈 파일 - + @@ -34,7 +34,7 @@ - + @@ -63,7 +63,7 @@ - + @@ -177,10 +177,10 @@

                        세트에는 무엇이 들어 있나요?

                        - - - - + + + +
                        파일 수32
                        레시피의 타깃 수32
                        총 크기40 431 B
                        형식avif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                        파일 수33
                        레시피의 타깃 수33
                        총 크기40 496 B
                        형식avif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, rtf, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                        @@ -191,7 +191,7 @@

                        세트에는 무엇이 들어 있나요?

                        기대값의미파일 수 - accept시스템은 이 파일을 받아야 합니다.30 + accept시스템은 이 파일을 받아야 합니다.31 unspecified시스템의 규칙에 따라 다릅니다. 직접 결정한 뒤 실제 일어나는 일이 의도한 것인지 확인하세요.2 diff --git a/web/public/nl/beschadigde-testbestanden/index.html b/web/public/nl/beschadigde-testbestanden/index.html index a3bf8c7c..0b1cb1f2 100644 --- a/web/public/nl/beschadigde-testbestanden/index.html +++ b/web/public/nl/beschadigde-testbestanden/index.html @@ -203,7 +203,7 @@

                        Een beschadigd bestand heeft nog steeds de grootte die je vroeg

                        Instellingen komen achter een dubbele punt. De optie mag herhaald worden, en de beschadigingen worden toegepast in de volgorde waarin je ze schrijft. Het werkt met elk van de - 30 formaten. + 31 formaten.

                        diff --git a/web/public/nl/formaten/index.html b/web/public/nl/formaten/index.html index 3e98552d..a5a894d3 100644 --- a/web/public/nl/formaten/index.html +++ b/web/public/nl/formaten/index.html @@ -4,8 +4,8 @@ -30 ondersteunde bestandsformaten - PDF, DOCX, PNG, ZIP en meer - +31 ondersteunde bestandsformaten - PDF, DOCX, PNG, ZIP en meer + @@ -33,8 +33,8 @@ - - + + @@ -62,8 +62,8 @@ - - + + @@ -144,7 +144,7 @@
                        -

                        30 bestandsformaten, elk gegenereerd in een exacte grootte

                        +

                        31 bestandsformaten, elk gegenereerd in een exacte grootte

                        Elk daarvan is een echt bestand van dat formaat. Het opent in het programma waartoe het behoort en is precies het aantal bytes dat je vroeg. Geen enkele is opgevulde nullen met een @@ -308,6 +308,14 @@

                        30 bestandsformaten, elk gegenereerd in een exacte grootte

                        full libreoffice + + rtf + Rich Text Format + .rtf + 65 + full + pandoc-rtf + svg Scalable Vector Graphics @@ -930,6 +938,26 @@

                        Instellingen die elk formaat accepteert

                        slides 1 - 500 dia's + + rtf + characters + ascii, international + + + + text_encoding + both, codepage, literal, unicode + + + + elements + basic, every + + + + nesting + 0 - 10000000 + svg width diff --git a/web/public/nl/index.html b/web/public/nl/index.html index e5749dd4..f81bbd38 100644 --- a/web/public/nl/index.html +++ b/web/public/nl/index.html @@ -4,7 +4,7 @@ -Testbestanden genereren - exacte grootte, 30 echte formaten +Testbestanden genereren - exacte grootte, 31 echte formaten @@ -33,7 +33,7 @@ - + @@ -62,7 +62,7 @@ - + @@ -76,7 +76,7 @@ "@type": "SoftwareApplication", "name": "Testing Files Generator", "alternateName": "tfg", - "description": "Een gratis open source generator van testbestanden voor QA. Hij maakt echte bestanden in 30 formaten in elke exacte grootte en schrijft een manifest dat zegt hoe het geteste systeem op elk bestand moet reageren.", + "description": "Een gratis open source generator van testbestanden voor QA. Hij maakt echte bestanden in 31 formaten in elke exacte grootte en schrijft een manifest dat zegt hoe het geteste systeem op elk bestand moet reageren.", "url": "https:\/\/testingfilesgenerator.donislawdev.com/", "applicationCategory": "DeveloperApplication", "applicationSubCategory": "Software Testing", @@ -157,7 +157,7 @@

                        Genereer echte testbestanden in elke exacte grootte

                        - PDF, PNG, DOCX, ZIP - 30 formaten in totaal, en elk is een + PDF, PNG, DOCX, ZIP - 31 formaten in totaal, en elk is een echt bestand dat opent in het programma waartoe het behoort, in precies de grootte die je vroeg. Elke run schrijft ook op wat je applicatie met elk bestand moet doen. Opdrachtregel en bureaubladvenster, gratis en open source, volledig op je eigen machine. @@ -179,7 +179,7 @@

                        Genereer echte testbestanden in elke exacte grootte

                        • - 30 + 31

                          echte formaten, elk opent in het programma waartoe het behoort

                        • @@ -342,7 +342,7 @@

                          Gebouwd voor een suite die onbeheerd draait

                          Vraag 10485761 bytes en krijg precies dat. Een grootte die een formaat niet kan halen is een fout met een reden, nooit een bestand van de verkeerde grootte.

                        • -

                          30 echte formaten

                          +

                          31 echte formaten

                          Geen opgevulde nullen met een extensie. Een gegenereerde PNG opent in een afbeeldingsviewer, een DOCX opent in Word, een ZIP pakt uit. Elk wordt vóór levering gecontroleerd met onafhankelijke lezers.

                        • diff --git a/web/public/nl/presets/empty-and-minimal/index.html b/web/public/nl/presets/empty-and-minimal/index.html index 8c16040c..0eac822c 100644 --- a/web/public/nl/presets/empty-and-minimal/index.html +++ b/web/public/nl/presets/empty-and-minimal/index.html @@ -5,7 +5,7 @@ Kleinste geldige en lege testbestanden in elk formaat - + @@ -34,7 +34,7 @@ - + @@ -63,7 +63,7 @@ - + @@ -179,10 +179,10 @@

                          Wat zit er in de set?

                          - - - - + + + +
                          Bestanden32
                          Targets in het recept32
                          Totale grootte40 431 B
                          Formatenavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                          Bestanden33
                          Targets in het recept33
                          Totale grootte40 496 B
                          Formatenavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, rtf, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                          @@ -193,7 +193,7 @@

                          Wat zit er in de set?

                          VerwachtBetekenisBestanden - acceptJe systeem moet het bestand aannemen.30 + acceptJe systeem moet het bestand aannemen.31 unspecifiedHet hangt af van de regels van je systeem. Jij beslist, en controleert daarna of wat er gebeurt is wat je bedoelde.2 diff --git a/web/public/nl/veelgestelde-vragen/index.html b/web/public/nl/veelgestelde-vragen/index.html index 08517d4d..8a69f4aa 100644 --- a/web/public/nl/veelgestelde-vragen/index.html +++ b/web/public/nl/veelgestelde-vragen/index.html @@ -206,7 +206,7 @@

                          Veelgestelde vragen

                          Welke formaten komen er nog?

                          -

                          7z en mp3. Vandaag werken 30 formaten van begin tot eind.

                          +

                          7z en mp3. Vandaag werken 31 formaten van begin tot eind.

                          @@ -277,7 +277,7 @@

                          Veelgestelde vragen

                          { "@type": "Question", "name": "Welke formaten komen er nog?", - "acceptedAnswer": { "@type": "Answer", "text": "7z en mp3. Vandaag werken 30 formaten van begin tot eind." } + "acceptedAnswer": { "@type": "Answer", "text": "7z en mp3. Vandaag werken 31 formaten van begin tot eind." } }, { "@type": "Question", diff --git a/web/public/pl/faq/index.html b/web/public/pl/faq/index.html index df4eba0e..281d3f5c 100644 --- a/web/public/pl/faq/index.html +++ b/web/public/pl/faq/index.html @@ -206,7 +206,7 @@

                          Najczęstsze pytania

                          Jakie formaty są następne w kolejce?

                          -

                          7z i mp3. Formatów działających dziś od początku do końca jest 30.

                          +

                          7z i mp3. Formatów działających dziś od początku do końca jest 31.

                          @@ -277,7 +277,7 @@

                          Najczęstsze pytania

                          { "@type": "Question", "name": "Jakie formaty są następne w kolejce?", - "acceptedAnswer": { "@type": "Answer", "text": "7z i mp3. Formatów działających dziś od początku do końca jest 30." } + "acceptedAnswer": { "@type": "Answer", "text": "7z i mp3. Formatów działających dziś od początku do końca jest 31." } }, { "@type": "Question", diff --git a/web/public/pl/formaty/index.html b/web/public/pl/formaty/index.html index 7778aa07..173b7e09 100644 --- a/web/public/pl/formaty/index.html +++ b/web/public/pl/formaty/index.html @@ -4,7 +4,7 @@ -30 formatów plików testowych - PDF, DOCX, PNG, ZIP +31 formatów plików testowych - PDF, DOCX, PNG, ZIP @@ -33,7 +33,7 @@ - + @@ -62,7 +62,7 @@ - + @@ -144,7 +144,7 @@
                          -

                          30 formatów plików, każdy generowany o dokładnym rozmiarze

                          +

                          31 formatów plików, każdy generowany o dokładnym rozmiarze

                          Każdy z nich to prawdziwy plik tego formatu. Otwiera się w programie, do którego należy, i ma dokładnie tyle bajtów, ile zamówiłeś. Żaden nie jest zerami z doklejonym rozszerzeniem. @@ -307,6 +307,14 @@

                          30 formatów plików, każdy generowany o dokładnym rozmiarze

                          full libreoffice + + rtf + Rich Text Format + .rtf + 65 + full + pandoc-rtf + svg Scalable Vector Graphics @@ -928,6 +936,26 @@

                          Ustawienia, które przyjmuje każdy format

                          slides 1 - 500 slajdów + + rtf + characters + ascii, international + + + + text_encoding + both, codepage, literal, unicode + + + + elements + basic, every + + + + nesting + 0 - 10000000 + svg width diff --git a/web/public/pl/index.html b/web/public/pl/index.html index 8ee9f496..f95538cf 100644 --- a/web/public/pl/index.html +++ b/web/public/pl/index.html @@ -4,7 +4,7 @@ -Generator plików testowych o zadanym rozmiarze - 30 formatów +Generator plików testowych o zadanym rozmiarze - 31 formatów @@ -33,7 +33,7 @@ - + @@ -62,7 +62,7 @@ - + @@ -76,7 +76,7 @@ "@type": "SoftwareApplication", "name": "Testing Files Generator", "alternateName": "tfg", - "description": "Darmowy generator plików testowych dla QA o otwartym kodzie. Tworzy prawdziwe pliki w 30 formatach o dokładnie zadanym rozmiarze i zapisuje manifest mówiący, jak testowany system ma na każdy z nich zareagować.", + "description": "Darmowy generator plików testowych dla QA o otwartym kodzie. Tworzy prawdziwe pliki w 31 formatach o dokładnie zadanym rozmiarze i zapisuje manifest mówiący, jak testowany system ma na każdy z nich zareagować.", "url": "https:\/\/testingfilesgenerator.donislawdev.com/", "applicationCategory": "DeveloperApplication", "applicationSubCategory": "Software Testing", @@ -157,7 +157,7 @@

                          Generuj pliki testowe o zadanym rozmiarze

                          - PDF, PNG, DOCX, ZIP - razem 30 formatów, a każdy to + PDF, PNG, DOCX, ZIP - razem 31 formatów, a każdy to prawdziwy plik, który otwiera się w programie, do którego należy, i ma dokładnie taki rozmiar, o jaki poprosisz. Każdy przebieg zapisuje też, co Twoja aplikacja ma z każdym plikiem zrobić. Wiersz poleceń i okno, darmowe i otwarte, działające wyłącznie na Twojej maszynie. @@ -179,7 +179,7 @@

                          Generuj pliki testowe o zadanym rozmiarze

                          • - 30 + 31

                            prawdziwych formatów, każdy otwiera się w programie, do którego należy

                          • @@ -342,7 +342,7 @@

                            Zbudowane pod zestaw, który chodzi bez nadzoru

                            Poproś o 10485761 bajtów i tyle dostaniesz. Rozmiar nieosiągalny dla formatu to błąd z powodem, nigdy plik o innym rozmiarze.

                          • -

                            30 prawdziwych formatów

                            +

                            31 prawdziwych formatów

                            Nie zera z doklejonym rozszerzeniem. Wygenerowany PNG otwiera się w przeglądarce obrazów, DOCX w Wordzie, a ZIP się rozpakowuje. Każdy format jest sprawdzany niezależnym czytnikiem, zanim trafi do wydania.

                          • diff --git a/web/public/pl/presety/empty-and-minimal/index.html b/web/public/pl/presety/empty-and-minimal/index.html index d1cd88c1..2dcec475 100644 --- a/web/public/pl/presety/empty-and-minimal/index.html +++ b/web/public/pl/presety/empty-and-minimal/index.html @@ -5,7 +5,7 @@ Najmniejsze poprawne i puste pliki w każdym formacie - + @@ -34,7 +34,7 @@ - + @@ -63,7 +63,7 @@ - + @@ -178,10 +178,10 @@

                            Co jest w zestawie?

                            - - - - + + + +
                            Pliki32
                            Cele w przepisie32
                            Łączny rozmiar40 431 B
                            Formatyavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                            Pliki33
                            Cele w przepisie33
                            Łączny rozmiar40 496 B
                            Formatyavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, rtf, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                            @@ -192,7 +192,7 @@

                            Co jest w zestawie?

                            OczekiwanieZnaczeniePliki - acceptSystem powinien przyjąć plik.30 + acceptSystem powinien przyjąć plik.31 unspecifiedZależy od reguł Twojego systemu. Ty decydujesz, a potem sprawdzasz, czy dzieje się to, co zamierzałeś.2 diff --git a/web/public/pl/uszkodzone-pliki-testowe/index.html b/web/public/pl/uszkodzone-pliki-testowe/index.html index 08162fa7..fe049bbf 100644 --- a/web/public/pl/uszkodzone-pliki-testowe/index.html +++ b/web/public/pl/uszkodzone-pliki-testowe/index.html @@ -202,7 +202,7 @@

                            Uszkodzony plik ma nadal rozmiar, o który prosiłeś

                            tfg generate --format pdf --size 1mb --count 5 --damage zero-head:bytes=16 --out ./broken

                            Ustawienia podaje się po dwukropku. Flagę można powtarzać, a uszkodzenia są stosowane w kolejności, - w jakiej je zapiszesz. Działa z każdym z 30 formatów. + w jakiej je zapiszesz. Działa z każdym z 31 formatów.

                            diff --git a/web/public/presets/empty-and-minimal/index.html b/web/public/presets/empty-and-minimal/index.html index 147bd8f2..f716d641 100644 --- a/web/public/presets/empty-and-minimal/index.html +++ b/web/public/presets/empty-and-minimal/index.html @@ -5,7 +5,7 @@ Smallest Valid and Empty Test Files in Every Format - + @@ -34,7 +34,7 @@ - + @@ -63,7 +63,7 @@ - + @@ -178,10 +178,10 @@

                            What is in the set?

                            - - - - + + + +
                            Files32
                            Targets in its recipe32
                            Total size40 431 B
                            Formatsavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                            Files33
                            Targets in its recipe33
                            Total size40 496 B
                            Formatsavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, rtf, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                            @@ -192,7 +192,7 @@

                            What is in the set?

                            ExpectedMeaningFiles - acceptYour system should take the file.30 + acceptYour system should take the file.31 unspecifiedIt depends on the rules of your system. You decide, then check that what happens is what you meant.2 diff --git a/web/public/pt-br/arquivos-de-teste-corrompidos/index.html b/web/public/pt-br/arquivos-de-teste-corrompidos/index.html index b953cfae..64bd13b4 100644 --- a/web/public/pt-br/arquivos-de-teste-corrompidos/index.html +++ b/web/public/pt-br/arquivos-de-teste-corrompidos/index.html @@ -201,7 +201,7 @@

                            Um arquivo danificado continua com o tamanho que você pediu

                            tfg generate --format pdf --size 1mb --count 5 --damage zero-head:bytes=16 --out ./broken

                            As configurações vão depois de dois-pontos. A opção pode ser repetida, e os danos são aplicados na - ordem em que você os escreve. Funciona com cada um dos 30 formatos. + ordem em que você os escreve. Funciona com cada um dos 31 formatos.

                            diff --git a/web/public/pt-br/formatos/index.html b/web/public/pt-br/formatos/index.html index a6743d3f..ce4d2da7 100644 --- a/web/public/pt-br/formatos/index.html +++ b/web/public/pt-br/formatos/index.html @@ -4,8 +4,8 @@ -30 formatos de arquivo - PDF, DOCX, PNG, ZIP e mais - +31 formatos de arquivo - PDF, DOCX, PNG, ZIP e mais + @@ -33,8 +33,8 @@ - - + + @@ -62,8 +62,8 @@ - - + + @@ -144,7 +144,7 @@
                            -

                            30 formatos de arquivo, cada um gerado em um tamanho exato

                            +

                            31 formatos de arquivo, cada um gerado em um tamanho exato

                            Cada um é um arquivo real daquele formato. Abre no programa a que pertence e tem exatamente o número de bytes que você pediu. Nenhum é preenchimento de zeros com uma extensão @@ -308,6 +308,14 @@

                            30 formatos de arquivo, cada um gerado em um tamanho exato

                            full libreoffice + + rtf + Rich Text Format + .rtf + 65 + full + pandoc-rtf + svg Scalable Vector Graphics @@ -929,6 +937,26 @@

                            Configurações que cada formato aceita

                            slides 1 - 500 slides + + rtf + characters + ascii, international + + + + text_encoding + both, codepage, literal, unicode + + + + elements + basic, every + + + + nesting + 0 - 10000000 + svg width diff --git a/web/public/pt-br/index.html b/web/public/pt-br/index.html index 3581709b..01eb718d 100644 --- a/web/public/pt-br/index.html +++ b/web/public/pt-br/index.html @@ -4,7 +4,7 @@ -Gerador de arquivos de teste - tamanho exato, 30 formatos reais +Gerador de arquivos de teste - tamanho exato, 31 formatos reais @@ -33,7 +33,7 @@ - + @@ -62,7 +62,7 @@ - + @@ -76,7 +76,7 @@ "@type": "SoftwareApplication", "name": "Testing Files Generator", "alternateName": "tfg", - "description": "Um gerador gratuito e de código aberto de arquivos de teste para QA. Produz arquivos reais de 30 formatos no tamanho exato e escreve um manifesto que diz como o sistema sob teste deve reagir a cada um.", + "description": "Um gerador gratuito e de código aberto de arquivos de teste para QA. Produz arquivos reais de 31 formatos no tamanho exato e escreve um manifesto que diz como o sistema sob teste deve reagir a cada um.", "url": "https:\/\/testingfilesgenerator.donislawdev.com/", "applicationCategory": "DeveloperApplication", "applicationSubCategory": "Software Testing", @@ -157,7 +157,7 @@

                            Gere arquivos de teste reais no tamanho exato

                            - PDF, PNG, DOCX, ZIP - 30 formatos no total, e cada um é um + PDF, PNG, DOCX, ZIP - 31 formatos no total, e cada um é um arquivo real que abre no programa a que pertence, com exatamente o tamanho que você pediu. Cada execução também registra o que sua aplicação deve fazer com cada arquivo. Linha de comando e janela de desktop, gratuito e de código aberto, funcionando inteiramente na @@ -180,7 +180,7 @@

                            Gere arquivos de teste reais no tamanho exato

                            • - 30 + 31

                              formatos reais, cada um abre no programa a que pertence

                            • @@ -345,7 +345,7 @@

                              Feito para uma suíte que roda sem supervisão

                              Peça 10485761 bytes e receba exatamente isso. Um tamanho que um formato não alcança é um erro com um motivo, nunca um arquivo de tamanho errado.

                            • -

                              30 formatos reais

                              +

                              31 formatos reais

                              Não são zeros de preenchimento com uma extensão. Um PNG gerado abre em um visualizador de imagens, um DOCX abre no Word, um ZIP extrai. Cada um é verificado com leitores independentes antes de ser liberado.

                            • diff --git a/web/public/pt-br/perguntas-frequentes/index.html b/web/public/pt-br/perguntas-frequentes/index.html index eafe4e05..9b7d1d00 100644 --- a/web/public/pt-br/perguntas-frequentes/index.html +++ b/web/public/pt-br/perguntas-frequentes/index.html @@ -206,7 +206,7 @@

                              Perguntas frequentes

                              Quais formatos vêm a seguir?

                              -

                              7z e mp3. Hoje 30 formatos funcionam de ponta a ponta.

                              +

                              7z e mp3. Hoje 31 formatos funcionam de ponta a ponta.

                              @@ -277,7 +277,7 @@

                              Perguntas frequentes

                              { "@type": "Question", "name": "Quais formatos vêm a seguir?", - "acceptedAnswer": { "@type": "Answer", "text": "7z e mp3. Hoje 30 formatos funcionam de ponta a ponta." } + "acceptedAnswer": { "@type": "Answer", "text": "7z e mp3. Hoje 31 formatos funcionam de ponta a ponta." } }, { "@type": "Question", diff --git a/web/public/pt-br/presets/empty-and-minimal/index.html b/web/public/pt-br/presets/empty-and-minimal/index.html index 99ef9b51..0011e0cd 100644 --- a/web/public/pt-br/presets/empty-and-minimal/index.html +++ b/web/public/pt-br/presets/empty-and-minimal/index.html @@ -5,7 +5,7 @@ Menores arquivos de teste válidos e vazios em cada formato - + @@ -34,7 +34,7 @@ - + @@ -63,7 +63,7 @@ - + @@ -178,10 +178,10 @@

                              O que há no conjunto?

                              - - - - + + + +
                              Arquivos32
                              Targets na sua receita32
                              Tamanho total40 431 B
                              Formatosavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                              Arquivos33
                              Targets na sua receita33
                              Tamanho total40 496 B
                              Formatosavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, rtf, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                              @@ -192,7 +192,7 @@

                              O que há no conjunto?

                              EsperadoSignificadoArquivos - acceptSeu sistema deve aceitar o arquivo.30 + acceptSeu sistema deve aceitar o arquivo.31 unspecifiedDepende das regras do seu sistema. Você decide e depois confere se o que acontece é o que você queria.2 diff --git a/web/public/ro/fisiere-de-test-corupte/index.html b/web/public/ro/fisiere-de-test-corupte/index.html index 6ca8992c..aff3e191 100644 --- a/web/public/ro/fisiere-de-test-corupte/index.html +++ b/web/public/ro/fisiere-de-test-corupte/index.html @@ -202,7 +202,7 @@

                              Un fișier deteriorat are în continuare mărimea cerută

                              tfg generate --format pdf --size 1mb --count 5 --damage zero-head:bytes=16 --out ./broken

                              Setările se scriu după două puncte. Opțiunea poate fi repetată, iar deteriorările se aplică în - ordinea în care le scrii. Funcționează cu fiecare dintre cele 30 formate. + ordinea în care le scrii. Funcționează cu fiecare dintre cele 31 formate.

                              diff --git a/web/public/ro/formate/index.html b/web/public/ro/formate/index.html index 941088b3..6a2bde53 100644 --- a/web/public/ro/formate/index.html +++ b/web/public/ro/formate/index.html @@ -4,8 +4,8 @@ -30 formate de fișiere - PDF, DOCX, PNG, ZIP și altele - +31 formate de fișiere - PDF, DOCX, PNG, ZIP și altele + @@ -33,8 +33,8 @@ - - + + @@ -62,8 +62,8 @@ - - + + @@ -144,7 +144,7 @@
                              -

                              30 formate de fișiere, fiecare generat la o dimensiune exactă

                              +

                              31 formate de fișiere, fiecare generat la o dimensiune exactă

                              Fiecare este un fișier real al acelui format. Se deschide în programul căruia îi aparține și are exact numărul de octeți pe care l-ai cerut. Niciunul nu e umplutură de zerouri cu @@ -308,6 +308,14 @@

                              30 formate de fișiere, fiecare generat la o dimensiune exactă

                              full libreoffice + + rtf + Rich Text Format + .rtf + 65 + full + pandoc-rtf + svg Scalable Vector Graphics @@ -929,6 +937,26 @@

                              Setările pe care le acceptă fiecare format

                              slides 1 - 500 diapozitive + + rtf + characters + ascii, international + + + + text_encoding + both, codepage, literal, unicode + + + + elements + basic, every + + + + nesting + 0 - 10000000 + svg width diff --git a/web/public/ro/index.html b/web/public/ro/index.html index 76399855..24e41825 100644 --- a/web/public/ro/index.html +++ b/web/public/ro/index.html @@ -4,7 +4,7 @@ -Generator de fișiere de test - dimensiune exactă, 30 formate reale +Generator de fișiere de test - dimensiune exactă, 31 formate reale @@ -33,7 +33,7 @@ - + @@ -62,7 +62,7 @@ - + @@ -76,7 +76,7 @@ "@type": "SoftwareApplication", "name": "Testing Files Generator", "alternateName": "tfg", - "description": "Un generator gratuit și open source de fișiere de test pentru QA. Produce fișiere reale în 30 formate, la dimensiunea exactă, și scrie un manifest care spune cum trebuie să reacționeze sistemul testat la fiecare.", + "description": "Un generator gratuit și open source de fișiere de test pentru QA. Produce fișiere reale în 31 formate, la dimensiunea exactă, și scrie un manifest care spune cum trebuie să reacționeze sistemul testat la fiecare.", "url": "https:\/\/testingfilesgenerator.donislawdev.com/", "applicationCategory": "DeveloperApplication", "applicationSubCategory": "Software Testing", @@ -157,7 +157,7 @@

                              Generează fișiere de test reale la dimensiunea exactă

                              - PDF, PNG, DOCX, ZIP - 30 formate în total, și fiecare este un + PDF, PNG, DOCX, ZIP - 31 formate în total, și fiecare este un fișier real care se deschide în programul căruia îi aparține, la exact dimensiunea pe care ai cerut-o. Fiecare rulare notează și ce trebuie să facă aplicația ta cu fiecare fișier. Linie de comandă și fereastră desktop, gratuit și open source, funcționând în întregime @@ -180,7 +180,7 @@

                              Generează fișiere de test reale la dimensiunea exactă

                              • - 30 + 31

                                formate reale, fiecare se deschide în programul căruia îi aparține

                              • @@ -343,7 +343,7 @@

                                Construit pentru o suită care rulează nesupravegheată

                                Cere 10485761 de octeți și primești exact atât. O dimensiune pe care un format nu o poate atinge este o eroare cu un motiv, niciodată un fișier de dimensiune greșită.

                              • -

                                30 formate reale

                                +

                                31 formate reale

                                Nu zerouri de umplutură cu o extensie. Un PNG generat se deschide într-un vizualizator de imagini, un DOCX se deschide în Word, un ZIP se extrage. Fiecare este verificat cu cititori independenți înainte de livrare.

                              • diff --git a/web/public/ro/intrebari-frecvente/index.html b/web/public/ro/intrebari-frecvente/index.html index 6c4808fe..c836faf2 100644 --- a/web/public/ro/intrebari-frecvente/index.html +++ b/web/public/ro/intrebari-frecvente/index.html @@ -206,7 +206,7 @@

                                Întrebări frecvente

                                Ce formate urmează?

                                -

                                7z și mp3. Azi funcționează de la un capăt la altul 30 formate.

                                +

                                7z și mp3. Azi funcționează de la un capăt la altul 31 formate.

                                @@ -277,7 +277,7 @@

                                Întrebări frecvente

                                { "@type": "Question", "name": "Ce formate urmează?", - "acceptedAnswer": { "@type": "Answer", "text": "7z și mp3. Azi funcționează de la un capăt la altul 30 formate." } + "acceptedAnswer": { "@type": "Answer", "text": "7z și mp3. Azi funcționează de la un capăt la altul 31 formate." } }, { "@type": "Question", diff --git a/web/public/ro/presetari/empty-and-minimal/index.html b/web/public/ro/presetari/empty-and-minimal/index.html index 1745887d..decf4447 100644 --- a/web/public/ro/presetari/empty-and-minimal/index.html +++ b/web/public/ro/presetari/empty-and-minimal/index.html @@ -5,7 +5,7 @@ Cele mai mici fișiere de test valide și goale, în fiecare format - + @@ -34,7 +34,7 @@ - + @@ -63,7 +63,7 @@ - + @@ -179,10 +179,10 @@

                                Ce este în set?

                                - - - - + + + +
                                Fișiere32
                                Targeturi în rețeta lui32
                                Dimensiune totală40 431 B
                                Formateavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                                Fișiere33
                                Targeturi în rețeta lui33
                                Dimensiune totală40 496 B
                                Formateavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, rtf, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                                @@ -193,7 +193,7 @@

                                Ce este în set?

                                AșteptatSemnificațieFișiere - acceptSistemul tău trebuie să accepte fișierul.30 + acceptSistemul tău trebuie să accepte fișierul.31 unspecifiedDepinde de regulile sistemului tău. Tu decizi, apoi verifici că ce se întâmplă este ce ai vrut.2 diff --git a/web/public/ru/corrupt-test-files/index.html b/web/public/ru/corrupt-test-files/index.html index 23fe28ce..6cd81714 100644 --- a/web/public/ru/corrupt-test-files/index.html +++ b/web/public/ru/corrupt-test-files/index.html @@ -202,7 +202,7 @@

                                Повреждённый файл остаётся нужного разме tfg generate --format pdf --size 1mb --count 5 --damage zero-head:bytes=16 --out ./broken

                                Настройки пишутся после двоеточия. Параметр можно повторять, а повреждения применяются в том - порядке, в каком вы их записали. Это работает с каждым из 30 форматов. + порядке, в каком вы их записали. Это работает с каждым из 31 форматов.

                                diff --git a/web/public/ru/faq/index.html b/web/public/ru/faq/index.html index 686300fc..ad05591b 100644 --- a/web/public/ru/faq/index.html +++ b/web/public/ru/faq/index.html @@ -206,7 +206,7 @@

                                Часто задаваемые вопросы

                                Какие форматы появятся дальше?

                                -

                                7z и mp3. Сегодня полностью работают 30 форматов.

                                +

                                7z и mp3. Сегодня полностью работают 31 форматов.

                                @@ -277,7 +277,7 @@

                                Часто задаваемые вопросы

                                { "@type": "Question", "name": "Какие форматы появятся дальше?", - "acceptedAnswer": { "@type": "Answer", "text": "7z и mp3. Сегодня полностью работают 30 форматов." } + "acceptedAnswer": { "@type": "Answer", "text": "7z и mp3. Сегодня полностью работают 31 форматов." } }, { "@type": "Question", diff --git a/web/public/ru/formats/index.html b/web/public/ru/formats/index.html index 74d3c5fc..9b253fe4 100644 --- a/web/public/ru/formats/index.html +++ b/web/public/ru/formats/index.html @@ -4,8 +4,8 @@ -30 форматов файлов - PDF, DOCX, PNG, ZIP и другие - +31 форматов файлов - PDF, DOCX, PNG, ZIP и другие + @@ -33,8 +33,8 @@ - - + + @@ -62,8 +62,8 @@ - - + + @@ -144,7 +144,7 @@
                                -

                                30 форматов файлов, каждый создаётся точного размера

                                +

                                31 форматов файлов, каждый создаётся точного размера

                                Каждый из них - настоящий файл этого формата. Он открывается в своей программе и имеет ровно то число байт, которое вы запросили. Ни один не является нулями-заполнителями с @@ -308,6 +308,14 @@

                                30 форматов файлов, каждый создаётся точно full libreoffice + + rtf + Rich Text Format + .rtf + 65 + full + pandoc-rtf + svg Scalable Vector Graphics @@ -928,6 +936,26 @@

                                Настройки, которые принимает каждый форм slides 1 - 500 слайдов + + rtf + characters + ascii, international + + + + text_encoding + both, codepage, literal, unicode + + + + elements + basic, every + + + + nesting + 0 - 10000000 + svg width diff --git a/web/public/ru/index.html b/web/public/ru/index.html index 30a67d5d..076dc3d3 100644 --- a/web/public/ru/index.html +++ b/web/public/ru/index.html @@ -4,7 +4,7 @@ -Генератор тестовых файлов для QA - точный размер, 30 форматов +Генератор тестовых файлов для QA - точный размер, 31 форматов @@ -33,7 +33,7 @@ - + @@ -62,7 +62,7 @@ - + @@ -76,7 +76,7 @@ "@type": "SoftwareApplication", "name": "Testing Files Generator", "alternateName": "tfg", - "description": "Бесплатный генератор тестовых файлов для QA с открытым кодом. Создаёт настоящие файлы в 30 форматах точного размера и записывает манифест с ожидаемой реакцией тестируемой системы на каждый из них.", + "description": "Бесплатный генератор тестовых файлов для QA с открытым кодом. Создаёт настоящие файлы в 31 форматах точного размера и записывает манифест с ожидаемой реакцией тестируемой системы на каждый из них.", "url": "https:\/\/testingfilesgenerator.donislawdev.com/", "applicationCategory": "DeveloperApplication", "applicationSubCategory": "Software Testing", @@ -157,7 +157,7 @@

                                Создавайте настоящие тестовые файлы точного размера

                                - PDF, PNG, DOCX, ZIP - всего 30 форматов, и каждый из них + PDF, PNG, DOCX, ZIP - всего 31 форматов, и каждый из них настоящий файл, который открывается в своей программе, точно того размера, который вы запросили. Каждый запуск ещё и записывает, что ваше приложение должно делать с каждым файлом. Командная строка и десктопное окно, бесплатно и с открытым кодом, всё работает на вашей @@ -180,7 +180,7 @@

                                Создавайте настоящие тестовые файлы точн
                                • - 30 + 31

                                  настоящих форматов, каждый открывается в своей программе

                                • @@ -343,7 +343,7 @@

                                  Создан для набора тестов, работающего без

                                  Запросите 10485761 байт и получите ровно столько. Размер, которого формат не может достичь, - это ошибка с причиной, а не файл неверного размера.

                                • -

                                  30 настоящих форматов

                                  +

                                  31 настоящих форматов

                                  Не нули-заполнители с расширением. Созданный PNG открывается в просмотрщике изображений, DOCX - в Word, ZIP распаковывается. Каждый формат проверяется независимыми читателями до выпуска.

                                • diff --git a/web/public/ru/presets/empty-and-minimal/index.html b/web/public/ru/presets/empty-and-minimal/index.html index b0931810..9ce3b910 100644 --- a/web/public/ru/presets/empty-and-minimal/index.html +++ b/web/public/ru/presets/empty-and-minimal/index.html @@ -5,7 +5,7 @@ Минимальные корректные и пустые тестовые файлы в каждом формате - + @@ -34,7 +34,7 @@ - + @@ -63,7 +63,7 @@ - + @@ -178,10 +178,10 @@

                                  Что входит в набор?

                                  - - - - + + + +
                                  Файлов32
                                  Целей в его рецепте32
                                  Общий размер40 431 B
                                  Форматыavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                                  Файлов33
                                  Целей в его рецепте33
                                  Общий размер40 496 B
                                  Форматыavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, rtf, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                                  @@ -192,7 +192,7 @@

                                  Что входит в набор?

                                  ОжидаетсяЗначениеФайлов - acceptВаша система должна принять файл.30 + acceptВаша система должна принять файл.31 unspecifiedЗависит от правил вашей системы. Вы решаете, а затем проверяете, что происходит именно то, что вы имели в виду.2 diff --git a/web/public/social.html b/web/public/social.html index a81dd581..94e6846a 100644 --- a/web/public/social.html +++ b/web/public/social.html @@ -203,7 +203,7 @@

                                  Test sets,
                                  not just files.

                                  • Presets - ready test sets for size limits, file names, encodings and imports
                                  • Recipes - one YAML file, same bytes in every CI run
                                  • -
                                  • 30 formats with their own settings - pages, pixels, rows, archive contents
                                  • +
                                  • 31 formats with their own settings - pages, pixels, rows, archive contents

                                  Free and open source · works offline · Windows · macOS · Linux

                                diff --git a/web/public/th/corrupt-test-files/index.html b/web/public/th/corrupt-test-files/index.html index 77bc32c0..cfce62e3 100644 --- a/web/public/th/corrupt-test-files/index.html +++ b/web/public/th/corrupt-test-files/index.html @@ -199,7 +199,7 @@

                                ไฟล์ที่เสียหายยังมีขนาดตา tfg generate --format pdf --size 1mb --count 5 --damage zero-head:bytes=16 --out ./broken

                                การตั้งค่าเขียนหลังเครื่องหมายทวิภาค ตัวเลือกนี้ใส่ซ้ำได้ - และความเสียหายจะถูกนำมาใช้ตามลำดับที่คุณเขียน ใช้ได้กับทั้ง 30 รูปแบบ + และความเสียหายจะถูกนำมาใช้ตามลำดับที่คุณเขียน ใช้ได้กับทั้ง 31 รูปแบบ

                                diff --git a/web/public/th/faq/index.html b/web/public/th/faq/index.html index 864bedc0..4aba3806 100644 --- a/web/public/th/faq/index.html +++ b/web/public/th/faq/index.html @@ -205,7 +205,7 @@

                                คำถามที่พบบ่อย

                                รูปแบบใดจะมาต่อไป

                                -

                                7z และ mp3 ตอนนี้ 30 รูปแบบทำงานได้ครบตั้งแต่ต้นจนจบ

                                +

                                7z และ mp3 ตอนนี้ 31 รูปแบบทำงานได้ครบตั้งแต่ต้นจนจบ

                                @@ -276,7 +276,7 @@

                                คำถามที่พบบ่อย

                                { "@type": "Question", "name": "รูปแบบใดจะมาต่อไป", - "acceptedAnswer": { "@type": "Answer", "text": "7z และ mp3 ตอนนี้ 30 รูปแบบทำงานได้ครบตั้งแต่ต้นจนจบ" } + "acceptedAnswer": { "@type": "Answer", "text": "7z และ mp3 ตอนนี้ 31 รูปแบบทำงานได้ครบตั้งแต่ต้นจนจบ" } }, { "@type": "Question", diff --git a/web/public/th/formats/index.html b/web/public/th/formats/index.html index 8bf91ad8..1e376d26 100644 --- a/web/public/th/formats/index.html +++ b/web/public/th/formats/index.html @@ -4,8 +4,8 @@ -30 รูปแบบไฟล์ที่รองรับ - PDF, DOCX, PNG, ZIP และอื่นๆ - +31 รูปแบบไฟล์ที่รองรับ - PDF, DOCX, PNG, ZIP และอื่นๆ + @@ -33,8 +33,8 @@ - - + + @@ -62,8 +62,8 @@ - - + + @@ -144,7 +144,7 @@
                                -

                                30 รูปแบบไฟล์ แต่ละรูปแบบสร้างที่ขนาดแม่นยำ

                                +

                                31 รูปแบบไฟล์ แต่ละรูปแบบสร้างที่ขนาดแม่นยำ

                                ทุกรูปแบบเป็นไฟล์จริงของรูปแบบนั้น เปิดได้ในซอฟต์แวร์ของมัน และมีจำนวนไบต์ตรงตามที่คุณขอพอดี ไม่มีรูปแบบใดเป็นศูนย์เติมเต็มที่แปะนามสกุลเข้าไป @@ -307,6 +307,14 @@

                                30 รูปแบบไฟล์ แต่ละรูปแบบสร้ full libreoffice + + rtf + Rich Text Format + .rtf + 65 + full + pandoc-rtf + svg Scalable Vector Graphics @@ -926,6 +934,26 @@

                                การตั้งค่าที่แต่ละรูปแบบร slides 1 - 500 สไลด์ + + rtf + characters + ascii, international + + + + text_encoding + both, codepage, literal, unicode + + + + elements + basic, every + + + + nesting + 0 - 10000000 + svg width diff --git a/web/public/th/index.html b/web/public/th/index.html index b68fa5c7..07fb489b 100644 --- a/web/public/th/index.html +++ b/web/public/th/index.html @@ -4,7 +4,7 @@ -ตัวสร้างไฟล์ทดสอบสำหรับ QA - ขนาดแม่นยำ 30 รูปแบบจริง +ตัวสร้างไฟล์ทดสอบสำหรับ QA - ขนาดแม่นยำ 31 รูปแบบจริง @@ -33,7 +33,7 @@ - + @@ -62,7 +62,7 @@ - + @@ -76,7 +76,7 @@ "@type": "SoftwareApplication", "name": "Testing Files Generator", "alternateName": "tfg", - "description": "ตัวสร้างไฟล์ทดสอบสำหรับ QA ฟรีและโอเพนซอร์ส สร้างไฟล์จริงใน 30 รูปแบบด้วยขนาดแม่นยำ และเขียนแมนิเฟสต์ที่บอกว่าระบบที่ถูกทดสอบควรตอบสนองต่อแต่ละไฟล์อย่างไร", + "description": "ตัวสร้างไฟล์ทดสอบสำหรับ QA ฟรีและโอเพนซอร์ส สร้างไฟล์จริงใน 31 รูปแบบด้วยขนาดแม่นยำ และเขียนแมนิเฟสต์ที่บอกว่าระบบที่ถูกทดสอบควรตอบสนองต่อแต่ละไฟล์อย่างไร", "url": "https:\/\/testingfilesgenerator.donislawdev.com/", "applicationCategory": "DeveloperApplication", "applicationSubCategory": "Software Testing", @@ -157,7 +157,7 @@

                                สร้างไฟล์ทดสอบจริงที่ขนาดแม่นยำ

                                - PDF, PNG, DOCX, ZIP - รวม 30 รูปแบบ + PDF, PNG, DOCX, ZIP - รวม 31 รูปแบบ และทุกไฟล์เป็นไฟล์จริงที่เปิดได้ในซอฟต์แวร์ของมัน ด้วยขนาดตรงตามที่คุณขอพอดี ทุกครั้งที่รันยังจดด้วยว่าแอปพลิเคชันของคุณควรทำอย่างไรกับแต่ละไฟล์ มีทั้งบรรทัดคำสั่งและหน้าต่างเดสก์ท็อป ฟรีและโอเพนซอร์ส ทำงานทั้งหมดบนเครื่องของคุณ @@ -179,7 +179,7 @@

                                สร้างไฟล์ทดสอบจริงที่ขนาด
                                • - 30 + 31

                                  รูปแบบจริง แต่ละรูปแบบเปิดได้ในซอฟต์แวร์ของมัน

                                • @@ -341,7 +341,7 @@

                                  สร้างมาสำหรับชุดทดสอบที่ร

                                  ขอ 10485761 ไบต์ แล้วได้ตามนั้นพอดี ขนาดที่รูปแบบไปไม่ถึงคือข้อผิดพลาดที่มีเหตุผล ไม่ใช่ไฟล์ขนาดผิด

                                • -

                                  30 รูปแบบจริง

                                  +

                                  31 รูปแบบจริง

                                  ไม่ใช่ศูนย์ที่เติมเต็มพร้อมนามสกุล PNG ที่สร้างเปิดได้ในโปรแกรมดูภาพ DOCX เปิดได้ใน Word และ ZIP แตกไฟล์ได้ ทุกรูปแบบถูกตรวจด้วยตัวอ่านอิสระก่อนปล่อย

                                • diff --git a/web/public/th/presets/empty-and-minimal/index.html b/web/public/th/presets/empty-and-minimal/index.html index 78966749..234853d6 100644 --- a/web/public/th/presets/empty-and-minimal/index.html +++ b/web/public/th/presets/empty-and-minimal/index.html @@ -5,7 +5,7 @@ ไฟล์ทดสอบที่ถูกต้องเล็กที่สุดและไฟล์ว่างในทุกรูปแบบ - + @@ -34,7 +34,7 @@ - + @@ -63,7 +63,7 @@ - + @@ -178,10 +178,10 @@

                                  ในชุดมีอะไร

                                  - - - - + + + +
                                  ไฟล์32
                                  target ในสูตรของมัน32
                                  ขนาดรวม40 431 B
                                  รูปแบบavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                                  ไฟล์33
                                  target ในสูตรของมัน33
                                  ขนาดรวม40 496 B
                                  รูปแบบavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, rtf, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                                  @@ -192,7 +192,7 @@

                                  ในชุดมีอะไร

                                  ที่คาดหวังความหมายไฟล์ - acceptระบบของคุณควรยอมรับไฟล์นี้30 + acceptระบบของคุณควรยอมรับไฟล์นี้31 unspecifiedขึ้นอยู่กับกฎของระบบของคุณ คุณเป็นผู้ตัดสิน แล้วตรวจสอบว่าสิ่งที่เกิดขึ้นตรงกับที่ตั้งใจ2 diff --git a/web/public/tr/bicimler/index.html b/web/public/tr/bicimler/index.html index a35435ab..07338d2f 100644 --- a/web/public/tr/bicimler/index.html +++ b/web/public/tr/bicimler/index.html @@ -4,8 +4,8 @@ -30 desteklenen dosya biçimi - PDF, DOCX, PNG, ZIP ve daha fazlası - +31 desteklenen dosya biçimi - PDF, DOCX, PNG, ZIP ve daha fazlası + @@ -33,8 +33,8 @@ - - + + @@ -62,8 +62,8 @@ - - + + @@ -144,7 +144,7 @@
                                  -

                                  30 dosya biçimi, her biri tam boyutta üretilir

                                  +

                                  31 dosya biçimi, her biri tam boyutta üretilir

                                  Bunların her biri o biçimde gerçek bir dosyadır. Ait olduğu programda açılır ve tam istediğiniz bayt sayısındadır. Hiçbiri yapıştırılmış uzantılı dolgu sıfırları değildir. @@ -307,6 +307,14 @@

                                  30 dosya biçimi, her biri tam boyutta üretilir

                                  full libreoffice + + rtf + Rich Text Format + .rtf + 65 + full + pandoc-rtf + svg Scalable Vector Graphics @@ -928,6 +936,26 @@

                                  Her biçimin kabul ettiği ayarlar

                                  slides 1 - 500 slayt + + rtf + characters + ascii, international + + + + text_encoding + both, codepage, literal, unicode + + + + elements + basic, every + + + + nesting + 0 - 10000000 + svg width diff --git a/web/public/tr/bozuk-test-dosyalari/index.html b/web/public/tr/bozuk-test-dosyalari/index.html index 818060e3..1d26f66c 100644 --- a/web/public/tr/bozuk-test-dosyalari/index.html +++ b/web/public/tr/bozuk-test-dosyalari/index.html @@ -201,7 +201,7 @@

                                  Hasarlı bir dosya yine istediğiniz boyuttadır

                                  tfg generate --format pdf --size 1mb --count 5 --damage zero-head:bytes=16 --out ./broken

                                  Ayarlar iki noktadan sonra yazılır. Seçenek tekrarlanabilir ve hasarlar yazdığınız sırayla - uygulanır. 30 biçimin her biriyle çalışır. + uygulanır. 31 biçimin her biriyle çalışır.

                                  diff --git a/web/public/tr/hazir-ayarlar/empty-and-minimal/index.html b/web/public/tr/hazir-ayarlar/empty-and-minimal/index.html index 4dcec871..40dd9356 100644 --- a/web/public/tr/hazir-ayarlar/empty-and-minimal/index.html +++ b/web/public/tr/hazir-ayarlar/empty-and-minimal/index.html @@ -5,7 +5,7 @@ Her biçimde en küçük geçerli ve boş test dosyaları - + @@ -34,7 +34,7 @@ - + @@ -63,7 +63,7 @@ - + @@ -179,10 +179,10 @@

                                  Sette ne var?

                                  - - - - + + + +
                                  Dosya32
                                  Tarifindeki hedefler32
                                  Toplam boyut40 431 B
                                  Biçimleravif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                                  Dosya33
                                  Tarifindeki hedefler33
                                  Toplam boyut40 496 B
                                  Biçimleravif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, rtf, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                                  @@ -193,7 +193,7 @@

                                  Sette ne var?

                                  BeklenenAnlamıDosya - acceptSisteminiz dosyayı kabul etmeli.30 + acceptSisteminiz dosyayı kabul etmeli.31 unspecifiedSisteminizin kurallarına bağlı. Siz karar verirsiniz, sonra olanın amaçladığınız şey olduğunu doğrularsınız.2 diff --git a/web/public/tr/index.html b/web/public/tr/index.html index a6485a33..6846df5b 100644 --- a/web/public/tr/index.html +++ b/web/public/tr/index.html @@ -4,7 +4,7 @@ -QA için test dosyası oluşturucu - tam boyut, 30 gerçek biçim +QA için test dosyası oluşturucu - tam boyut, 31 gerçek biçim @@ -33,7 +33,7 @@ - + @@ -62,7 +62,7 @@ - + @@ -76,7 +76,7 @@ "@type": "SoftwareApplication", "name": "Testing Files Generator", "alternateName": "tfg", - "description": "QA için ücretsiz ve açık kaynaklı bir test dosyası oluşturucu. 30 biçimde tam boyutta gerçek dosyalar üretir ve test edilen sistemin her birine nasıl tepki vermesi gerektiğini söyleyen bir manifest yazar.", + "description": "QA için ücretsiz ve açık kaynaklı bir test dosyası oluşturucu. 31 biçimde tam boyutta gerçek dosyalar üretir ve test edilen sistemin her birine nasıl tepki vermesi gerektiğini söyleyen bir manifest yazar.", "url": "https:\/\/testingfilesgenerator.donislawdev.com/", "applicationCategory": "DeveloperApplication", "applicationSubCategory": "Software Testing", @@ -157,7 +157,7 @@

                                  Tam boyutta gerçek test dosyaları üretin

                                  - PDF, PNG, DOCX, ZIP - toplam 30 biçim ve her biri ait olduğu + PDF, PNG, DOCX, ZIP - toplam 31 biçim ve her biri ait olduğu programda açılan, tam istediğiniz boyutta gerçek bir dosya. Her çalıştırma ayrıca uygulamanızın her dosyayla ne yapması gerektiğini de yazar. Komut satırı ve masaüstü penceresi, ücretsiz ve açık kaynak, tamamen makinenizde çalışır. @@ -179,7 +179,7 @@

                                  Tam boyutta gerçek test dosyaları üretin

                                  • - 30 + 31

                                    gerçek biçim, her biri ait olduğu programda açılır

                                  • @@ -342,7 +342,7 @@

                                    Gözetimsiz çalışan bir test takımı için yapıldı

                                    10485761 bayt isteyin ve tam olarak onu alın. Bir biçimin ulaşamayacağı boyut nedeni olan bir hatadır, asla yanlış boyutta bir dosya değil.

                                  • -

                                    30 gerçek biçim

                                    +

                                    31 gerçek biçim

                                    Uzantılı dolgu sıfırları değil. Üretilmiş bir PNG resim görüntüleyicide, bir DOCX Word'de açılır, bir ZIP çıkarılır. Her biri yayımlanmadan önce bağımsız okuyucularla doğrulanır.

                                  • diff --git a/web/public/tr/sss/index.html b/web/public/tr/sss/index.html index 7949e6d4..9e3dbac8 100644 --- a/web/public/tr/sss/index.html +++ b/web/public/tr/sss/index.html @@ -205,7 +205,7 @@

                                    Sık sorulan sorular

                                    Sırada hangi biçimler var?

                                    -

                                    7z ve mp3. Bugün 30 biçim uçtan uca çalışıyor.

                                    +

                                    7z ve mp3. Bugün 31 biçim uçtan uca çalışıyor.

                                    @@ -276,7 +276,7 @@

                                    Sık sorulan sorular

                                    { "@type": "Question", "name": "Sırada hangi biçimler var?", - "acceptedAnswer": { "@type": "Answer", "text": "7z ve mp3. Bugün 30 biçim uçtan uca çalışıyor." } + "acceptedAnswer": { "@type": "Answer", "text": "7z ve mp3. Bugün 31 biçim uçtan uca çalışıyor." } }, { "@type": "Question", diff --git a/web/public/uk/corrupt-test-files/index.html b/web/public/uk/corrupt-test-files/index.html index eab28dd0..93154e94 100644 --- a/web/public/uk/corrupt-test-files/index.html +++ b/web/public/uk/corrupt-test-files/index.html @@ -202,7 +202,7 @@

                                    Пошкоджений файл лишається потрібного ро tfg generate --format pdf --size 1mb --count 5 --damage zero-head:bytes=16 --out ./broken

                                    Налаштування пишуться після двокрапки. Параметр можна повторювати, а пошкодження застосовуються в - тому порядку, в якому ви їх записали. Це працює з кожним із 30 форматів. + тому порядку, в якому ви їх записали. Це працює з кожним із 31 форматів.

                                    diff --git a/web/public/uk/faq/index.html b/web/public/uk/faq/index.html index ca524b56..c38e7c61 100644 --- a/web/public/uk/faq/index.html +++ b/web/public/uk/faq/index.html @@ -206,7 +206,7 @@

                                    Часті запитання

                                    Які формати з'являться далі?

                                    -

                                    7z і mp3. Сьогодні повністю працюють 30 форматів.

                                    +

                                    7z і mp3. Сьогодні повністю працюють 31 форматів.

                                    @@ -277,7 +277,7 @@

                                    Часті запитання

                                    { "@type": "Question", "name": "Які формати з\u0027являться далі?", - "acceptedAnswer": { "@type": "Answer", "text": "7z і mp3. Сьогодні повністю працюють 30 форматів." } + "acceptedAnswer": { "@type": "Answer", "text": "7z і mp3. Сьогодні повністю працюють 31 форматів." } }, { "@type": "Question", diff --git a/web/public/uk/formats/index.html b/web/public/uk/formats/index.html index e1c44bd6..81878041 100644 --- a/web/public/uk/formats/index.html +++ b/web/public/uk/formats/index.html @@ -4,8 +4,8 @@ -30 форматів файлів - PDF, DOCX, PNG, ZIP та інші - +31 форматів файлів - PDF, DOCX, PNG, ZIP та інші + @@ -33,8 +33,8 @@ - - + + @@ -62,8 +62,8 @@ - - + + @@ -144,7 +144,7 @@
                                    -

                                    30 форматів файлів, кожен створюється точного розміру

                                    +

                                    31 форматів файлів, кожен створюється точного розміру

                                    Кожен із них - справжній файл цього формату. Він відкривається у своїй програмі та має рівно стільки байтів, скільки ви запросили. Жоден не є нулями-заповнювачами з приклеєним @@ -308,6 +308,14 @@

                                    30 форматів файлів, кожен створюється точн full libreoffice + + rtf + Rich Text Format + .rtf + 65 + full + pandoc-rtf + svg Scalable Vector Graphics @@ -928,6 +936,26 @@

                                    Налаштування, які приймає кожен формат

                                    slides 1 - 500 слайдів + + rtf + characters + ascii, international + + + + text_encoding + both, codepage, literal, unicode + + + + elements + basic, every + + + + nesting + 0 - 10000000 + svg width diff --git a/web/public/uk/index.html b/web/public/uk/index.html index fe5ff9c8..224770c3 100644 --- a/web/public/uk/index.html +++ b/web/public/uk/index.html @@ -4,7 +4,7 @@ -Генератор тестових файлів для QA - точний розмір, 30 форматів +Генератор тестових файлів для QA - точний розмір, 31 форматів @@ -33,7 +33,7 @@ - + @@ -62,7 +62,7 @@ - + @@ -76,7 +76,7 @@ "@type": "SoftwareApplication", "name": "Testing Files Generator", "alternateName": "tfg", - "description": "Безкоштовний генератор тестових файлів для QA з відкритим кодом. Створює справжні файли у 30 форматах точного розміру й записує маніфест з очікуваною реакцією тестованої системи на кожен із них.", + "description": "Безкоштовний генератор тестових файлів для QA з відкритим кодом. Створює справжні файли у 31 форматах точного розміру й записує маніфест з очікуваною реакцією тестованої системи на кожен із них.", "url": "https:\/\/testingfilesgenerator.donislawdev.com/", "applicationCategory": "DeveloperApplication", "applicationSubCategory": "Software Testing", @@ -157,7 +157,7 @@

                                    Створюйте справжні тестові файли точного розміру

                                    - PDF, PNG, DOCX, ZIP - усього 30 форматів, і кожен із них - + PDF, PNG, DOCX, ZIP - усього 31 форматів, і кожен із них - справжній файл, що відкривається у своїй програмі, точно того розміру, який ви запросили. Кожен запуск ще й записує, що ваш застосунок має робити з кожним файлом. Командний рядок і десктопне вікно, безкоштовно та з відкритим кодом, усе працює на вашій машині. @@ -179,7 +179,7 @@

                                    Створюйте справжні тестові файли точного
                                    • - 30 + 31

                                      справжніх форматів, кожен відкривається у своїй програмі

                                    • @@ -342,7 +342,7 @@

                                      Створений для набору тестів, що працює бе

                                      Запросіть 10485761 байт і отримайте рівно стільки. Розмір, якого формат не може досягти, - це помилка з причиною, а не файл неправильного розміру.

                                    • -

                                      30 справжніх форматів

                                      +

                                      31 справжніх форматів

                                      Не нулі-заповнювачі з розширенням. Створений PNG відкривається в переглядачі зображень, DOCX - у Word, ZIP розпаковується. Кожен формат перевіряється незалежними читачами до випуску.

                                    • diff --git a/web/public/uk/presets/empty-and-minimal/index.html b/web/public/uk/presets/empty-and-minimal/index.html index 66e5d242..7a752415 100644 --- a/web/public/uk/presets/empty-and-minimal/index.html +++ b/web/public/uk/presets/empty-and-minimal/index.html @@ -5,7 +5,7 @@ Мінімальні коректні та порожні тестові файли в кожному форматі - + @@ -34,7 +34,7 @@ - + @@ -63,7 +63,7 @@ - + @@ -178,10 +178,10 @@

                                      Що входить у набір?

                                      - - - - + + + +
                                      Файлів32
                                      Цілей у його рецепті32
                                      Загальний розмір40 431 B
                                      Форматиavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                                      Файлів33
                                      Цілей у його рецепті33
                                      Загальний розмір40 496 B
                                      Форматиavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, rtf, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                                      @@ -192,7 +192,7 @@

                                      Що входить у набір?

                                      ОчікуєтьсяЗначенняФайлів - acceptВаша система має прийняти файл.30 + acceptВаша система має прийняти файл.31 unspecifiedЗалежить від правил вашої системи. Ви вирішуєте, а потім перевіряєте, що відбувається саме те, що ви мали на увазі.2 diff --git a/web/public/vi/dinh-dang/index.html b/web/public/vi/dinh-dang/index.html index c72a3572..61ece0db 100644 --- a/web/public/vi/dinh-dang/index.html +++ b/web/public/vi/dinh-dang/index.html @@ -4,8 +4,8 @@ -30 định dạng tệp được hỗ trợ - PDF, DOCX, PNG, ZIP và hơn nữa - +31 định dạng tệp được hỗ trợ - PDF, DOCX, PNG, ZIP và hơn nữa + @@ -33,8 +33,8 @@ - - + + @@ -62,8 +62,8 @@ - - + + @@ -144,7 +144,7 @@
                                      -

                                      30 định dạng tệp, mỗi định dạng được tạo ở kích thước chính xác

                                      +

                                      31 định dạng tệp, mỗi định dạng được tạo ở kích thước chính xác

                                      Mỗi cái là một tệp thật của định dạng đó. Nó mở được bằng phần mềm của nó và có đúng số byte bạn đã yêu cầu. Không cái nào là số không độn với phần mở rộng dán vào. @@ -307,6 +307,14 @@

                                      30 định dạng tệp, mỗi định dạng được tạo ở kích thư full libreoffice + + rtf + Rich Text Format + .rtf + 65 + full + pandoc-rtf + svg Scalable Vector Graphics @@ -926,6 +934,26 @@

                                      Các thiết lập mỗi định dạng nhận

                                      slides 1 - 500 trang chiếu + + rtf + characters + ascii, international + + + + text_encoding + both, codepage, literal, unicode + + + + elements + basic, every + + + + nesting + 0 - 10000000 + svg width diff --git a/web/public/vi/faq/index.html b/web/public/vi/faq/index.html index d39a4bd3..27b19e76 100644 --- a/web/public/vi/faq/index.html +++ b/web/public/vi/faq/index.html @@ -206,7 +206,7 @@

                                      Câu hỏi thường gặp

                                      Những định dạng nào sắp có?

                                      -

                                      7z và mp3. Hôm nay có 30 định dạng hoạt động trọn vẹn từ đầu đến cuối.

                                      +

                                      7z và mp3. Hôm nay có 31 định dạng hoạt động trọn vẹn từ đầu đến cuối.

                                      @@ -277,7 +277,7 @@

                                      Câu hỏi thường gặp

                                      { "@type": "Question", "name": "Những định dạng nào sắp có?", - "acceptedAnswer": { "@type": "Answer", "text": "7z và mp3. Hôm nay có 30 định dạng hoạt động trọn vẹn từ đầu đến cuối." } + "acceptedAnswer": { "@type": "Answer", "text": "7z và mp3. Hôm nay có 31 định dạng hoạt động trọn vẹn từ đầu đến cuối." } }, { "@type": "Question", diff --git a/web/public/vi/index.html b/web/public/vi/index.html index be60157c..99523b66 100644 --- a/web/public/vi/index.html +++ b/web/public/vi/index.html @@ -4,7 +4,7 @@ -Trình tạo tệp kiểm thử cho QA - kích thước chính xác, 30 định dạng +Trình tạo tệp kiểm thử cho QA - kích thước chính xác, 31 định dạng @@ -33,7 +33,7 @@ - + @@ -62,7 +62,7 @@ - + @@ -76,7 +76,7 @@ "@type": "SoftwareApplication", "name": "Testing Files Generator", "alternateName": "tfg", - "description": "Trình tạo tệp kiểm thử miễn phí, mã nguồn mở cho QA. Nó tạo tệp thật ở 30 định dạng, đúng kích thước, và ghi manifest nêu cách hệ thống được kiểm thử cần phản ứng với từng tệp.", + "description": "Trình tạo tệp kiểm thử miễn phí, mã nguồn mở cho QA. Nó tạo tệp thật ở 31 định dạng, đúng kích thước, và ghi manifest nêu cách hệ thống được kiểm thử cần phản ứng với từng tệp.", "url": "https:\/\/testingfilesgenerator.donislawdev.com/", "applicationCategory": "DeveloperApplication", "applicationSubCategory": "Software Testing", @@ -157,7 +157,7 @@

                                      Tạo tệp kiểm thử thật đúng kích thước

                                      - PDF, PNG, DOCX, ZIP - tổng cộng 30 định dạng, và mỗi tệp là + PDF, PNG, DOCX, ZIP - tổng cộng 31 định dạng, và mỗi tệp là tệp thật mở được bằng phần mềm của nó, ở đúng kích thước bạn yêu cầu. Mỗi lần chạy còn ghi lại ứng dụng của bạn cần làm gì với từng tệp. Dòng lệnh và cửa sổ desktop, miễn phí, mã nguồn mở, chạy hoàn toàn trên máy của bạn. @@ -179,7 +179,7 @@

                                      Tạo tệp kiểm thử thật đúng kích thước

                                      • - 30 + 31

                                        định dạng thật, mỗi định dạng mở được bằng phần mềm của nó

                                      • @@ -341,7 +341,7 @@

                                        Làm cho bộ kiểm thử chạy không cần người trông

                                        Yêu cầu 10485761 byte và nhận đúng như vậy. Kích thước mà định dạng không thể đạt là một lỗi có lý do, không bao giờ là tệp sai kích thước.

                                      • -

                                        30 định dạng thật

                                        +

                                        31 định dạng thật

                                        Không phải số không độn kèm một phần mở rộng. PNG được tạo mở trong trình xem ảnh, DOCX mở trong Word, ZIP giải nén được. Mỗi định dạng được kiểm tra bằng các trình đọc độc lập trước khi phát hành.

                                      • diff --git a/web/public/vi/preset/empty-and-minimal/index.html b/web/public/vi/preset/empty-and-minimal/index.html index ab82c7e2..f26df705 100644 --- a/web/public/vi/preset/empty-and-minimal/index.html +++ b/web/public/vi/preset/empty-and-minimal/index.html @@ -5,7 +5,7 @@ Tệp kiểm thử hợp lệ nhỏ nhất và tệp rỗng ở mọi định dạng - + @@ -34,7 +34,7 @@ - + @@ -63,7 +63,7 @@ - + @@ -178,10 +178,10 @@

                                        Trong bộ có gì?

                                        - - - - + + + +
                                        Tệp32
                                        Target trong công thức của nó32
                                        Tổng kích thước40 431 B
                                        Định dạngavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                                        Tệp33
                                        Target trong công thức của nó33
                                        Tổng kích thước40 496 B
                                        Định dạngavif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, rtf, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                                        @@ -192,7 +192,7 @@

                                        Trong bộ có gì?

                                        Mong đợiÝ nghĩaTệp - acceptHệ thống của bạn nên nhận tệp.30 + acceptHệ thống của bạn nên nhận tệp.31 unspecifiedTùy vào quy tắc của hệ thống bạn. Bạn quyết định, rồi kiểm tra điều xảy ra có đúng ý bạn không.2 diff --git a/web/public/vi/tep-kiem-thu-bi-hong/index.html b/web/public/vi/tep-kiem-thu-bi-hong/index.html index 191ad730..21f693fc 100644 --- a/web/public/vi/tep-kiem-thu-bi-hong/index.html +++ b/web/public/vi/tep-kiem-thu-bi-hong/index.html @@ -199,7 +199,7 @@

                                        Tệp bị hỏng vẫn có kích thước bạn đã yêu cầu

                                        tfg generate --format pdf --size 1mb --count 5 --damage zero-head:bytes=16 --out ./broken

                                        Cài đặt viết sau dấu hai chấm. Tùy chọn có thể lặp lại, và các hỏng hóc được áp dụng theo thứ tự bạn - viết. Nó dùng được với từng định dạng trong 30 định dạng. + viết. Nó dùng được với từng định dạng trong 31 định dạng.

                                        diff --git a/web/public/zh-hans/corrupt-test-files/index.html b/web/public/zh-hans/corrupt-test-files/index.html index a91263e0..9bb3a429 100644 --- a/web/public/zh-hans/corrupt-test-files/index.html +++ b/web/public/zh-hans/corrupt-test-files/index.html @@ -189,7 +189,7 @@

                                        损坏的文件仍然是你要求的大小

                                        tfg generate --format png --size 2mb --damage zero-head --out ./out
                                         tfg generate --format pdf --size 1mb --count 5 --damage zero-head:bytes=16 --out ./broken

                                        - 设置写在冒号之后。该选项可以重复,损坏按你写下的顺序依次应用。它适用于全部 30 种格式。 + 设置写在冒号之后。该选项可以重复,损坏按你写下的顺序依次应用。它适用于全部 31 种格式。

                                        diff --git a/web/public/zh-hans/faq/index.html b/web/public/zh-hans/faq/index.html index 8ad6c7d7..6111bcda 100644 --- a/web/public/zh-hans/faq/index.html +++ b/web/public/zh-hans/faq/index.html @@ -204,7 +204,7 @@

                                        常见问题

                                        接下来会支持哪些格式?

                                        -

                                        7z 和 mp3。目前有 30 种格式可以端到端使用。

                                        +

                                        7z 和 mp3。目前有 31 种格式可以端到端使用。

                                        @@ -275,7 +275,7 @@

                                        常见问题

                                        { "@type": "Question", "name": "接下来会支持哪些格式?", - "acceptedAnswer": { "@type": "Answer", "text": "7z 和 mp3。目前有 30 种格式可以端到端使用。" } + "acceptedAnswer": { "@type": "Answer", "text": "7z 和 mp3。目前有 31 种格式可以端到端使用。" } }, { "@type": "Question", diff --git a/web/public/zh-hans/formats/index.html b/web/public/zh-hans/formats/index.html index c8a252c8..0215cfad 100644 --- a/web/public/zh-hans/formats/index.html +++ b/web/public/zh-hans/formats/index.html @@ -4,8 +4,8 @@ -30 种支持的文件格式 - PDF、DOCX、PNG、ZIP 等 - +31 种支持的文件格式 - PDF、DOCX、PNG、ZIP 等 + @@ -33,8 +33,8 @@ - - + + @@ -62,8 +62,8 @@ - - + + @@ -144,7 +144,7 @@
                                        -

                                        30 种文件格式,每一种都按精确大小生成

                                        +

                                        31 种文件格式,每一种都按精确大小生成

                                        它们每一个都是该格式的真实文件。它能在对应软件中打开,字节数恰好等于你的要求。没有一个是粘上扩展名的填充零。

                                        @@ -306,6 +306,14 @@

                                        30 种文件格式,每一种都按精确大小生成

                                        full libreoffice + + rtf + Rich Text Format + .rtf + 65 + full + pandoc-rtf + svg Scalable Vector Graphics @@ -920,6 +928,26 @@

                                        每种格式接受的设置

                                        slides 1 - 500 幻灯片 + + rtf + characters + ascii, international + + + + text_encoding + both, codepage, literal, unicode + + + + elements + basic, every + + + + nesting + 0 - 10000000 + svg width diff --git a/web/public/zh-hans/index.html b/web/public/zh-hans/index.html index 90ace16c..aa47b9a8 100644 --- a/web/public/zh-hans/index.html +++ b/web/public/zh-hans/index.html @@ -4,7 +4,7 @@ -测试文件生成器 - 精确大小,30 种真实格式 +测试文件生成器 - 精确大小,31 种真实格式 @@ -33,7 +33,7 @@ - + @@ -62,7 +62,7 @@ - + @@ -76,7 +76,7 @@ "@type": "SoftwareApplication", "name": "Testing Files Generator", "alternateName": "tfg", - "description": "面向 QA 的免费开源测试文件生成器。它生成 30 种格式、大小精确的真实文件,并写出说明被测系统应如何响应每个文件的清单。", + "description": "面向 QA 的免费开源测试文件生成器。它生成 31 种格式、大小精确的真实文件,并写出说明被测系统应如何响应每个文件的清单。", "url": "https:\/\/testingfilesgenerator.donislawdev.com/", "applicationCategory": "DeveloperApplication", "applicationSubCategory": "Software Testing", @@ -157,7 +157,7 @@

                                        生成大小精确的真实测试文件

                                        - PDF、PNG、DOCX、ZIP,共 30 + PDF、PNG、DOCX、ZIP,共 31 种格式,每一种都是能在对应软件中打开的真实文件,大小恰好等于你的要求。每次运行还会写下你的应用应该如何处理每个文件。命令行加桌面窗口,免费开源,完全在你的机器上运行。

                                        @@ -177,7 +177,7 @@

                                        生成大小精确的真实测试文件

                                        • - 30 + 31

                                          种真实格式,每一种都能在对应软件中打开

                                        • @@ -332,7 +332,7 @@

                                          为无人值守的测试套件而生

                                          请求 10485761 字节,就得到恰好这么多。格式无法达到的大小会得到带原因的错误,绝不会得到大小错误的文件。

                                        • -

                                          30 种真实格式

                                          +

                                          31 种真实格式

                                          不是带扩展名的填充零。生成的 PNG 能在图片查看器中打开,DOCX 能在 Word 中打开,ZIP 能解压。每种格式在发布前都经过独立读取器验证。

                                        • diff --git a/web/public/zh-hans/presets/empty-and-minimal/index.html b/web/public/zh-hans/presets/empty-and-minimal/index.html index ae9a46e1..4afecd0f 100644 --- a/web/public/zh-hans/presets/empty-and-minimal/index.html +++ b/web/public/zh-hans/presets/empty-and-minimal/index.html @@ -5,7 +5,7 @@ 各格式最小的合法文件与空文件 - + @@ -34,7 +34,7 @@ - + @@ -63,7 +63,7 @@ - + @@ -177,10 +177,10 @@

                                          集合里有什么?

                                          - - - - + + + +
                                          文件数32
                                          其配方中的 target 数32
                                          总大小40 431 B
                                          格式avif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                                          文件数33
                                          其配方中的 target 数33
                                          总大小40 496 B
                                          格式avif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, rtf, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                                          @@ -191,7 +191,7 @@

                                          集合里有什么?

                                          预期含义文件数 - accept你的系统应该接受这个文件。30 + accept你的系统应该接受这个文件。31 unspecified取决于你的系统规则。由你决定,然后检查实际发生的是否符合你的本意。2 diff --git a/web/public/zh-hant/corrupt-test-files/index.html b/web/public/zh-hant/corrupt-test-files/index.html index ab36352b..d04ac828 100644 --- a/web/public/zh-hant/corrupt-test-files/index.html +++ b/web/public/zh-hant/corrupt-test-files/index.html @@ -189,7 +189,7 @@

                                          損毀的檔案仍然是你要求的大小

                                          tfg generate --format png --size 2mb --damage zero-head --out ./out
                                           tfg generate --format pdf --size 1mb --count 5 --damage zero-head:bytes=16 --out ./broken

                                          - 設定寫在冒號之後。該選項可以重複,損毀依你寫下的順序逐一套用。它適用於全部 30 種格式。 + 設定寫在冒號之後。該選項可以重複,損毀依你寫下的順序逐一套用。它適用於全部 31 種格式。

                                          diff --git a/web/public/zh-hant/faq/index.html b/web/public/zh-hant/faq/index.html index 9d00d874..7dfd7dce 100644 --- a/web/public/zh-hant/faq/index.html +++ b/web/public/zh-hant/faq/index.html @@ -204,7 +204,7 @@

                                          常見問題

                                          接下來會支援哪些格式?

                                          -

                                          7z 與 mp3。目前有 30 種格式可以端到端使用。

                                          +

                                          7z 與 mp3。目前有 31 種格式可以端到端使用。

                                          @@ -275,7 +275,7 @@

                                          常見問題

                                          { "@type": "Question", "name": "接下來會支援哪些格式?", - "acceptedAnswer": { "@type": "Answer", "text": "7z 與 mp3。目前有 30 種格式可以端到端使用。" } + "acceptedAnswer": { "@type": "Answer", "text": "7z 與 mp3。目前有 31 種格式可以端到端使用。" } }, { "@type": "Question", diff --git a/web/public/zh-hant/formats/index.html b/web/public/zh-hant/formats/index.html index 7af0b4aa..dec252a5 100644 --- a/web/public/zh-hant/formats/index.html +++ b/web/public/zh-hant/formats/index.html @@ -4,8 +4,8 @@ -30 種支援的檔案格式 - PDF、DOCX、PNG、ZIP 等 - +31 種支援的檔案格式 - PDF、DOCX、PNG、ZIP 等 + @@ -33,8 +33,8 @@ - - + + @@ -62,8 +62,8 @@ - - + + @@ -144,7 +144,7 @@
                                          -

                                          30 種檔案格式,每一種都以精確大小產生

                                          +

                                          31 種檔案格式,每一種都以精確大小產生

                                          它們每一個都是該格式的真實檔案。它能在對應軟體中開啟,位元組數恰好等於你的要求。沒有一個是黏上副檔名的填充零。

                                          @@ -306,6 +306,14 @@

                                          30 種檔案格式,每一種都以精確大小產生

                                          full libreoffice + + rtf + Rich Text Format + .rtf + 65 + full + pandoc-rtf + svg Scalable Vector Graphics @@ -920,6 +928,26 @@

                                          每種格式接受的設定

                                          slides 1 - 500 投影片 + + rtf + characters + ascii, international + + + + text_encoding + both, codepage, literal, unicode + + + + elements + basic, every + + + + nesting + 0 - 10000000 + svg width diff --git a/web/public/zh-hant/index.html b/web/public/zh-hant/index.html index f2e97648..eabb47c2 100644 --- a/web/public/zh-hant/index.html +++ b/web/public/zh-hant/index.html @@ -4,7 +4,7 @@ -測試檔案產生器 - 精確大小,30 種真實格式 +測試檔案產生器 - 精確大小,31 種真實格式 @@ -33,7 +33,7 @@ - + @@ -62,7 +62,7 @@ - + @@ -76,7 +76,7 @@ "@type": "SoftwareApplication", "name": "Testing Files Generator", "alternateName": "tfg", - "description": "專為 QA 設計的免費開源測試檔案產生器。它產生 30 種格式、大小精確的真實檔案,並寫出說明受測系統應如何回應每個檔案的清單。", + "description": "專為 QA 設計的免費開源測試檔案產生器。它產生 31 種格式、大小精確的真實檔案,並寫出說明受測系統應如何回應每個檔案的清單。", "url": "https:\/\/testingfilesgenerator.donislawdev.com/", "applicationCategory": "DeveloperApplication", "applicationSubCategory": "Software Testing", @@ -157,7 +157,7 @@

                                          產生大小精確的真實測試檔案

                                          - PDF、PNG、DOCX、ZIP,共 30 + PDF、PNG、DOCX、ZIP,共 31 種格式,每一種都是能在對應軟體中開啟的真實檔案,大小恰好等於你的要求。每次執行還會寫下你的應用程式應該如何處理每個檔案。命令列加桌面視窗,免費開源,完全在你的電腦上執行。

                                          @@ -177,7 +177,7 @@

                                          產生大小精確的真實測試檔案

                                          • - 30 + 31

                                            種真實格式,每一種都能在對應軟體中開啟

                                          • @@ -332,7 +332,7 @@

                                            為無人看管的測試套件而生

                                            要求 10485761 位元組,就得到恰好這麼多。格式無法達到的大小會得到附上原因的錯誤,絕不會得到大小錯誤的檔案。

                                          • -

                                            30 種真實格式

                                            +

                                            31 種真實格式

                                            不是帶副檔名的填充零。產生的 PNG 能在圖片檢視器中開啟,DOCX 能在 Word 中開啟,ZIP 能解壓縮。每種格式在發布前都經過獨立讀取器驗證。

                                          • diff --git a/web/public/zh-hant/presets/empty-and-minimal/index.html b/web/public/zh-hant/presets/empty-and-minimal/index.html index 6274f458..d36e0dd6 100644 --- a/web/public/zh-hant/presets/empty-and-minimal/index.html +++ b/web/public/zh-hant/presets/empty-and-minimal/index.html @@ -5,7 +5,7 @@ 各格式最小的合法檔案與空檔案 - + @@ -34,7 +34,7 @@ - + @@ -63,7 +63,7 @@ - + @@ -177,10 +177,10 @@

                                            組合裡有什麼?

                                            - - - - + + + +
                                            檔案數32
                                            其配方中的 target 數32
                                            總大小40 431 B
                                            格式avif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                                            檔案數33
                                            其配方中的 target 數33
                                            總大小40 496 B
                                            格式avif, bmp, csv, docx, eml, geojson, gif, html, ico, jpg, json, jxl, log, md, mp4, pdf, png, pptx, rtf, svg, targz, tiff, toml, txt, wav, webm, webp, xlsx, xml, yaml, zip
                                            @@ -191,7 +191,7 @@

                                            組合裡有什麼?

                                            預期意義檔案數 - accept你的系統應該接受這個檔案。30 + accept你的系統應該接受這個檔案。31 unspecified取決於你的系統規則。由你決定,然後檢查實際發生的是否符合你的本意。2 diff --git a/web/social-preview.sha256 b/web/social-preview.sha256 index 8c32e1c0..d48cc131 100644 --- a/web/social-preview.sha256 +++ b/web/social-preview.sha256 @@ -1 +1 @@ -a7706bfec4f2b97cebbc7bc3e3a40dd188b0279f46a94564730973300a61c772 +5b18d0390a6e9f32c54a3cff95460e702253aa438be1574f302ffae348498549