Development #121
Merged
Development #121
GitHub Actions / Unit Tests
succeeded
Feb 24, 2026 in 1s
288 passed, 0 failed and 0 skipped
✅ test-results.json
288 tests were completed in 52s with 288 passed, 0 failed and 0 skipped.
| Test suite | Passed | Failed | Skipped | Time |
|---|---|---|---|---|
| test/alerts_test.dart | 3✅ | 630ms | ||
| test/color_test.dart | 32✅ | 80ms | ||
| test/colorblind_filter_test.dart | 38✅ | 88ms | ||
| test/datetime_extension_test.dart | 3✅ | 25ms | ||
| test/datetime_test.dart | 26✅ | 78ms | ||
| test/duration_test.dart | 12✅ | 47ms | ||
| test/file_utilities_test.dart | 25✅ | 72ms | ||
| test/grid_test.dart | 7✅ | 38ms | ||
| test/helpers_test.dart | 14✅ | 57ms | ||
| test/orm_test.dart | 21✅ | 53ms | ||
| test/password_input_test.dart | 7✅ | 1s | ||
| test/separator_extension_test.dart | 24✅ | 59ms | ||
| test/table_controller_test.dart | 9✅ | 39ms | ||
| test/theme_color_test.dart | 26✅ | 62ms | ||
| test/widgets/alerts_test.dart | 3✅ | 592ms | ||
| test/widgets/avatar_test.dart | 18✅ | 979ms | ||
| test/widgets/button_test.dart | 7✅ | 1s | ||
| test/widgets/chip_test.dart | 2✅ | 519ms | ||
| test/widgets/field_error_test.dart | 8✅ | 697ms | ||
| test/widgets/layo_test.dart | 3✅ | 714ms |
✅ test/alerts_test.dart
ThemedAlert widget
✅ renders info alert
✅ renders success alert
✅ renders custom alert with icon and color
✅ test/color_test.dart
toHex()
✅ converts black to #000000
✅ converts white to #FFFFFF
✅ converts kAccentColor (#FF8200)
✅ converts kPrimaryColor (#001e60)
✅ outputs uppercase hex
✅ ignores alpha channel
✅ hex getter is alias for toHex()
toHexWithAlpha()
✅ includes full alpha (#FFFFFFFF for white)
✅ includes zero alpha (#00000000 for transparent)
✅ includes partial alpha (#80FF8200)
✅ alpha comes first in AARRGGBB format
✅ hexWithAlpha getter is alias for toHexWithAlpha()
toInt()
✅ converts to ARGB integer
✅ handles alpha channel correctly
✅ black is 0xFF000000
✅ white is 0xFFFFFFFF
✅ transparent is 0x00000000
fromHex()
✅ parses black #000000
✅ parses white #FFFFFF
✅ parses accent color #FF8200
✅ parses primary color #001E60
✅ parses lowercase hex #ff8200
✅ sets alpha to 255 (fully opaque)
fromHexWithAlpha()
✅ parses full alpha #FFFFFFFF
✅ parses zero alpha #00000000
✅ parses partial alpha #80FF8200
✅ parses alpha first in AARRGGBB format
Round-trip conversions
✅ Color -> toHex() -> fromHex() -> Color preserves RGB
✅ Color -> toHexWithAlpha() -> fromHexWithAlpha() -> Color preserves ARGB
✅ Color -> toInt() -> Color() preserves exact value
JSON aliases
✅ toJson() is equivalent to toHex()
✅ fromJson() is equivalent to fromHex()
✅ test/colorblind_filter_test.dart
protanopiaFilter()
✅ strength 0.0 returns identity matrix
✅ strength 1.0 returns full filter matrix
✅ strength 0.5 returns interpolated matrix
✅ has exactly 20 elements
✅ handles boundary strength values
protanomalyFilter()
✅ strength 0.0 returns identity matrix
✅ strength 1.0 returns full filter matrix
✅ strength 0.5 returns interpolated matrix
✅ has exactly 20 elements
deuteranopiaFilter()
✅ strength 0.0 returns identity matrix
✅ strength 1.0 returns full filter matrix
✅ strength 0.5 returns interpolated matrix
✅ has exactly 20 elements
deuteranomalyFilter()
✅ strength 0.0 returns identity matrix
✅ strength 1.0 returns full filter matrix
✅ strength 0.5 returns interpolated matrix
✅ has exactly 20 elements
tritanopiaFilter()
✅ strength 0.0 returns identity matrix
✅ strength 1.0 returns full filter matrix
✅ strength 0.5 returns interpolated matrix
✅ has exactly 20 elements
tritanomalyFilter()
✅ strength 0.0 returns identity matrix
✅ strength 1.0 returns full filter matrix
✅ strength 0.5 returns interpolated matrix
✅ has exactly 20 elements
ColorblindFilter extension
✅ normal mode returns identity matrix
✅ protanopia mode creates ColorFilter from protanopia matrix
✅ protanomaly mode creates ColorFilter from protanomaly matrix
✅ deuteranopia mode creates ColorFilter from deuteranopia matrix
✅ deuteranomaly mode creates ColorFilter from deuteranomaly matrix
✅ tritanopia mode creates ColorFilter from tritanopia matrix
✅ tritanomaly mode creates ColorFilter from tritanomaly matrix
✅ all modes accept strength parameter
Matrix interpolation behavior
✅ increasing strength gradually changes matrix values
✅ all filters preserve alpha channel (elements 15-19)
Edge cases
✅ negative strength handled (treated as 0 or clamped)
✅ strength > 1.0 handled (extrapolates or clamped)
✅ all filters produce distinct matrices at full strength
✅ test/datetime_extension_test.dart
DateTimeExtension
✅ secondsSinceEpoch returns correct value
✅ thisWeek and lastWeek return correct dates
✅ thisMonth and lastMonth return correct dates
✅ test/datetime_test.dart
thisWeek / lastWeek
✅ returns correct week boundaries
✅ handles Monday correctly
✅ handles Sunday correctly
thisMonth / lastMonth
✅ returns correct month boundaries for August
✅ returns correct lastMonth boundaries
✅ handles February in leap year
✅ handles February in non-leap year
✅ handles January lastMonth wraps to previous year
secondsSinceEpoch
✅ converts milliseconds to seconds
✅ handles epoch zero
format
✅ %Y full year
✅ %y two-digit year
✅ %m zero-padded month
✅ %d zero-padded day
✅ %H 24-hour format
✅ %I 12-hour format
✅ %p AM/PM indicator
✅ %M zero-padded minute
✅ %S zero-padded second
✅ %A full weekday name
✅ %a abbreviated weekday name
✅ %B full month name
✅ %b abbreviated month name
✅ %% literal percent
✅ combined pattern
✅ %I shows 12 for noon/midnight
✅ test/duration_test.dart
Duration.humanize
✅ single unit
✅ singular unit
✅ two units joined with conjunction
✅ three units with delimiter and conjunction
✅ zero duration returns smallest unit with 0
✅ negative duration uses absolute value
✅ filters out zero-value units
✅ lastPrefixComma adds comma before conjunction
✅ custom delimiter
✅ custom units subset
✅ zero duration with seconds in units
✅ large duration includes days and months
✅ test/file_utilities_test.dart
ThemedFile
✅ creates file with name and bytes
✅ creates file with optional path
✅ toString() includes name and size
ThemedFile.mimeType
✅ detects PNG image
✅ detects JPG image
✅ detects JPEG image
✅ detects GIF image
✅ detects SVG image
✅ detects PDF document
✅ detects custom .lc extension
✅ uses path over name when both provided
✅ handles unknown extension
✅ case insensitive extension detection
parseFileToBase64()
✅ converts bytes to base64
✅ includes file name in result
✅ includes mime type in result
✅ returns null when mime type cannot be determined
✅ handles empty file
✅ round-trip base64 encoding/decoding
parseFileToByteArray()
✅ returns file bytes as List<int>
✅ handles empty file
✅ preserves byte values
✅ returns a copy (new list)
globalMimeResolver
✅ includes custom .lc extension
✅ still supports standard extensions
✅ test/grid_test.dart
Sizes.gridSize
✅ each enum returns correct column count
Sizes.boxWidth
✅ col12 returns full width
✅ col6 returns half width
✅ col4 returns one-third width
✅ col3 returns one-quarter width
✅ col1 returns 1/12 of width
✅ formula is (width / 12) * gridSize
✅ test/helpers_test.dart
useBlack
✅ returns true for white (high luminance)
✅ returns false for black (low luminance)
✅ returns true for yellow (high luminance)
✅ returns false for dark blue (low luminance)
✅ respects custom tolerance
validateColor
✅ returns black for light colors
✅ returns white for dark colors
getPrimaryColor
✅ returns kPrimaryColor when null
✅ returns provided color when non-null
getAccentColor
✅ returns kAccentColor when null
✅ returns provided color when non-null
generateSwatch
✅ without shader all shades are the same color
✅ with shader shades have increasing alpha
✅ swatch has all 10 shade levels
✅ test/orm_test.dart
setErrors() and getErrors()
✅ stores and retrieves errors correctly
✅ retrieves empty list for non-existent key
✅ handles multiple errors for same key
✅ replaces existing errors when setErrors called again
hasErrors()
✅ returns true when key has errors
✅ returns false when key has no errors
✅ returns false for non-existent key
hasContainerErrors()
✅ returns true when any key starts with prefix
✅ returns false when no keys match prefix
✅ exact match works as prefix
✅ returns false when errors map is empty
Error code handling without i18n
✅ returns error code as fallback when no i18n set
✅ minLength error includes parameters in fallback
✅ maxLength error includes parameters in fallback
✅ minLength with multiple parameters in fallback
Multiple error codes
✅ handles mix of standard and length errors
Raw errors access
✅ rawErrors returns the internal error map
✅ rawErrors is empty after setting empty map
Edge cases
✅ handles empty error list for key
✅ handles error with empty code
✅ handles special characters in error keys
✅ test/password_input_test.dart
ThemedPasswordInput
✅ renders with label
✅ toggles password visibility on eye icon tap
✅ shows shield check icon for valid password
✅ shows close circle icon for invalid password
✅ shows close circle icon for empty password
✅ hides strength indicator when showLevels is false
✅ calls onChanged when text is entered
✅ test/separator_extension_test.dart
num.w (width)
✅ creates SizedBox with width
✅ handles integer values
✅ handles double values
✅ handles zero
✅ width alias is equivalent to w
num.h (height)
✅ creates SizedBox with height
✅ handles integer values
✅ handles double values
✅ handles zero
✅ height alias is equivalent to h
num.wh (square)
✅ creates SizedBox with equal width and height
✅ handles integer values
✅ handles double values
✅ handles zero
✅ square alias is equivalent to wh
Different num types
✅ works with int
✅ works with double
✅ works with num variable
Edge cases
✅ handles very small values
✅ handles very large values
✅ handles negative values (though unusual in UI)
Common usage patterns
✅ can be used for spacing between widgets
✅ can create responsive spacing
✅ can create square placeholders
✅ test/table_controller_test.dart
ThemedTable2Controller
✅ addListener adds listener to list
✅ removeListener removes specific listener
✅ clearListeners removes all listeners
✅ sort triggers ThemedTable2SortEvent with correct parameters
✅ sort with default parameters
✅ refresh triggers ThemedTable2RefreshEvent
✅ multiple listeners all receive events
✅ dispose clears all listeners
✅ events fire in order listeners were added
✅ test/theme_color_test.dart
getThemeColor() - Predefined themes
✅ PINK returns Colors.pink
✅ RED returns Colors.red
✅ DEEPORANGE returns Colors.deepOrange
✅ ORANGE returns Colors.orange
✅ AMBER returns Colors.amber
✅ YELLOW returns Colors.yellow
✅ LIME returns Colors.lime
✅ LIGHTGREEN returns Colors.lightGreen
✅ GREEN returns Colors.green
✅ TEAL returns Colors.teal
✅ CYAN returns Colors.cyan
✅ LIGHTBLUE returns Colors.lightBlue
✅ BLUE returns Colors.blue
✅ INDIGO returns Colors.indigo
✅ DEEPBLUE returns Colors.deepPurple
✅ PURPLE returns Colors.purple
✅ BLUEGREY returns Colors.blueGrey
✅ GREY returns Colors.grey
✅ BROWN returns Colors.brown
getThemeColor() - CUSTOM theme
✅ CUSTOM with provided color generates swatch from that color
✅ CUSTOM without explicit color uses kPrimaryColor
getThemeColor() - Invalid/default handling
✅ Invalid theme returns swatch from kPrimaryColor
✅ Empty string theme returns swatch from kPrimaryColor
✅ Lowercase theme name does not match (case-sensitive)
getThemeColor() - Return type validation
✅ All valid themes return MaterialColor type
✅ MaterialColor has all required shades (50-900)
✅ test/widgets/alerts_test.dart
ThemedAlert widget
✅ renders info alert
✅ renders success alert
✅ renders custom alert with icon and color
✅ test/widgets/avatar_test.dart
ThemedAvatar - Basic rendering
✅ renders with default size
✅ renders with custom size
✅ renders fallback initials when no avatar provided
✅ renders NA when name is null
ThemedAvatar - Icon rendering
✅ renders icon when provided
✅ icon size is 70% of avatar size by default
✅ respects custom icon size
ThemedAvatar - Name cleaning
✅ cleans special characters from name
✅ handles single character name
✅ returns NA for name with only special characters
✅ takes first 2 characters and uppercases
ThemedAvatar - Tap handlers
✅ calls onTap when tapped
✅ calls onLongTap when long pressed
✅ calls onSecondaryTap when secondary tapped
ThemedAvatar - Elevation and styling
✅ applies custom color
✅ elevation must be between 0 and 5
✅ radius must be greater than or equal to 0
ThemedAvatar - Priority order
✅ icon takes priority over name fallback
✅ test/widgets/button_test.dart
ThemedButton widget
✅ renders with labelText
✅ renders with icon
✅ renders as disabled
✅ renders loading state
✅ renders with custom color
✅ renders with different styles
✅ renders with factory constructors
✅ test/widgets/chip_test.dart
ThemedChip widget
✅ renders with label
✅ renders with custom color
✅ test/widgets/field_error_test.dart
ThemedFieldDisplayError
✅ displays single error message
✅ displays multiple errors joined by comma
✅ hides errors when hideDetails is true
✅ shows nothing when errors list is empty
✅ applies custom padding
✅ applies maxLines constraint
✅ error text is red
✅ default maxLines is 1
✅ test/widgets/layo_test.dart
Layo widget
✅ throws assertion error for invalid elevation
✅ renders with default values
✅ renders with custom emotion
Loading