|
| 1 | +package guard |
| 2 | + |
| 3 | +import ( |
| 4 | + "reflect" |
| 5 | + "testing" |
| 6 | + |
| 7 | + "github.com/donislawdev/TestingFilesGenerator/internal/format" |
| 8 | + _ "github.com/donislawdev/TestingFilesGenerator/internal/format/all" |
| 9 | + "github.com/donislawdev/TestingFilesGenerator/internal/format/imagedim" |
| 10 | + "github.com/donislawdev/TestingFilesGenerator/internal/format/textenc" |
| 11 | +) |
| 12 | + |
| 13 | +// Two families of formats share a declaration through a package, and this is |
| 14 | +// what stops a member writing its own copy instead. |
| 15 | +// |
| 16 | +// The containers have had this since 2026-09-01 - archiveaxes_test.go compares |
| 17 | +// every axis a container offers against the one archive declares. The other two |
| 18 | +// families had nothing, and the gap was measured rather than suspected. On |
| 19 | +// 2026-09-09 md was given a declaration of its own that agreed on kind, unit |
| 20 | +// and default and offered one encoding fewer, and bmp was given one whose width |
| 21 | +// started at zero. ELEVEN guards stayed green on the first and TEN on the |
| 22 | +// second, including the ones that look closest: TestOneSettingNameMeansOneKind |
| 23 | +// OfSetting asks only about Kind and Unit, and the README and format-document |
| 24 | +// guards compare the prose against whatever the registry happens to say. |
| 25 | +// |
| 26 | +// What each of the two ran into is different, and both are worth naming: |
| 27 | +// |
| 28 | +// - md kept writing utf-16be perfectly well and stopped OFFERING it, so txt |
| 29 | +// and xml answered one question and md answered another. |
| 30 | +// - bmp printed "whole number of pixels from 0 to 20000" and refused width=0 |
| 31 | +// with "it has to be between 1 and 20000". The declaration contradicted the |
| 32 | +// program, and what caught it was the backstop in imagedim.Value - the one |
| 33 | +// picturesides_test.go says a person cannot reach. A person reaches it |
| 34 | +// exactly when a declaration drifts, which is the case with no guard. |
| 35 | +// |
| 36 | +// Both guards skip a name listed in deliberateHomonyms, so the one list this |
| 37 | +// package already keeps stays the one place a shared name can be excused. A |
| 38 | +// second list of excuses beside it would be a second place to look away from. |
| 39 | +// |
| 40 | +// The cost of sharing that list is worth stating rather than leaving to be |
| 41 | +// found: an entry there turns the name off for EVERY format, not only for the |
| 42 | +// one it excuses, so writing "encoding" into it would silence half of the first |
| 43 | +// guard. That is a deliberate act and a visible one - the entry is in the diff, |
| 44 | +// and TestEveryDeliberateHomonymStillNamesTwoMeanings makes it prove that two |
| 45 | +// formats really do mean different things by the name - but it is a door, and |
| 46 | +// archiveaxes_test.go has none because it keeps no list at all. Narrowing the |
| 47 | +// skip to the one format that earned it would mean changing the shape of |
| 48 | +// deliberateHomonyms, which is another guard's, so it is written down here |
| 49 | +// instead of done quietly. |
| 50 | + |
| 51 | +// Every text format declares the encoding settings the way textenc declares |
| 52 | +// them. |
| 53 | +// |
| 54 | +// Asked by name against textenc.Names(), so a third axis added to that package |
| 55 | +// is covered on the day it arrives rather than the day somebody remembers this |
| 56 | +// file. A format is free not to carry an axis at all - that is what |
| 57 | +// textenc.Axes narrows, and HTML is the named case, since its specification |
| 58 | +// leaves it no encoding to choose and only the mark to declare. What is |
| 59 | +// refused is carrying one and describing it differently. |
| 60 | +func TestEveryTextFormatDeclaresTheEncodingSettingsAsTheyAreDeclaredOnce(t *testing.T) { |
| 61 | + compared := 0 |
| 62 | + for _, d := range format.All() { |
| 63 | + declared := byName(d.Properties) |
| 64 | + for _, axis := range textenc.Names() { |
| 65 | + if _, excused := deliberateHomonyms[axis]; excused { |
| 66 | + continue |
| 67 | + } |
| 68 | + p, offered := declared[axis] |
| 69 | + if !offered { |
| 70 | + continue |
| 71 | + } |
| 72 | + compared++ |
| 73 | + want := textenc.Axes(axis)[0] |
| 74 | + if !reflect.DeepEqual(p, want) { |
| 75 | + t.Errorf("%s declares %q its own way rather than the way textenc declares it\n"+ |
| 76 | + " format: %+v\n"+ |
| 77 | + " shared: %+v", |
| 78 | + d.ID, axis, p, want) |
| 79 | + } |
| 80 | + } |
| 81 | + } |
| 82 | + |
| 83 | + if compared == 0 { |
| 84 | + t.Fatal("no format declares a text encoding setting, so this proved nothing") |
| 85 | + } |
| 86 | + t.Logf("%d text encoding declaration(s) compared against the one definition", compared) |
| 87 | +} |
| 88 | + |
| 89 | +// Every picture format declares its sides the way imagedim would build them. |
| 90 | +// |
| 91 | +// This one cannot be a straight comparison, because three of the fields are the |
| 92 | +// format's own and are SUPPOSED to differ: the largest side is the ceiling of |
| 93 | +// the thing itself, the default is declared by SVG alone, and the sentence is |
| 94 | +// per format on purpose - four of the ten are correctly different, and a shared |
| 95 | +// one would have made three of them wrong. |
| 96 | +// |
| 97 | +// So it asks the question the other way round: rebuild the declaration from the |
| 98 | +// parts a format supplies and require the result to be what is registered. |
| 99 | +// Whatever the format did NOT supply - the name, that it is a whole number, |
| 100 | +// that the smallest side is one pixel, that the number counts pixels - has to |
| 101 | +// come out of the package, and anything a format added by hand shows up as a |
| 102 | +// difference. That covers a field nobody has thought of yet, which a list of |
| 103 | +// four field comparisons would not. |
| 104 | +func TestEveryPictureFormatDeclaresItsSidesAsTheImageDimensionPackageWould(t *testing.T) { |
| 105 | + rebuild := map[string]func(imagedim.Side) format.Property{ |
| 106 | + imagedim.SettingWidth: imagedim.Width, |
| 107 | + imagedim.SettingHeight: imagedim.Height, |
| 108 | + } |
| 109 | + |
| 110 | + compared := 0 |
| 111 | + for _, d := range format.All() { |
| 112 | + for _, p := range d.Properties { |
| 113 | + build, isSide := rebuild[p.Name] |
| 114 | + if !isSide { |
| 115 | + continue |
| 116 | + } |
| 117 | + if _, excused := deliberateHomonyms[p.Name]; excused { |
| 118 | + continue |
| 119 | + } |
| 120 | + compared++ |
| 121 | + want := build(imagedim.Side{Largest: p.Max, Default: p.Default, Detail: p.Detail}) |
| 122 | + if !reflect.DeepEqual(p, want) { |
| 123 | + t.Errorf("%s declares %q its own way rather than through imagedim\n"+ |
| 124 | + " format: %+v\n"+ |
| 125 | + " the package: %+v", |
| 126 | + d.ID, p.Name, p, want) |
| 127 | + } |
| 128 | + } |
| 129 | + } |
| 130 | + |
| 131 | + if compared == 0 { |
| 132 | + t.Fatal("no format declares a picture side, so this proved nothing") |
| 133 | + } |
| 134 | + t.Logf("%d picture side declaration(s) rebuilt from what the format supplies", compared) |
| 135 | +} |
0 commit comments