| 849 | static char g_sim_tmpdir[512]; |
| 850 | |
| 851 | static int setup_sim_test_repo(void) { |
| 852 | snprintf(g_sim_tmpdir, sizeof(g_sim_tmpdir), "/tmp/cbm_sim_test_XXXXXX"); |
| 853 | if (!cbm_mkdtemp(g_sim_tmpdir)) { |
| 854 | return -1; |
| 855 | } |
| 856 | |
| 857 | /* Near-clone: ValidateUser and ValidateOrder have same structure, different names. |
| 858 | * Must be large enough (>= 30 leaf tokens, >= 32 unique structural trigrams). */ |
| 859 | th_write_file(TH_PATH(g_sim_tmpdir, "pkg/validation/user_validator.go"), |
| 860 | "package validation\n" |
| 861 | "import \"errors\"\n" |
| 862 | "import \"strings\"\n" |
| 863 | "func ValidateUser(u User) error {\n" |
| 864 | " if u.Name == \"\" { return errors.New(\"name required\") }\n" |
| 865 | " if len(u.Name) > 100 { return errors.New(\"name too long\") }\n" |
| 866 | " if u.Age < 0 { return errors.New(\"invalid age\") }\n" |
| 867 | " if u.Age > 200 { return errors.New(\"age too high\") }\n" |
| 868 | " if u.Email == \"\" { return errors.New(\"email required\") }\n" |
| 869 | " if !strings.Contains(u.Email, \"@\") { return errors.New(\"invalid email\") }\n" |
| 870 | " if u.Phone == \"\" { return errors.New(\"phone required\") }\n" |
| 871 | " if len(u.Phone) < 7 { return errors.New(\"phone too short\") }\n" |
| 872 | " if u.Country == \"\" { return errors.New(\"country required\") }\n" |
| 873 | " for _, c := range u.Tags {\n" |
| 874 | " if c == \"\" { return errors.New(\"empty tag\") }\n" |
| 875 | " }\n" |
| 876 | " return nil\n" |
| 877 | "}\n"); |
| 878 | |
| 879 | th_write_file(TH_PATH(g_sim_tmpdir, "pkg/validation/order_validator.go"), |
| 880 | "package validation\n" |
| 881 | "import \"errors\"\n" |
| 882 | "import \"strings\"\n" |
| 883 | "func ValidateOrder(o Order) error {\n" |
| 884 | " if o.Title == \"\" { return errors.New(\"title required\") }\n" |
| 885 | " if len(o.Title) > 100 { return errors.New(\"title too long\") }\n" |
| 886 | " if o.Amount < 0 { return errors.New(\"invalid amount\") }\n" |
| 887 | " if o.Amount > 200 { return errors.New(\"amount too high\") }\n" |
| 888 | " if o.Status == \"\" { return errors.New(\"status required\") }\n" |
| 889 | " if !strings.Contains(o.Status, \"@\") { return errors.New(\"invalid status\") }\n" |
| 890 | " if o.Region == \"\" { return errors.New(\"region required\") }\n" |
| 891 | " if len(o.Region) < 7 { return errors.New(\"region too short\") }\n" |
| 892 | " if o.Vendor == \"\" { return errors.New(\"vendor required\") }\n" |
| 893 | " for _, c := range o.Items {\n" |
| 894 | " if c == \"\" { return errors.New(\"empty item\") }\n" |
| 895 | " }\n" |
| 896 | " return nil\n" |
| 897 | "}\n"); |
| 898 | |
| 899 | /* Completely different function — also large enough for fingerprinting */ |
| 900 | th_write_file(TH_PATH(g_sim_tmpdir, "pkg/handler/user_handler.go"), |
| 901 | GO_HANDLE_REQUEST_SRC); |
| 902 | |
| 903 | /* Tiny function — should be skipped */ |
| 904 | th_write_file(TH_PATH(g_sim_tmpdir, "pkg/util/tiny_helper.go"), |
| 905 | "package util\n" |
| 906 | "\n" |
| 907 | "func Max(a, b int) int {\n" |
| 908 | " if a > b { return a }\n" |
no test coverage detected