Skip to content

feat: enhance ThemedTable2 with widget tests and performance improvem…

85d103a
Select commit
Loading
Failed to load commit list.
Sign in for the full log view
Merged

Enhance ThemedTable2 with performance improvements and tests #128

feat: enhance ThemedTable2 with widget tests and performance improvem…
85d103a
Select commit
Loading
Failed to load commit list.
GitHub Actions / Unit Tests succeeded Mar 28, 2026 in 0s

301 passed, 0 failed and 0 skipped

Tests passed successfully

✅ test-results.json

301 tests were completed in 62s with 301 passed, 0 failed and 0 skipped.

Test suite Passed Failed Skipped Time
test/alerts_test.dart 3✅ 775ms
test/color_test.dart 32✅ 103ms
test/colorblind_filter_test.dart 38✅ 102ms
test/datetime_extension_test.dart 3✅ 32ms
test/datetime_test.dart 26✅ 84ms
test/duration_test.dart 12✅ 56ms
test/file_utilities_test.dart 25✅ 98ms
test/grid_test.dart 7✅ 33ms
test/helpers_test.dart 14✅ 64ms
test/orm_test.dart 21✅ 64ms
test/password_input_test.dart 7✅ 1s
test/separator_extension_test.dart 24✅ 71ms
test/table_controller_test.dart 9✅ 40ms
test/theme_color_test.dart 26✅ 98ms
test/widgets/alerts_test.dart 3✅ 670ms
test/widgets/avatar_test.dart 18✅ 1s
test/widgets/button_test.dart 7✅ 1s
test/widgets/chip_test.dart 2✅ 559ms
test/widgets/field_error_test.dart 8✅ 577ms
test/widgets/layo_test.dart 3✅ 649ms
test/widgets/table2_test.dart 13✅ 15s

✅ 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

✅ test/widgets/table2_test.dart

ThemedTable2 rendering
  ✅ renders item values after compute completes
  ✅ shows CircularProgressIndicator while loading
  ✅ renders without errors when items is empty
ThemedTable2 column key collision regression
  ✅ two columns with identical headerText show distinct data
ThemedTable2 search
  ✅ filters items matching the query
  ✅ search matches values from all columns
  ✅ shows all items when search is cleared
ThemedTable2 sort
  ✅ controller.sort ascending orders items A→Z
  ✅ controller.sort descending orders items Z→A
  ✅ numeric values sort as numbers not as strings
  ✅ controller.refresh re-runs sort without changing order
ThemedTable2 didUpdateWidget
  ✅ reflects new items when widget rebuilds with a different list
  ✅ handles growing list without losing existing rows