class

Analyzer::Haskell::Scotty

Inherits Analyzer < FileHelper < Reference < Object

Constants

ADDROUTE_LINE_REGEX = /^([ \t]*)(?:[A-Z][A-Za-z0-9_']*\.)?addroute\s+([A-Z]+)\s+"((?:[^"\\]|\\.)*)"(.*)$/
FORM_PARAM_REGEX = /(?<![A-Za-z0-9_'])(?:formParam|formParamMaybe|formParams)\s+"((?:[^"\\]|\\.)*)"/
HEADER_REGEX = /(?<![A-Za-z0-9_'])header\s+"((?:[^"\\]|\\.)*)"/
HSPEC_WAI_IMPORT_RE = /^[ \t]*import\s+(?:qualified\s+)?Test\.Hspec\.Wai\b/m

hspec-wai test clients call get "/x" shouldRespondWith ..., which reads exactly like a Scotty route; a file that imports it is a test even when it lives outside a test directory.

HTTP_VERBS = {"get" => "GET", "post" => "POST", "put" => "PUT", "patch" => "PATCH", "delete" => "DELETE", "options" => "OPTIONS", "head" => "HEAD"}
PATH_PARAM_REGEX = /(?<![A-Za-z0-9_'])(?:pathParam|pathParamMaybe)\s+"((?:[^"\\]|\\.)*)"/
QUERY_PARAM_REGEX = /(?<![A-Za-z0-9_'])(?:queryParam|queryParamMaybe|param|captureParam)\s+"((?:[^"\\]|\\.)*)"/
ROUTE_LINE_REGEX = /^([ \t]*)(?:[A-Z][A-Za-z0-9_']*\.)?(get|post|put|patch|delete|options|head)\s+"((?:[^"\\]|\\.)*)"(.*)$/
TEST_DIR_RE = /\/(?:tests?|spec)\//

test/, tests/ and spec/ trees. Case-sensitive on purpose: a production src/Test/... module namespace must stay in.

TEST_LIB_IMPORT_RE = /^[ \t]*import\s+(?:qualified\s+)?Test\.(?:Hspec|Tasty|HUnit|QuickCheck)\b/m
TEST_SUFFIX_RE = /(?:Spec|Tests?)\.l?hs$|_(?:spec|test)\./

hspec-discover/tasty FooSpec.hs / FooTest.hs files and foo_spec. / foo_test. files. The name alone is not enough: OpenApiSpec.hs, SpeedTest.hs and Handlers/Tests.hs are production modules, so the file must also import a Haskell test library.

TOKEN_PATTERNS = {"jsonData" => /(?<![A-Za-z0-9_'])jsonData(?![A-Za-z0-9_'])/, "files" => /(?<![A-Za-z0-9_'])files(?![A-Za-z0-9_'])/}

Crystal recompiles an interpolated regex literal on every evaluation (a full PCRE2 JIT compile). The probed token set is fixed, so precompile the matchers once at load time.

Class methods

tech_name
Source

Instance methods

analyze
Source
tech

Instance-side view of the same declaration. The per-file rescues live on this base class, which has no way to name the analyzer that is running inside them, so a skipped file could not be attributed to a tech. Deriving it from analyzer_for keeps the name written exactly once.

Source

Nested types