@@ -447,4 +447,168 @@ describeWithGrammars("PostHogDetector", () => {
447447 ] ) ;
448448 } ) ;
449449 } ) ;
450+
451+ // ═══════════════════════════════════════════════════
452+ // Python — additional findPostHogCalls / findInitCalls
453+ // ═══════════════════════════════════════════════════
454+
455+ describe ( "Python — findPostHogCalls (capture)" , ( ) => {
456+ test ( "detects capture with positional event arg" , async ( ) => {
457+ const code = `posthog.capture('user_id', 'purchase')` ;
458+ const calls = await detector . findPostHogCalls ( code , "python" ) ;
459+ const capture = calls . find (
460+ ( c ) => c . method === "capture" && c . key === "purchase" ,
461+ ) ;
462+ expect ( capture ) . toBeDefined ( ) ;
463+ } ) ;
464+
465+ test ( "detects flag method get_feature_flag" , async ( ) => {
466+ const code = `posthog.get_feature_flag('my-flag')` ;
467+ const calls = await detector . findPostHogCalls ( code , "python" ) ;
468+ expect ( simpleCalls ( calls ) ) . toEqual ( [
469+ { line : 0 , method : "get_feature_flag" , key : "my-flag" } ,
470+ ] ) ;
471+ } ) ;
472+ } ) ;
473+
474+ describe ( "Python — findInitCalls" , ( ) => {
475+ test ( "detects positional constructor Posthog('phc_token')" , async ( ) => {
476+ const code = `Posthog('phc_token')` ;
477+ const inits = await detector . findInitCalls ( code , "python" ) ;
478+ expect ( inits ) . toHaveLength ( 1 ) ;
479+ expect ( inits [ 0 ] . token ) . toBe ( "phc_token" ) ;
480+ } ) ;
481+
482+ test ( "detects keyword constructor with api_key and host" , async ( ) => {
483+ const code = `Posthog(api_key='phc_token', host='https://app.posthog.com')` ;
484+ const inits = await detector . findInitCalls ( code , "python" ) ;
485+ expect ( inits ) . toHaveLength ( 1 ) ;
486+ expect ( inits [ 0 ] . token ) . toBe ( "phc_token" ) ;
487+ expect ( inits [ 0 ] . apiHost ) . toBe ( "https://app.posthog.com" ) ;
488+ } ) ;
489+ } ) ;
490+
491+ // ═══════════════════════════════════════════════════
492+ // Go — additional findPostHogCalls / findInitCalls
493+ // ═══════════════════════════════════════════════════
494+
495+ describe ( "Go — findPostHogCalls (capture & flags)" , ( ) => {
496+ test ( "detects struct-based Enqueue capture" , async ( ) => {
497+ const code = [
498+ `package main` ,
499+ `` ,
500+ `func main() {` ,
501+ ` client.Enqueue(posthog.Capture{Event: "purchase"})` ,
502+ `}` ,
503+ ] . join ( "\n" ) ;
504+ const calls = await detector . findPostHogCalls ( code , "go" ) ;
505+ const capture = calls . find (
506+ ( c ) => c . method === "capture" && c . key === "purchase" ,
507+ ) ;
508+ expect ( capture ) . toBeDefined ( ) ;
509+ } ) ;
510+
511+ test ( "detects flag method GetFeatureFlag" , async ( ) => {
512+ const code = [
513+ `package main` ,
514+ `` ,
515+ `func main() {` ,
516+ ` client.GetFeatureFlag(posthog.FeatureFlagPayload{Key: "my-flag"})` ,
517+ `}` ,
518+ ] . join ( "\n" ) ;
519+ const calls = await detector . findPostHogCalls ( code , "go" ) ;
520+ const flag = calls . find (
521+ ( c ) => c . method === "GetFeatureFlag" && c . key === "my-flag" ,
522+ ) ;
523+ expect ( flag ) . toBeDefined ( ) ;
524+ } ) ;
525+ } ) ;
526+
527+ describe ( "Go — findInitCalls" , ( ) => {
528+ test ( "detects posthog.New constructor" , async ( ) => {
529+ const code = [
530+ `package main` ,
531+ `` ,
532+ `func main() {` ,
533+ ` client := posthog.New("phc_token")` ,
534+ `}` ,
535+ ] . join ( "\n" ) ;
536+ const inits = await detector . findInitCalls ( code , "go" ) ;
537+ expect ( inits ) . toHaveLength ( 1 ) ;
538+ expect ( inits [ 0 ] . token ) . toBe ( "phc_token" ) ;
539+ } ) ;
540+
541+ test ( "detects posthog.NewWithConfig constructor" , async ( ) => {
542+ const code = [
543+ `package main` ,
544+ `` ,
545+ `func main() {` ,
546+ ` client, _ := posthog.NewWithConfig("phc_token", posthog.Config{Endpoint: "https://app.posthog.com"})` ,
547+ `}` ,
548+ ] . join ( "\n" ) ;
549+ const inits = await detector . findInitCalls ( code , "go" ) ;
550+ expect ( inits ) . toHaveLength ( 1 ) ;
551+ expect ( inits [ 0 ] . token ) . toBe ( "phc_token" ) ;
552+ expect ( inits [ 0 ] . apiHost ) . toBe ( "https://app.posthog.com" ) ;
553+ } ) ;
554+ } ) ;
555+
556+ // ═══════════════════════════════════════════════════
557+ // Ruby — additional findPostHogCalls / findInitCalls
558+ // ═══════════════════════════════════════════════════
559+
560+ describe ( "Ruby — findPostHogCalls (capture & flags)" , ( ) => {
561+ test ( "detects capture with keyword args" , async ( ) => {
562+ const code = `client.capture(distinct_id: 'user', event: 'purchase')` ;
563+ const calls = await detector . findPostHogCalls ( code , "ruby" ) ;
564+ const capture = calls . find (
565+ ( c ) => c . method === "capture" && c . key === "purchase" ,
566+ ) ;
567+ expect ( capture ) . toBeDefined ( ) ;
568+ } ) ;
569+
570+ test ( "detects flag method get_feature_flag" , async ( ) => {
571+ const code = `client.get_feature_flag('my-flag')` ;
572+ const calls = await detector . findPostHogCalls ( code , "ruby" ) ;
573+ const flag = calls . find (
574+ ( c ) => c . method === "get_feature_flag" && c . key === "my-flag" ,
575+ ) ;
576+ expect ( flag ) . toBeDefined ( ) ;
577+ } ) ;
578+ } ) ;
579+
580+ describe ( "Ruby — findInitCalls" , ( ) => {
581+ test ( "detects PostHog::Client.new constructor" , async ( ) => {
582+ const code = `client = PostHog::Client.new(api_key: 'phc_token')` ;
583+ const inits = await detector . findInitCalls ( code , "ruby" ) ;
584+ expect ( inits ) . toHaveLength ( 1 ) ;
585+ expect ( inits [ 0 ] . token ) . toBe ( "phc_token" ) ;
586+ } ) ;
587+ } ) ;
588+
589+ // ═══════════════════════════════════════════════════
590+ // Negative / edge cases
591+ // ═══════════════════════════════════════════════════
592+
593+ describe ( "Negative / edge cases" , ( ) => {
594+ test ( "unsupported language returns empty arrays" , async ( ) => {
595+ const code = `posthog.capture('event')` ;
596+ const calls = await detector . findPostHogCalls ( code , "haskell" ) ;
597+ const inits = await detector . findInitCalls ( code , "haskell" ) ;
598+ expect ( calls ) . toEqual ( [ ] ) ;
599+ expect ( inits ) . toEqual ( [ ] ) ;
600+ } ) ;
601+
602+ test ( "non-PostHog client names are ignored" , async ( ) => {
603+ const code = `other.capture('event')` ;
604+
605+ const jsCalls = await detector . findPostHogCalls ( code , "javascript" ) ;
606+ const pyCalls = await detector . findPostHogCalls ( code , "python" ) ;
607+ const rbCalls = await detector . findPostHogCalls ( code , "ruby" ) ;
608+
609+ expect ( jsCalls ) . toEqual ( [ ] ) ;
610+ expect ( pyCalls ) . toEqual ( [ ] ) ;
611+ expect ( rbCalls ) . toEqual ( [ ] ) ;
612+ } ) ;
613+ } ) ;
450614} ) ;
0 commit comments