@@ -2043,4 +2043,144 @@ void when_spliting_pip_show_dep_with_license() {
20432043 + "Requires: \n "
20442044 + "Required-by: cycler, gensim, gTTS, python-dateutil, tweepy\n " );
20452045 }
2046+
2047+ @ Test
2048+ void preprocessRequirementsLines_filters_extra_index_url () {
2049+ List <String > input =
2050+ List .of (
2051+ "--extra-index-url https://pypi.example.com/simple" ,
2052+ "requests==2.28.0" ,
2053+ "--index-url https://pypi.org/simple" ,
2054+ "flask==2.0.3" );
2055+ List <String > result = PythonControllerBase .preprocessRequirementsLines (input );
2056+ assertEquals (List .of ("requests==2.28.0" , "flask==2.0.3" ), result );
2057+ }
2058+
2059+ @ Test
2060+ void preprocessRequirementsLines_filters_short_pip_options () {
2061+ List <String > input =
2062+ List .of ("-r other-requirements.txt" , "-c constraints.txt" , "numpy==1.24.0" );
2063+ List <String > result = PythonControllerBase .preprocessRequirementsLines (input );
2064+ assertEquals (List .of ("numpy==1.24.0" ), result );
2065+ }
2066+
2067+ @ Test
2068+ void preprocessRequirementsLines_strips_hashes () {
2069+ List <String > input =
2070+ List .of ("requests==2.28.0 --hash=sha256:abc123 --hash=sha256:def456" , "flask==2.0.3" );
2071+ List <String > result = PythonControllerBase .preprocessRequirementsLines (input );
2072+ assertEquals (List .of ("requests==2.28.0" , "flask==2.0.3" ), result );
2073+ }
2074+
2075+ @ Test
2076+ void preprocessRequirementsLines_strips_config_settings () {
2077+ List <String > input =
2078+ List .of (
2079+ "aiohappyeyeballs==2.6.1 --config-settings=KEY=VALUE --config-settings=OTHER=VAL" ,
2080+ "flask==2.0.3" );
2081+ List <String > result = PythonControllerBase .preprocessRequirementsLines (input );
2082+ assertEquals (List .of ("aiohappyeyeballs==2.6.1" , "flask==2.0.3" ), result );
2083+ }
2084+
2085+ @ Test
2086+ void preprocessRequirementsLines_joins_line_continuations () {
2087+ List <String > input =
2088+ List .of (
2089+ "requests==2.28.0 \\ " ,
2090+ " --hash=sha256:abc123 \\ " ,
2091+ " --hash=sha256:def456" ,
2092+ "flask==2.0.3" );
2093+ List <String > result = PythonControllerBase .preprocessRequirementsLines (input );
2094+ assertEquals (List .of ("requests==2.28.0" , "flask==2.0.3" ), result );
2095+ }
2096+
2097+ @ Test
2098+ void preprocessRequirementsLines_joins_continuations_with_config_settings () {
2099+ List <String > input =
2100+ List .of (
2101+ "aiohappyeyeballs==2.6.1 \\ " ,
2102+ " --config-settings=SAMPLE_TEXT=TEST_VALUE \\ " ,
2103+ " --config-settings=ANOTHER_KEY=ANOTHER_VALUE" ,
2104+ "async-timeout==5.0.1 ; python_full_version < '3.11'" );
2105+ List <String > result = PythonControllerBase .preprocessRequirementsLines (input );
2106+ assertEquals (
2107+ List .of ("aiohappyeyeballs==2.6.1" , "async-timeout==5.0.1 ; python_full_version < '3.11'" ),
2108+ result );
2109+ }
2110+
2111+ @ Test
2112+ void preprocessRequirementsLines_filters_comments_and_empty_lines () {
2113+ List <String > input = List .of ("# this is a comment" , "" , " " , "requests==2.28.0" );
2114+ List <String > result = PythonControllerBase .preprocessRequirementsLines (input );
2115+ assertEquals (List .of ("requests==2.28.0" ), result );
2116+ }
2117+
2118+ @ Test
2119+ void preprocessRequirementsLines_strips_direct_references () {
2120+ List <String > input =
2121+ List .of (
2122+ "pip @ https://github.com/pypa/pip/archive/22.0.2.zip" ,
2123+ "requests[security] @ https://github.com/psf/requests/archive/main.zip" ,
2124+ "flask==2.0.3" );
2125+ List <String > result = PythonControllerBase .preprocessRequirementsLines (input );
2126+ assertEquals (List .of ("pip" , "requests[security]" , "flask==2.0.3" ), result );
2127+ }
2128+
2129+ @ Test
2130+ void preprocessRequirementsLines_handles_trailing_whitespace_after_backslash () {
2131+ List <String > input =
2132+ List .of ("requests==2.28.0 \\ " , " --hash=sha256:abc123" , "flask==2.0.3" );
2133+ List <String > result = PythonControllerBase .preprocessRequirementsLines (input );
2134+ assertEquals (List .of ("requests==2.28.0" , "flask==2.0.3" ), result );
2135+ }
2136+
2137+ @ Test
2138+ void preprocessRequirementsLines_filters_bare_urls () {
2139+ List <String > input =
2140+ List .of (
2141+ "https://example.com/packages/MyPackage-1.0.tar.gz" ,
2142+ "http://example.com/packages/other.whl" ,
2143+ "git+https://git.example.com/MyProject.git@v1.0" ,
2144+ "git+git://git.example.com/repo.git" ,
2145+ "hg+http://hg.example.com/repo" ,
2146+ "hg+ssh://hg.example.com/repo" ,
2147+ "svn+svn://svn.example.com/project/trunk" ,
2148+ "bzr+ftp://bzr.example.com/repo" ,
2149+ "requests==2.28.0" );
2150+ List <String > result = PythonControllerBase .preprocessRequirementsLines (input );
2151+ assertEquals (List .of ("requests==2.28.0" ), result );
2152+ }
2153+
2154+ @ Test
2155+ void preprocessRequirementsLines_filters_local_paths () {
2156+ List <String > input =
2157+ List .of (
2158+ "./local-package" ,
2159+ "../parent-package" ,
2160+ "./downloads/MyPackage-1.0.tar.gz" ,
2161+ "/absolute/path/to/package" ,
2162+ "requests==2.28.0" );
2163+ List <String > result = PythonControllerBase .preprocessRequirementsLines (input );
2164+ assertEquals (List .of ("requests==2.28.0" ), result );
2165+ }
2166+
2167+ @ Test
2168+ void preprocessRequirementsLines_combined_scenario () {
2169+ List <String > input =
2170+ List .of (
2171+ "--extra-index-url https://pypi.example.com/simple" ,
2172+ "# A comment" ,
2173+ "requests==2.28.0 \\ " ,
2174+ " --hash=sha256:abc123" ,
2175+ "" ,
2176+ "--trusted-host pypi.example.com" ,
2177+ "flask==2.0.3 --hash=sha256:xyz789" ,
2178+ "pip @ https://github.com/pypa/pip/archive/22.0.2.zip" ,
2179+ "https://example.com/packages/other.tar.gz" ,
2180+ "git+git://git.example.com/repo.git" ,
2181+ "./local-package" ,
2182+ "numpy>=1.24.0" );
2183+ List <String > result = PythonControllerBase .preprocessRequirementsLines (input );
2184+ assertEquals (List .of ("requests==2.28.0" , "flask==2.0.3" , "pip" , "numpy>=1.24.0" ), result );
2185+ }
20462186}
0 commit comments