import assert from 'node:assert/strict';
import test from 'node:test';
import { iosRules } from './ios';

test('iosRules define reglas heurísticas locked para plataforma ios', () => {
  assert.equal(iosRules.length, 137);

  const ids = iosRules.map((rule) => rule.id);
  assert.deepEqual(ids, [
    'heuristics.ios.force-unwrap.ast',
    'heuristics.ios.anyview.ast',
    'heuristics.ios.type-erasure.any.ast',
    'heuristics.ios.force-try.ast',
    'heuristics.ios.force-cast.ast',
    'heuristics.ios.callback-style.ast',
    'heuristics.ios.combine.sink-without-store.ast',
    'heuristics.ios.dispatchqueue.ast',
    'heuristics.ios.dispatchgroup.ast',
    'heuristics.ios.dispatchsemaphore.ast',
    'heuristics.ios.operation-queue.ast',
    'heuristics.ios.task-detached.ast',
    'heuristics.ios.concurrency.long-task-without-cancellation-check.ast',
    'heuristics.ios.concurrency.async-without-await.ast',
    'heuristics.ios.concurrency.dummy-await.ast',
    'heuristics.ios.error.empty-catch.ast',
    'heuristics.ios.error.nserror-throw.ast',
    'heuristics.ios.networking.endpoint-enum-ocp.ast',
    'heuristics.ios.swiftui.onappear-task.ast',
    'heuristics.ios.swiftui.onchange-task.ast',
    'heuristics.ios.swiftui.onchange-readonly-var.ast',
    'heuristics.ios.memory.strong-delegate.ast',
    'heuristics.ios.architecture.cross-feature-import.ast',
    'heuristics.ios.architecture.layer-direction-violation.ast',
    'heuristics.ios.architecture.excessive-public-api.ast',
    'heuristics.ios.memory.strong-self-escaping-closure.ast',
    'heuristics.ios.memory.unowned-self-capture.ast',
    'heuristics.ios.memory.manual-management.ast',
    'heuristics.ios.testing.makesut-without-memory-tracking.ast',
    'heuristics.ios.testing.direct-sut-instantiation-without-makesut.ast',
    'heuristics.ios.maintainability.nested-if-pyramid.ast',
    'heuristics.ios.maintainability.comment-trivia.ast',
    'heuristics.ios.maintainability.warning-suppression.ast',
    'heuristics.ios.architecture.custom-singleton.ast',
    'heuristics.ios.architecture.swinject.ast',
    'heuristics.ios.architecture.tca-composable-architecture.ast',
    'heuristics.ios.architecture.massive-view-controller.ast',
    'heuristics.ios.maintainability.magic-number-layout.ast',
    'heuristics.ios.uikit.manual-frame-layout.ast',
    'heuristics.ios.safety.non-iboutlet-iuo.ast',
    'heuristics.ios.logging.adhoc-print.ast',
    'heuristics.ios.logging.sensitive-data.ast',
    'heuristics.ios.security.hardcoded-sensitive-string.ast',
    'heuristics.ios.localization.unlocalized-dateformatter.ast',
    'heuristics.ios.networking.alamofire.ast',
    'heuristics.ios.json.jsonserialization.ast',
    'heuristics.ios.dependencies.cocoapods.ast',
    'heuristics.ios.dependencies.carthage.ast',
    'heuristics.ios.dependencies.swiftpm-branch-dependency.ast',
    'heuristics.ios.dependencies.swift-tools-version-below-6-2.ast',
    'heuristics.ios.concurrency.swiftpm-default-isolation-not-mainactor.ast',
    'heuristics.ios.concurrency.swiftpm-strict-concurrency-below-complete.ast',
    'heuristics.ios.concurrency.strict-concurrency-below-complete.ast',
    'heuristics.ios.concurrency.default-actor-isolation-not-mainactor.ast',
    'heuristics.ios.concurrency.upcoming-feature-disabled.ast',
    'heuristics.ios.concurrency.ui-state-without-mainactor.ast',
    'heuristics.ios.concurrency.shared-mutable-state-without-actor.ast',
    'heuristics.ios.concurrency.mainactor-run-patch.ast',
    'heuristics.ios.naming.non-pascal-case-type.ast',
    'heuristics.ios.uikit.cell-without-reuse.ast',
    'heuristics.ios.security.userdefaults-sensitive-data.ast',
    'heuristics.ios.security.insecure-transport.ast',
    'heuristics.ios.security.urlsession-trust-bypass.ast',
    'heuristics.ios.localization.localizable-strings.ast',
    'heuristics.ios.interface-builder.storyboard-xib.ast',
    'heuristics.ios.localization.hardcoded-ui-string.ast',
    'heuristics.ios.assets.loose-resource.ast',
    'heuristics.ios.accessibility.fixed-font-size.ast',
    'heuristics.ios.localization.physical-text-alignment.ast',
    'heuristics.ios.performance.blocking-sleep.ast',
    'heuristics.ios.concurrency.thread-centric-debugging.ast',
    'heuristics.ios.accessibility.icon-only-control-label.ast',
    'heuristics.ios.accessibility.missing-accessibility-identifier.ast',
    'heuristics.ios.swiftui.missing-bindable-observable-binding.ast',
    'heuristics.ios.unchecked-sendable.ast',
    'heuristics.ios.preconcurrency.ast',
    'heuristics.ios.nonisolated-unsafe.ast',
    'heuristics.ios.assume-isolated.ast',
    'heuristics.ios.observable-object.ast',
    'heuristics.ios.swiftui.legacy-preview-provider.ast',
    'heuristics.ios.legacy-swiftui-observable-wrapper.ast',
    'heuristics.ios.swiftui.environment-object.ast',
    'heuristics.ios.testing.test-double-without-protocol.ast',
    'heuristics.ios.testing.production-test-double.ast',
    'heuristics.ios.accessibility.low-contrast-static-color-pair.ast',
    'heuristics.ios.swiftui.non-private-state-ownership.ast',
    'heuristics.ios.passed-value-state-wrapper.ast',
    'heuristics.ios.foreach-indices.ast',
    'heuristics.ios.swiftui.foreach-self-identity.ast',
    'heuristics.ios.swiftui.inline-foreach-transform.ast',
    'heuristics.ios.swiftui.self-print-changes.ast',
    'heuristics.ios.swiftui.foreach-conditional-view-count.ast',
    'heuristics.ios.contains-user-filter.ast',
    'heuristics.ios.geometryreader.ast',
    'heuristics.ios.font-weight-bold.ast',
    'heuristics.ios.swiftui.explicit-color-static-member.ast',
    'heuristics.ios.swiftui.closure-based-viewbuilder-content.ast',
    'heuristics.ios.swiftui.large-config-context-prop.ast',
    'heuristics.ios.swiftui.conditional-same-view-identity.ast',
    'heuristics.ios.swiftui.parent-owned-sheet-action.ast',
    'heuristics.ios.swiftui.redundant-reactive-state-assignment.ast',
    'heuristics.ios.swiftui.non-lazy-scroll-foreach.ast',
    'heuristics.ios.swiftui.body-object-creation.ast',
    'heuristics.ios.swiftui.image-data-decoding.ast',
    'heuristics.ios.swiftui.manual-rendering-without-imagerenderer.ast',
    'heuristics.ios.swiftui.large-viewbuilder-function.ast',
    'heuristics.ios.accessibility.animation-without-reduce-motion.ast',
    'heuristics.ios.swiftui.inline-action-logic.ast',
    'heuristics.ios.navigation-view.ast',
    'heuristics.ios.navigation.path-without-restoration.ast',
    'heuristics.ios.swiftui.untyped-navigation-link-destination.ast',
    'heuristics.ios.foreground-color.ast',
    'heuristics.ios.corner-radius.ast',
    'heuristics.ios.tab-item.ast',
    'heuristics.ios.on-tap-gesture.ast',
    'heuristics.ios.accessibility.on-tap-without-button-trait.ast',
    'heuristics.ios.swiftui.glass-interactive-static-element.ast',
    'heuristics.ios.swiftui.glasseffectid-without-namespace.ast',
    'heuristics.ios.string-format.ast',
    'heuristics.ios.scrollview-shows-indicators.ast',
    'heuristics.ios.sheet-is-presented.ast',
    'heuristics.ios.legacy-onchange.ast',
    'heuristics.ios.uiscreen-main-bounds.ast',
    'heuristics.ios.testing.xctest-import.ast',
    'heuristics.ios.testing.xctest-suite-modernizable.ast',
    'heuristics.ios.testing.xctassert.ast',
    'heuristics.ios.testing.xctunwrap.ast',
    'heuristics.ios.testing.wait-for-expectations.ast',
    'heuristics.ios.testing.legacy-expectation-description.ast',
    'heuristics.ios.testing.mixed-frameworks.ast',
    'heuristics.ios.testing.quick-nimble.ast',
    'heuristics.ios.testing.third-party-ui-test-framework.ast',
    'heuristics.ios.core-data.nsmanagedobject-boundary.ast',
    'heuristics.ios.core-data.nsmanagedobject-async-boundary.ast',
    'heuristics.ios.core-data.layer-leak.ast',
    'heuristics.ios.swiftdata.layer-leak.ast',
    'heuristics.ios.core-data.nsmanagedobject-state-leak.ast',
  ]);

  const byId = new Map(iosRules.map((rule) => [rule.id, rule]));
  assert.equal(
    byId.get('heuristics.ios.force-unwrap.ast')?.then.code,
    'HEURISTICS_IOS_FORCE_UNWRAP_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.type-erasure.any.ast')?.then.code,
    'HEURISTICS_IOS_TYPE_ERASURE_ANY_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.task-detached.ast')?.then.code,
    'HEURISTICS_IOS_TASK_DETACHED_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.concurrency.long-task-without-cancellation-check.ast')?.then.code,
    'HEURISTICS_IOS_CONCURRENCY_LONG_TASK_WITHOUT_CANCELLATION_CHECK_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.concurrency.async-without-await.ast')?.then.code,
    'HEURISTICS_IOS_CONCURRENCY_ASYNC_WITHOUT_AWAIT_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.concurrency.dummy-await.ast')?.then.code,
    'HEURISTICS_IOS_CONCURRENCY_DUMMY_AWAIT_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.error.empty-catch.ast')?.then.code,
    'HEURISTICS_IOS_ERROR_EMPTY_CATCH_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.combine.sink-without-store.ast')?.then.code,
    'HEURISTICS_IOS_COMBINE_SINK_WITHOUT_STORE_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.memory.unowned-self-capture.ast')?.then.code,
    'HEURISTICS_IOS_MEMORY_UNOWNED_SELF_CAPTURE_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.memory.manual-management.ast')?.then.code,
    'HEURISTICS_IOS_MEMORY_MANUAL_MANAGEMENT_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.dependencies.swift-tools-version-below-6-2.ast')?.then.code,
    'HEURISTICS_IOS_DEPENDENCIES_SWIFT_TOOLS_VERSION_BELOW_6_2_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.concurrency.swiftpm-default-isolation-not-mainactor.ast')?.then.code,
    'HEURISTICS_IOS_CONCURRENCY_SWIFTPM_DEFAULT_ISOLATION_NOT_MAINACTOR_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.concurrency.swiftpm-strict-concurrency-below-complete.ast')?.then.code,
    'HEURISTICS_IOS_CONCURRENCY_SWIFTPM_STRICT_CONCURRENCY_BELOW_COMPLETE_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.concurrency.strict-concurrency-below-complete.ast')?.then.code,
    'HEURISTICS_IOS_CONCURRENCY_STRICT_CONCURRENCY_BELOW_COMPLETE_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.concurrency.default-actor-isolation-not-mainactor.ast')?.then.code,
    'HEURISTICS_IOS_CONCURRENCY_DEFAULT_ACTOR_ISOLATION_NOT_MAINACTOR_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.concurrency.upcoming-feature-disabled.ast')?.then.code,
    'HEURISTICS_IOS_CONCURRENCY_UPCOMING_FEATURE_DISABLED_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.concurrency.ui-state-without-mainactor.ast')?.then.code,
    'HEURISTICS_IOS_CONCURRENCY_UI_STATE_WITHOUT_MAINACTOR_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.concurrency.shared-mutable-state-without-actor.ast')?.then.code,
    'HEURISTICS_IOS_CONCURRENCY_SHARED_MUTABLE_STATE_WITHOUT_ACTOR_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.concurrency.mainactor-run-patch.ast')?.then.code,
    'HEURISTICS_IOS_CONCURRENCY_MAINACTOR_RUN_PATCH_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.architecture.cross-feature-import.ast')?.then.code,
    'HEURISTICS_IOS_ARCHITECTURE_CROSS_FEATURE_IMPORT_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.architecture.layer-direction-violation.ast')?.then.code,
    'HEURISTICS_IOS_ARCHITECTURE_LAYER_DIRECTION_VIOLATION_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.architecture.excessive-public-api.ast')?.then.code,
    'HEURISTICS_IOS_ARCHITECTURE_EXCESSIVE_PUBLIC_API_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.naming.non-pascal-case-type.ast')?.then.code,
    'HEURISTICS_IOS_NAMING_NON_PASCAL_CASE_TYPE_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.uikit.cell-without-reuse.ast')?.then.code,
    'HEURISTICS_IOS_UIKIT_CELL_WITHOUT_REUSE_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.testing.makesut-without-memory-tracking.ast')?.then.code,
    'HEURISTICS_IOS_TESTING_MAKESUT_WITHOUT_MEMORY_TRACKING_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.testing.direct-sut-instantiation-without-makesut.ast')?.then.code,
    'HEURISTICS_IOS_TESTING_DIRECT_SUT_INSTANTIATION_WITHOUT_MAKESUT_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.swiftui.manual-rendering-without-imagerenderer.ast')?.then.code,
    'HEURISTICS_IOS_SWIFTUI_MANUAL_RENDERING_WITHOUT_IMAGERENDERER_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.swiftui.large-viewbuilder-function.ast')?.then.code,
    'HEURISTICS_IOS_SWIFTUI_LARGE_VIEWBUILDER_FUNCTION_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.accessibility.animation-without-reduce-motion.ast')?.then.code,
    'HEURISTICS_IOS_ACCESSIBILITY_ANIMATION_WITHOUT_REDUCE_MOTION_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.accessibility.on-tap-without-button-trait.ast')?.then.code,
    'HEURISTICS_IOS_ACCESSIBILITY_ON_TAP_WITHOUT_BUTTON_TRAIT_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.navigation.path-without-restoration.ast')?.then.code,
    'HEURISTICS_IOS_NAVIGATION_PATH_WITHOUT_RESTORATION_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.swiftui.glasseffectid-without-namespace.ast')?.then.code,
    'HEURISTICS_IOS_SWIFTUI_GLASSEFFECTID_WITHOUT_NAMESPACE_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.maintainability.nested-if-pyramid.ast')?.then.code,
    'HEURISTICS_IOS_MAINTAINABILITY_NESTED_IF_PYRAMID_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.maintainability.comment-trivia.ast')?.then.code,
    'HEURISTICS_IOS_MAINTAINABILITY_COMMENT_TRIVIA_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.maintainability.warning-suppression.ast')?.then.code,
    'HEURISTICS_IOS_MAINTAINABILITY_WARNING_SUPPRESSION_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.uikit.manual-frame-layout.ast')?.then.code,
    'HEURISTICS_IOS_UIKIT_MANUAL_FRAME_LAYOUT_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.swiftui.onchange-task.ast')?.then.code,
    'HEURISTICS_IOS_SWIFTUI_ONCHANGE_TASK_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.swiftui.onchange-readonly-var.ast')?.then.code,
    'HEURISTICS_IOS_SWIFTUI_ONCHANGE_READONLY_VAR_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.logging.adhoc-print.ast')?.then.code,
    'HEURISTICS_IOS_LOGGING_ADHOC_PRINT_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.logging.sensitive-data.ast')?.then.code,
    'HEURISTICS_IOS_LOGGING_SENSITIVE_DATA_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.networking.alamofire.ast')?.then.code,
    'HEURISTICS_IOS_NETWORKING_ALAMOFIRE_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.architecture.tca-composable-architecture.ast')?.then.code,
    'HEURISTICS_IOS_ARCHITECTURE_TCA_COMPOSABLE_ARCHITECTURE_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.testing.third-party-ui-test-framework.ast')?.then.code,
    'HEURISTICS_IOS_TESTING_THIRD_PARTY_UI_TEST_FRAMEWORK_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.json.jsonserialization.ast')?.then.code,
    'HEURISTICS_IOS_JSON_JSONSERIALIZATION_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.dependencies.cocoapods.ast')?.then.code,
    'HEURISTICS_IOS_DEPENDENCIES_COCOAPODS_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.dependencies.carthage.ast')?.then.code,
    'HEURISTICS_IOS_DEPENDENCIES_CARTHAGE_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.security.userdefaults-sensitive-data.ast')?.then.code,
    'HEURISTICS_IOS_SECURITY_USERDEFAULTS_SENSITIVE_DATA_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.security.insecure-transport.ast')?.then.code,
    'HEURISTICS_IOS_SECURITY_INSECURE_TRANSPORT_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.localization.localizable-strings.ast')?.then.code,
    'HEURISTICS_IOS_LOCALIZATION_LOCALIZABLE_STRINGS_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.interface-builder.storyboard-xib.ast')?.then.code,
    'HEURISTICS_IOS_INTERFACE_BUILDER_STORYBOARD_XIB_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.localization.hardcoded-ui-string.ast')?.then.code,
    'HEURISTICS_IOS_LOCALIZATION_HARDCODED_UI_STRING_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.localization.unlocalized-dateformatter.ast')?.then.code,
    'HEURISTICS_IOS_LOCALIZATION_UNLOCALIZED_DATEFORMATTER_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.assets.loose-resource.ast')?.then.code,
    'HEURISTICS_IOS_ASSETS_LOOSE_RESOURCE_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.accessibility.fixed-font-size.ast')?.then.code,
    'HEURISTICS_IOS_ACCESSIBILITY_FIXED_FONT_SIZE_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.localization.physical-text-alignment.ast')?.then.code,
    'HEURISTICS_IOS_LOCALIZATION_PHYSICAL_TEXT_ALIGNMENT_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.performance.blocking-sleep.ast')?.then.code,
    'HEURISTICS_IOS_PERFORMANCE_BLOCKING_SLEEP_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.concurrency.thread-centric-debugging.ast')?.then.code,
    'HEURISTICS_IOS_CONCURRENCY_THREAD_CENTRIC_DEBUGGING_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.accessibility.icon-only-control-label.ast')?.then.code,
    'HEURISTICS_IOS_ACCESSIBILITY_ICON_ONLY_CONTROL_LABEL_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.accessibility.missing-accessibility-identifier.ast')?.then.code,
    'HEURISTICS_IOS_ACCESSIBILITY_MISSING_ACCESSIBILITY_IDENTIFIER_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.swiftui.missing-bindable-observable-binding.ast')?.then.code,
    'HEURISTICS_IOS_SWIFTUI_MISSING_BINDABLE_OBSERVABLE_BINDING_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.preconcurrency.ast')?.then.code,
    'HEURISTICS_IOS_PRECONCURRENCY_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.nonisolated-unsafe.ast')?.then.code,
    'HEURISTICS_IOS_NONISOLATED_UNSAFE_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.assume-isolated.ast')?.then.code,
    'HEURISTICS_IOS_ASSUME_ISOLATED_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.dependencies.swiftpm-branch-dependency.ast')?.then.code,
    'HEURISTICS_IOS_DEPENDENCIES_SWIFTPM_BRANCH_DEPENDENCY_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.error.nserror-throw.ast')?.then.code,
    'HEURISTICS_IOS_ERROR_NSERROR_THROW_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.legacy-swiftui-observable-wrapper.ast')?.then.code,
    'HEURISTICS_IOS_LEGACY_SWIFTUI_OBSERVABLE_WRAPPER_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.swiftui.environment-object.ast')?.then.code,
    'HEURISTICS_IOS_SWIFTUI_ENVIRONMENT_OBJECT_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.testing.production-test-double.ast')?.then.code,
    'HEURISTICS_IOS_TESTING_PRODUCTION_TEST_DOUBLE_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.passed-value-state-wrapper.ast')?.then.code,
    'HEURISTICS_IOS_PASSED_VALUE_STATE_WRAPPER_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.foreach-indices.ast')?.then.code,
    'HEURISTICS_IOS_FOREACH_INDICES_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.contains-user-filter.ast')?.then.code,
    'HEURISTICS_IOS_CONTAINS_USER_FILTER_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.geometryreader.ast')?.then.code,
    'HEURISTICS_IOS_GEOMETRYREADER_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.font-weight-bold.ast')?.then.code,
    'HEURISTICS_IOS_FONT_WEIGHT_BOLD_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.swiftui.large-config-context-prop.ast')?.then.code,
    'HEURISTICS_IOS_SWIFTUI_LARGE_CONFIG_CONTEXT_PROP_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.swiftui.conditional-same-view-identity.ast')?.then.code,
    'HEURISTICS_IOS_SWIFTUI_CONDITIONAL_SAME_VIEW_IDENTITY_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.swiftui.parent-owned-sheet-action.ast')?.then.code,
    'HEURISTICS_IOS_SWIFTUI_PARENT_OWNED_SHEET_ACTION_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.uiscreen-main-bounds.ast')?.then.code,
    'HEURISTICS_IOS_UISCREEN_MAIN_BOUNDS_AST'
  );
  assert.equal(byId.get('heuristics.ios.foreground-color.ast')?.then.code, 'HEURISTICS_IOS_FOREGROUND_COLOR_AST');
  assert.equal(
    byId.get('heuristics.ios.sheet-is-presented.ast')?.then.code,
    'HEURISTICS_IOS_SHEET_IS_PRESENTED_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.legacy-onchange.ast')?.then.code,
    'HEURISTICS_IOS_LEGACY_ONCHANGE_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.testing.xctassert.ast')?.then.code,
    'HEURISTICS_IOS_TESTING_XCTASSERT_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.testing.xctest-suite-modernizable.ast')?.then.code,
    'HEURISTICS_IOS_TESTING_XCTEST_SUITE_MODERNIZABLE_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.testing.wait-for-expectations.ast')?.then.code,
    'HEURISTICS_IOS_TESTING_WAIT_FOR_EXPECTATIONS_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.testing.legacy-expectation-description.ast')?.then.code,
    'HEURISTICS_IOS_TESTING_LEGACY_EXPECTATION_DESCRIPTION_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.testing.mixed-frameworks.ast')?.then.code,
    'HEURISTICS_IOS_TESTING_MIXED_FRAMEWORKS_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.core-data.nsmanagedobject-async-boundary.ast')?.then.code,
    'HEURISTICS_IOS_CORE_DATA_NSMANAGEDOBJECT_ASYNC_BOUNDARY_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.core-data.layer-leak.ast')?.then.code,
    'HEURISTICS_IOS_CORE_DATA_LAYER_LEAK_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.swiftdata.layer-leak.ast')?.then.code,
    'HEURISTICS_IOS_SWIFTDATA_LAYER_LEAK_AST'
  );
  assert.equal(
    byId.get('heuristics.ios.core-data.nsmanagedobject-state-leak.ast')?.then.code,
    'HEURISTICS_IOS_CORE_DATA_NSMANAGEDOBJECT_STATE_LEAK_AST'
  );

  for (const rule of iosRules) {
    assert.equal(rule.platform, 'ios');
    assert.equal(rule.severity, 'WARN');
    assert.equal(rule.locked, true);
    assert.equal(rule.when.kind, 'Heuristic');
    assert.equal(rule.then.kind, 'Finding');
    assert.equal(rule.when.where?.ruleId, rule.id);
  }
});
