aboutsummaryrefslogtreecommitdiff
path: root/unit_tests
diff options
context:
space:
mode:
Diffstat (limited to 'unit_tests')
-rw-r--r--unit_tests/UnitTests.vcxproj279
-rw-r--r--unit_tests/UnitTests.vcxproj.filters44
-rw-r--r--unit_tests/_pch.hpp2
-rw-r--r--unit_tests/deep_tests.cpp11
-rw-r--r--unit_tests/embedded_tests.cpp22
-rw-r--r--unit_tests/init_and_shutdown.cpp680
-rw-r--r--unit_tests/lane_tests.cpp256
-rw-r--r--unit_tests/legacy_tests.cpp4
-rw-r--r--unit_tests/linda_tests.cpp333
-rw-r--r--unit_tests/scripts/_utils.lua20
-rw-r--r--unit_tests/scripts/_utils54.lua30
-rw-r--r--unit_tests/scripts/coro/basics.lua97
-rw-r--r--unit_tests/scripts/coro/cancelling_suspended.lua31
-rw-r--r--unit_tests/scripts/coro/collect_yielded_lane.lua64
-rw-r--r--unit_tests/scripts/coro/error_handling.lua6
-rw-r--r--unit_tests/scripts/coro/index_suspended.lua28
-rw-r--r--unit_tests/scripts/coro/join_suspended.lua24
-rw-r--r--unit_tests/scripts/coro/linda_in_close_handler.lua43
-rw-r--r--unit_tests/scripts/coro/regular_function.lua38
-rw-r--r--unit_tests/scripts/coro/resume_basics.lua40
-rw-r--r--unit_tests/scripts/coro/yielding_in_non_coro_errors.lua28
-rw-r--r--unit_tests/scripts/lane/body_is_a_c_function.lua28
-rw-r--r--unit_tests/scripts/lane/cooperative_shutdown.lua16
-rw-r--r--unit_tests/scripts/lane/tasking_cancelling.lua112
-rw-r--r--unit_tests/scripts/lane/tasking_cancelling_with_hook.lua68
-rw-r--r--unit_tests/scripts/lane/tasking_comms_criss_cross.lua2
-rw-r--r--unit_tests/scripts/lane/tasking_communications.lua4
-rw-r--r--unit_tests/scripts/lane/tasking_join_test.lua16
-rw-r--r--unit_tests/scripts/lane/tasking_send_receive_code.lua20
-rw-r--r--unit_tests/scripts/lane/uncooperative_shutdown.lua2
-rw-r--r--unit_tests/scripts/linda/multiple_keepers.lua6
-rw-r--r--unit_tests/scripts/linda/send_receive_func_and_string.lua13
-rw-r--r--unit_tests/scripts/linda/send_registered_userdata.lua2
-rw-r--r--unit_tests/scripts/linda/wake_period.lua42
-rw-r--r--unit_tests/scripts/misc/deeptest.lua161
-rw-r--r--unit_tests/shared.cpp57
-rw-r--r--unit_tests/shared.h2
37 files changed, 1852 insertions, 779 deletions
diff --git a/unit_tests/UnitTests.vcxproj b/unit_tests/UnitTests.vcxproj
index 6ff1eb1..2093063 100644
--- a/unit_tests/UnitTests.vcxproj
+++ b/unit_tests/UnitTests.vcxproj
@@ -45,6 +45,30 @@
45 <Configuration>Debug 5.4</Configuration> 45 <Configuration>Debug 5.4</Configuration>
46 <Platform>Win32</Platform> 46 <Platform>Win32</Platform>
47 </ProjectConfiguration> 47 </ProjectConfiguration>
48 <ProjectConfiguration Include="Debug 5.5|Prospero">
49 <Configuration>Debug 5.5</Configuration>
50 <Platform>Prospero</Platform>
51 </ProjectConfiguration>
52 <ProjectConfiguration Include="Debug 5.5|Win32">
53 <Configuration>Debug 5.5</Configuration>
54 <Platform>Win32</Platform>
55 </ProjectConfiguration>
56 <ProjectConfiguration Include="Debug 5.5|x64">
57 <Configuration>Debug 5.5</Configuration>
58 <Platform>x64</Platform>
59 </ProjectConfiguration>
60 <ProjectConfiguration Include="Release 5.5|Prospero">
61 <Configuration>Release 5.5</Configuration>
62 <Platform>Prospero</Platform>
63 </ProjectConfiguration>
64 <ProjectConfiguration Include="Release 5.5|Win32">
65 <Configuration>Release 5.5</Configuration>
66 <Platform>Win32</Platform>
67 </ProjectConfiguration>
68 <ProjectConfiguration Include="Release 5.5|x64">
69 <Configuration>Release 5.5</Configuration>
70 <Platform>x64</Platform>
71 </ProjectConfiguration>
48 <ProjectConfiguration Include="Release LuaJIT|Prospero"> 72 <ProjectConfiguration Include="Release LuaJIT|Prospero">
49 <Configuration>Release LuaJIT</Configuration> 73 <Configuration>Release LuaJIT</Configuration>
50 <Platform>Prospero</Platform> 74 <Platform>Prospero</Platform>
@@ -125,7 +149,7 @@
125 <PropertyGroup Label="Globals"> 149 <PropertyGroup Label="Globals">
126 <ProjectGuid>{aed7f42f-139a-46ba-80fe-16e062ea1345}</ProjectGuid> 150 <ProjectGuid>{aed7f42f-139a-46ba-80fe-16e062ea1345}</ProjectGuid>
127 <Keyword>Win32Proj</Keyword> 151 <Keyword>Win32Proj</Keyword>
128 <WindowsTargetPlatformVersion>10.0.22621.0</WindowsTargetPlatformVersion> 152 <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
129 <ConfigurationType>Application</ConfigurationType> 153 <ConfigurationType>Application</ConfigurationType>
130 <PlatformToolset>v143</PlatformToolset> 154 <PlatformToolset>v143</PlatformToolset>
131 <CharacterSet>Unicode</CharacterSet> 155 <CharacterSet>Unicode</CharacterSet>
@@ -143,6 +167,9 @@
143 <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|x64'"> 167 <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|x64'">
144 <UseDebugLibraries>true</UseDebugLibraries> 168 <UseDebugLibraries>true</UseDebugLibraries>
145 </PropertyGroup> 169 </PropertyGroup>
170 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.5|x64'" Label="Configuration">
171 <UseDebugLibraries>true</UseDebugLibraries>
172 </PropertyGroup>
146 <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release LuaJIT|x64'"> 173 <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release LuaJIT|x64'">
147 <UseDebugLibraries>true</UseDebugLibraries> 174 <UseDebugLibraries>true</UseDebugLibraries>
148 </PropertyGroup> 175 </PropertyGroup>
@@ -155,103 +182,123 @@
155 <ImportGroup Label="PropertySheets" /> 182 <ImportGroup Label="PropertySheets" />
156 <PropertyGroup Label="UserMacros" /> 183 <PropertyGroup Label="UserMacros" />
157 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|Win32'"> 184 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|Win32'">
158 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 185 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
186 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
187 <LinkIncremental>false</LinkIncremental>
188 </PropertyGroup>
189 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.5|Win32'">
190 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
159 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 191 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
160 <LinkIncremental>false</LinkIncremental> 192 <LinkIncremental>false</LinkIncremental>
161 </PropertyGroup> 193 </PropertyGroup>
162 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|Win32'"> 194 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|Win32'">
163 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 195 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
164 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 196 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
165 <LinkIncremental>false</LinkIncremental> 197 <LinkIncremental>false</LinkIncremental>
166 </PropertyGroup> 198 </PropertyGroup>
167 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.3|Win32'"> 199 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.3|Win32'">
168 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 200 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
169 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 201 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
170 <LinkIncremental>false</LinkIncremental> 202 <LinkIncremental>false</LinkIncremental>
171 </PropertyGroup> 203 </PropertyGroup>
172 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.2|Win32'"> 204 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.2|Win32'">
173 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 205 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
174 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 206 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
175 <LinkIncremental>false</LinkIncremental> 207 <LinkIncremental>false</LinkIncremental>
176 </PropertyGroup> 208 </PropertyGroup>
177 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.2|Win32'"> 209 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.2|Win32'">
178 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 210 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
179 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 211 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
180 <LinkIncremental>false</LinkIncremental> 212 <LinkIncremental>false</LinkIncremental>
181 </PropertyGroup> 213 </PropertyGroup>
182 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.1|Win32'"> 214 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.1|Win32'">
183 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 215 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
184 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 216 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
185 <LinkIncremental>false</LinkIncremental> 217 <LinkIncremental>false</LinkIncremental>
186 </PropertyGroup> 218 </PropertyGroup>
187 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.1|Win32'"> 219 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.1|Win32'">
188 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 220 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
189 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 221 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
190 <LinkIncremental>false</LinkIncremental> 222 <LinkIncremental>false</LinkIncremental>
191 </PropertyGroup> 223 </PropertyGroup>
192 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release LuaJIT|Win32'"> 224 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release LuaJIT|Win32'">
193 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 225 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
194 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 226 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
195 <LinkIncremental>false</LinkIncremental> 227 <LinkIncremental>false</LinkIncremental>
196 </PropertyGroup> 228 </PropertyGroup>
197 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release MoonJIT|Win32'"> 229 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release MoonJIT|Win32'">
198 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 230 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
199 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 231 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
200 <LinkIncremental>false</LinkIncremental> 232 <LinkIncremental>false</LinkIncremental>
201 </PropertyGroup> 233 </PropertyGroup>
202 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.4|Win32'"> 234 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.4|Win32'">
203 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 235 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
236 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
237 <LinkIncremental>false</LinkIncremental>
238 </PropertyGroup>
239 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.5|Win32'">
240 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
204 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 241 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
205 <LinkIncremental>false</LinkIncremental> 242 <LinkIncremental>false</LinkIncremental>
206 </PropertyGroup> 243 </PropertyGroup>
207 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|x64'"> 244 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|x64'">
208 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 245 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
246 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
247 <LinkIncremental>false</LinkIncremental>
248 </PropertyGroup>
249 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.5|x64'">
250 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
209 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 251 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
210 <LinkIncremental>false</LinkIncremental> 252 <LinkIncremental>false</LinkIncremental>
211 </PropertyGroup> 253 </PropertyGroup>
212 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|Prospero'" /> 254 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|Prospero'" />
213 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|x64'"> 255 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|x64'">
214 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 256 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
215 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 257 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
216 <LinkIncremental>false</LinkIncremental> 258 <LinkIncremental>false</LinkIncremental>
217 </PropertyGroup> 259 </PropertyGroup>
218 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.3|x64'"> 260 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.3|x64'">
219 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 261 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
220 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 262 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
221 <LinkIncremental>false</LinkIncremental> 263 <LinkIncremental>false</LinkIncremental>
222 </PropertyGroup> 264 </PropertyGroup>
223 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.2|x64'"> 265 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.2|x64'">
224 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 266 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
225 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 267 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
226 <LinkIncremental>false</LinkIncremental> 268 <LinkIncremental>false</LinkIncremental>
227 </PropertyGroup> 269 </PropertyGroup>
228 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.2|x64'"> 270 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.2|x64'">
229 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 271 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
230 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 272 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
231 <LinkIncremental>false</LinkIncremental> 273 <LinkIncremental>false</LinkIncremental>
232 </PropertyGroup> 274 </PropertyGroup>
233 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.1|x64'"> 275 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.1|x64'">
234 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 276 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
235 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 277 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
236 <LinkIncremental>false</LinkIncremental> 278 <LinkIncremental>false</LinkIncremental>
237 </PropertyGroup> 279 </PropertyGroup>
238 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.1|x64'"> 280 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.1|x64'">
239 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 281 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
240 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 282 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
241 <LinkIncremental>false</LinkIncremental> 283 <LinkIncremental>false</LinkIncremental>
242 </PropertyGroup> 284 </PropertyGroup>
243 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release LuaJIT|x64'"> 285 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release LuaJIT|x64'">
244 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 286 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
245 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 287 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
246 <LinkIncremental>false</LinkIncremental> 288 <LinkIncremental>false</LinkIncremental>
247 </PropertyGroup> 289 </PropertyGroup>
248 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release MoonJIT|x64'"> 290 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release MoonJIT|x64'">
249 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 291 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
250 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 292 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
251 <LinkIncremental>false</LinkIncremental> 293 <LinkIncremental>false</LinkIncremental>
252 </PropertyGroup> 294 </PropertyGroup>
253 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.4|x64'"> 295 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.4|x64'">
254 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 296 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
297 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
298 <LinkIncremental>false</LinkIncremental>
299 </PropertyGroup>
300 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.5|x64'">
301 <OutDir>$(SolutionDir)_LuaVersions\$(PlatformName)\$(Configuration)\</OutDir>
255 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 302 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
256 <LinkIncremental>false</LinkIncremental> 303 <LinkIncremental>false</LinkIncremental>
257 </PropertyGroup> 304 </PropertyGroup>
@@ -261,7 +308,26 @@
261 <PrecompiledHeader>Use</PrecompiledHeader> 308 <PrecompiledHeader>Use</PrecompiledHeader>
262 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile> 309 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile>
263 <Optimization>Disabled</Optimization> 310 <Optimization>Disabled</Optimization>
264 <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> 311 <PreprocessorDefinitions>LANES_DEBUG;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
312 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
313 <WarningLevel>Level3</WarningLevel>
314 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories>
315 <LanguageStandard>stdcpp20</LanguageStandard>
316 <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
317 </ClCompile>
318 <Link>
319 <GenerateDebugInformation>true</GenerateDebugInformation>
320 <SubSystem>Console</SubSystem>
321 <AdditionalDependencies>lua54.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
322 <AdditionalLibraryDirectories>$(SolutionDir)_LuaVersions\$(PlatformName)\$(ConfigurationName)</AdditionalLibraryDirectories>
323 </Link>
324 </ItemDefinitionGroup>
325 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.5|Win32'">
326 <ClCompile>
327 <PrecompiledHeader>Use</PrecompiledHeader>
328 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile>
329 <Optimization>Disabled</Optimization>
330 <PreprocessorDefinitions>LANES_DEBUG;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
265 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> 331 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
266 <WarningLevel>Level3</WarningLevel> 332 <WarningLevel>Level3</WarningLevel>
267 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories> 333 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories>
@@ -280,7 +346,7 @@
280 <PrecompiledHeader>Use</PrecompiledHeader> 346 <PrecompiledHeader>Use</PrecompiledHeader>
281 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile> 347 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile>
282 <Optimization>Disabled</Optimization> 348 <Optimization>Disabled</Optimization>
283 <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> 349 <PreprocessorDefinitions>LANES_DEBUG;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
284 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> 350 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
285 <WarningLevel>Level3</WarningLevel> 351 <WarningLevel>Level3</WarningLevel>
286 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories> 352 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories>
@@ -299,7 +365,7 @@
299 <PrecompiledHeader>Use</PrecompiledHeader> 365 <PrecompiledHeader>Use</PrecompiledHeader>
300 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile> 366 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile>
301 <Optimization>Disabled</Optimization> 367 <Optimization>Disabled</Optimization>
302 <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> 368 <PreprocessorDefinitions>LANES_DEBUG;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
303 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> 369 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
304 <WarningLevel>Level3</WarningLevel> 370 <WarningLevel>Level3</WarningLevel>
305 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories> 371 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories>
@@ -318,7 +384,7 @@
318 <PrecompiledHeader>Use</PrecompiledHeader> 384 <PrecompiledHeader>Use</PrecompiledHeader>
319 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile> 385 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile>
320 <Optimization>Disabled</Optimization> 386 <Optimization>Disabled</Optimization>
321 <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> 387 <PreprocessorDefinitions>LANES_DEBUG;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
322 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> 388 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
323 <WarningLevel>Level3</WarningLevel> 389 <WarningLevel>Level3</WarningLevel>
324 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories> 390 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories>
@@ -337,7 +403,7 @@
337 <PrecompiledHeader>Use</PrecompiledHeader> 403 <PrecompiledHeader>Use</PrecompiledHeader>
338 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile> 404 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile>
339 <Optimization>Disabled</Optimization> 405 <Optimization>Disabled</Optimization>
340 <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> 406 <PreprocessorDefinitions>LANES_DEBUG;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
341 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> 407 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
342 <WarningLevel>Level3</WarningLevel> 408 <WarningLevel>Level3</WarningLevel>
343 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories> 409 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories>
@@ -356,7 +422,7 @@
356 <PrecompiledHeader>Use</PrecompiledHeader> 422 <PrecompiledHeader>Use</PrecompiledHeader>
357 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile> 423 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile>
358 <Optimization>Disabled</Optimization> 424 <Optimization>Disabled</Optimization>
359 <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> 425 <PreprocessorDefinitions>LANES_DEBUG;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
360 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> 426 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
361 <WarningLevel>Level3</WarningLevel> 427 <WarningLevel>Level3</WarningLevel>
362 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories> 428 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories>
@@ -375,7 +441,7 @@
375 <PrecompiledHeader>Use</PrecompiledHeader> 441 <PrecompiledHeader>Use</PrecompiledHeader>
376 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile> 442 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile>
377 <Optimization>Disabled</Optimization> 443 <Optimization>Disabled</Optimization>
378 <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> 444 <PreprocessorDefinitions>LANES_DEBUG;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
379 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> 445 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
380 <WarningLevel>Level3</WarningLevel> 446 <WarningLevel>Level3</WarningLevel>
381 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories> 447 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories>
@@ -394,7 +460,7 @@
394 <PrecompiledHeader>Use</PrecompiledHeader> 460 <PrecompiledHeader>Use</PrecompiledHeader>
395 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile> 461 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile>
396 <Optimization>Disabled</Optimization> 462 <Optimization>Disabled</Optimization>
397 <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> 463 <PreprocessorDefinitions>LANES_DEBUG;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
398 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> 464 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
399 <WarningLevel>Level3</WarningLevel> 465 <WarningLevel>Level3</WarningLevel>
400 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories> 466 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories>
@@ -413,7 +479,7 @@
413 <PrecompiledHeader>Use</PrecompiledHeader> 479 <PrecompiledHeader>Use</PrecompiledHeader>
414 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile> 480 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile>
415 <Optimization>Disabled</Optimization> 481 <Optimization>Disabled</Optimization>
416 <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> 482 <PreprocessorDefinitions>LANES_DEBUG;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
417 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> 483 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
418 <WarningLevel>Level3</WarningLevel> 484 <WarningLevel>Level3</WarningLevel>
419 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories> 485 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories>
@@ -432,7 +498,7 @@
432 <PrecompiledHeader>Use</PrecompiledHeader> 498 <PrecompiledHeader>Use</PrecompiledHeader>
433 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile> 499 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile>
434 <Optimization>Disabled</Optimization> 500 <Optimization>Disabled</Optimization>
435 <PreprocessorDefinitions>X64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> 501 <PreprocessorDefinitions>LANES_DEBUG;X64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
436 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> 502 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
437 <WarningLevel>Level3</WarningLevel> 503 <WarningLevel>Level3</WarningLevel>
438 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories> 504 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories>
@@ -448,6 +514,27 @@
448 </IgnoreSpecificDefaultLibraries> 514 </IgnoreSpecificDefaultLibraries>
449 </Link> 515 </Link>
450 </ItemDefinitionGroup> 516 </ItemDefinitionGroup>
517 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.5|x64'">
518 <ClCompile>
519 <PrecompiledHeader>Use</PrecompiledHeader>
520 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile>
521 <Optimization>Disabled</Optimization>
522 <PreprocessorDefinitions>LANES_DEBUG;X64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
523 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
524 <WarningLevel>Level3</WarningLevel>
525 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories>
526 <LanguageStandard>stdcpp20</LanguageStandard>
527 <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
528 </ClCompile>
529 <Link>
530 <GenerateDebugInformation>true</GenerateDebugInformation>
531 <SubSystem>Console</SubSystem>
532 <AdditionalLibraryDirectories>$(SolutionDir)_LuaVersions\$(PlatformName)\$(ConfigurationName)</AdditionalLibraryDirectories>
533 <AdditionalDependencies>lua55.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
534 <IgnoreSpecificDefaultLibraries>
535 </IgnoreSpecificDefaultLibraries>
536 </Link>
537 </ItemDefinitionGroup>
451 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|Prospero'"> 538 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|Prospero'">
452 <ClCompile> 539 <ClCompile>
453 <PrecompiledHeader>Use</PrecompiledHeader> 540 <PrecompiledHeader>Use</PrecompiledHeader>
@@ -469,7 +556,7 @@
469 </IgnoreSpecificDefaultLibraries> 556 </IgnoreSpecificDefaultLibraries>
470 </Link> 557 </Link>
471 </ItemDefinitionGroup> 558 </ItemDefinitionGroup>
472 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|x64'"> 559 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.5|Prospero'">
473 <ClCompile> 560 <ClCompile>
474 <PrecompiledHeader>Use</PrecompiledHeader> 561 <PrecompiledHeader>Use</PrecompiledHeader>
475 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile> 562 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile>
@@ -477,6 +564,27 @@
477 <PreprocessorDefinitions>X64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> 564 <PreprocessorDefinitions>X64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
478 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> 565 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
479 <WarningLevel>Level3</WarningLevel> 566 <WarningLevel>Level3</WarningLevel>
567 <AdditionalIncludeDirectories>$(SolutionDir)..\..\..\Lua54\include;$(SolutionDir)..</AdditionalIncludeDirectories>
568 <LanguageStandard>stdcpp20</LanguageStandard>
569 <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
570 </ClCompile>
571 <Link>
572 <GenerateDebugInformation>true</GenerateDebugInformation>
573 <SubSystem>Console</SubSystem>
574 <AdditionalLibraryDirectories>$(SolutionDir)..\..\..\Lua54\bin\$(Platform)\Debug;$(SolutionDir)..\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.1.8.1.7\lib\native\v140\windesktop\msvcstl\static\rt-dyn\x64\Debug</AdditionalLibraryDirectories>
575 <AdditionalDependencies>lua54.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
576 <IgnoreSpecificDefaultLibraries>
577 </IgnoreSpecificDefaultLibraries>
578 </Link>
579 </ItemDefinitionGroup>
580 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|x64'">
581 <ClCompile>
582 <PrecompiledHeader>Use</PrecompiledHeader>
583 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile>
584 <Optimization>Disabled</Optimization>
585 <PreprocessorDefinitions>LANES_DEBUG;X64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
586 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
587 <WarningLevel>Level3</WarningLevel>
480 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories> 588 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories>
481 <LanguageStandard>stdcpp20</LanguageStandard> 589 <LanguageStandard>stdcpp20</LanguageStandard>
482 <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> 590 <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
@@ -494,7 +602,7 @@
494 <ClCompile> 602 <ClCompile>
495 <PrecompiledHeader>Use</PrecompiledHeader> 603 <PrecompiledHeader>Use</PrecompiledHeader>
496 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile> 604 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile>
497 <PreprocessorDefinitions>X64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> 605 <PreprocessorDefinitions>LANES_DEBUG;X64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
498 <WarningLevel>Level3</WarningLevel> 606 <WarningLevel>Level3</WarningLevel>
499 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories> 607 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories>
500 <LanguageStandard>stdcpp20</LanguageStandard> 608 <LanguageStandard>stdcpp20</LanguageStandard>
@@ -555,7 +663,7 @@
555 <PrecompiledHeader>Use</PrecompiledHeader> 663 <PrecompiledHeader>Use</PrecompiledHeader>
556 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile> 664 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile>
557 <Optimization>Disabled</Optimization> 665 <Optimization>Disabled</Optimization>
558 <PreprocessorDefinitions>X64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> 666 <PreprocessorDefinitions>LANES_DEBUG;X64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
559 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> 667 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
560 <WarningLevel>Level3</WarningLevel> 668 <WarningLevel>Level3</WarningLevel>
561 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories> 669 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories>
@@ -575,7 +683,7 @@
575 <ClCompile> 683 <ClCompile>
576 <PrecompiledHeader>Use</PrecompiledHeader> 684 <PrecompiledHeader>Use</PrecompiledHeader>
577 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile> 685 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile>
578 <PreprocessorDefinitions>X64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> 686 <PreprocessorDefinitions>LANES_DEBUG;X64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
579 <WarningLevel>Level3</WarningLevel> 687 <WarningLevel>Level3</WarningLevel>
580 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories> 688 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories>
581 <LanguageStandard>stdcpp20</LanguageStandard> 689 <LanguageStandard>stdcpp20</LanguageStandard>
@@ -636,7 +744,7 @@
636 <PrecompiledHeader>Use</PrecompiledHeader> 744 <PrecompiledHeader>Use</PrecompiledHeader>
637 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile> 745 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile>
638 <Optimization>Disabled</Optimization> 746 <Optimization>Disabled</Optimization>
639 <PreprocessorDefinitions>X64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> 747 <PreprocessorDefinitions>LANES_DEBUG;X64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
640 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> 748 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
641 <WarningLevel>Level3</WarningLevel> 749 <WarningLevel>Level3</WarningLevel>
642 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories> 750 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories>
@@ -656,7 +764,7 @@
656 <ClCompile> 764 <ClCompile>
657 <PrecompiledHeader>Use</PrecompiledHeader> 765 <PrecompiledHeader>Use</PrecompiledHeader>
658 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile> 766 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile>
659 <PreprocessorDefinitions>X64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> 767 <PreprocessorDefinitions>LANES_DEBUG;X64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
660 <WarningLevel>Level3</WarningLevel> 768 <WarningLevel>Level3</WarningLevel>
661 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories> 769 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories>
662 <LanguageStandard>stdcpp20</LanguageStandard> 770 <LanguageStandard>stdcpp20</LanguageStandard>
@@ -717,7 +825,7 @@
717 <PrecompiledHeader>Use</PrecompiledHeader> 825 <PrecompiledHeader>Use</PrecompiledHeader>
718 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile> 826 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile>
719 <Optimization>Disabled</Optimization> 827 <Optimization>Disabled</Optimization>
720 <PreprocessorDefinitions>X64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> 828 <PreprocessorDefinitions>LANES_DEBUG;X64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
721 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> 829 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
722 <WarningLevel>Level3</WarningLevel> 830 <WarningLevel>Level3</WarningLevel>
723 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories> 831 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories>
@@ -738,7 +846,7 @@
738 <PrecompiledHeader>Use</PrecompiledHeader> 846 <PrecompiledHeader>Use</PrecompiledHeader>
739 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile> 847 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile>
740 <Optimization>Disabled</Optimization> 848 <Optimization>Disabled</Optimization>
741 <PreprocessorDefinitions>X64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> 849 <PreprocessorDefinitions>LANES_DEBUG;X64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
742 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> 850 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
743 <WarningLevel>Level3</WarningLevel> 851 <WarningLevel>Level3</WarningLevel>
744 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories> 852 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories>
@@ -800,7 +908,26 @@
800 <ClCompile> 908 <ClCompile>
801 <PrecompiledHeader>Use</PrecompiledHeader> 909 <PrecompiledHeader>Use</PrecompiledHeader>
802 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile> 910 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile>
803 <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> 911 <PreprocessorDefinitions>LANES_DEBUG;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
912 <WarningLevel>Level3</WarningLevel>
913 <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
914 <LanguageStandard>stdcpp20</LanguageStandard>
915 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories>
916 </ClCompile>
917 <Link>
918 <GenerateDebugInformation>true</GenerateDebugInformation>
919 <SubSystem>Console</SubSystem>
920 <OptimizeReferences>true</OptimizeReferences>
921 <EnableCOMDATFolding>true</EnableCOMDATFolding>
922 <AdditionalDependencies>lua54.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
923 <AdditionalLibraryDirectories>$(SolutionDir)_LuaVersions\$(PlatformName)\$(ConfigurationName)</AdditionalLibraryDirectories>
924 </Link>
925 </ItemDefinitionGroup>
926 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.5|Win32'">
927 <ClCompile>
928 <PrecompiledHeader>Use</PrecompiledHeader>
929 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile>
930 <PreprocessorDefinitions>LANES_DEBUG;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
804 <WarningLevel>Level3</WarningLevel> 931 <WarningLevel>Level3</WarningLevel>
805 <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> 932 <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
806 <LanguageStandard>stdcpp20</LanguageStandard> 933 <LanguageStandard>stdcpp20</LanguageStandard>
@@ -819,7 +946,7 @@
819 <ClCompile> 946 <ClCompile>
820 <PrecompiledHeader>Use</PrecompiledHeader> 947 <PrecompiledHeader>Use</PrecompiledHeader>
821 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile> 948 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile>
822 <PreprocessorDefinitions>X64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> 949 <PreprocessorDefinitions>LANES_DEBUG;X64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
823 <WarningLevel>Level3</WarningLevel> 950 <WarningLevel>Level3</WarningLevel>
824 <LanguageStandard>stdcpp20</LanguageStandard> 951 <LanguageStandard>stdcpp20</LanguageStandard>
825 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories> 952 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories>
@@ -833,6 +960,24 @@
833 <AdditionalDependencies>lua54.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies> 960 <AdditionalDependencies>lua54.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
834 </Link> 961 </Link>
835 </ItemDefinitionGroup> 962 </ItemDefinitionGroup>
963 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.5|x64'">
964 <ClCompile>
965 <PrecompiledHeader>Use</PrecompiledHeader>
966 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile>
967 <PreprocessorDefinitions>LANES_DEBUG;X64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
968 <WarningLevel>Level3</WarningLevel>
969 <LanguageStandard>stdcpp20</LanguageStandard>
970 <AdditionalIncludeDirectories>$(SolutionDir)/_LuaVersions/$(PlatformName)/$(ConfigurationName)/include;$(SolutionDir)..</AdditionalIncludeDirectories>
971 </ClCompile>
972 <Link>
973 <GenerateDebugInformation>true</GenerateDebugInformation>
974 <SubSystem>Console</SubSystem>
975 <OptimizeReferences>true</OptimizeReferences>
976 <EnableCOMDATFolding>true</EnableCOMDATFolding>
977 <AdditionalLibraryDirectories>$(SolutionDir)_LuaVersions\$(PlatformName)\$(ConfigurationName)</AdditionalLibraryDirectories>
978 <AdditionalDependencies>lua55.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
979 </Link>
980 </ItemDefinitionGroup>
836 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.4|Prospero'"> 981 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.4|Prospero'">
837 <ClCompile> 982 <ClCompile>
838 <PrecompiledHeader>Use</PrecompiledHeader> 983 <PrecompiledHeader>Use</PrecompiledHeader>
@@ -852,6 +997,25 @@
852 <AdditionalDependencies>lua54.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies> 997 <AdditionalDependencies>lua54.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
853 </Link> 998 </Link>
854 </ItemDefinitionGroup> 999 </ItemDefinitionGroup>
1000 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.5|Prospero'">
1001 <ClCompile>
1002 <PrecompiledHeader>Use</PrecompiledHeader>
1003 <PrecompiledHeaderFile>_pch.hpp</PrecompiledHeaderFile>
1004 <PreprocessorDefinitions>X64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
1005 <WarningLevel>Level3</WarningLevel>
1006 <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
1007 <LanguageStandard>stdcpp20</LanguageStandard>
1008 <AdditionalIncludeDirectories>$(SolutionDir)..\..\..\Lua54\include;$(SolutionDir)..</AdditionalIncludeDirectories>
1009 </ClCompile>
1010 <Link>
1011 <GenerateDebugInformation>true</GenerateDebugInformation>
1012 <SubSystem>Console</SubSystem>
1013 <OptimizeReferences>true</OptimizeReferences>
1014 <EnableCOMDATFolding>true</EnableCOMDATFolding>
1015 <AdditionalLibraryDirectories>$(SolutionDir)..\..\..\Lua54\bin\$(Platform)\Release;$(SolutionDir)..\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.1.8.1.7\lib\native\v140\windesktop\msvcstl\static\rt-dyn\x64\Release</AdditionalLibraryDirectories>
1016 <AdditionalDependencies>lua54.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
1017 </Link>
1018 </ItemDefinitionGroup>
855 <ItemGroup> 1019 <ItemGroup>
856 <ClInclude Include="..\src\compat.hpp" /> 1020 <ClInclude Include="..\src\compat.hpp" />
857 <ClInclude Include="..\src\deep.hpp" /> 1021 <ClInclude Include="..\src\deep.hpp" />
@@ -864,11 +1028,13 @@
864 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|Win32'">NotUsing</PrecompiledHeader> 1028 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|Win32'">NotUsing</PrecompiledHeader>
865 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.3|Win32'">NotUsing</PrecompiledHeader> 1029 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.3|Win32'">NotUsing</PrecompiledHeader>
866 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|Win32'">NotUsing</PrecompiledHeader> 1030 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|Win32'">NotUsing</PrecompiledHeader>
1031 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.5|Win32'">NotUsing</PrecompiledHeader>
867 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.1|Win32'">NotUsing</PrecompiledHeader> 1032 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.1|Win32'">NotUsing</PrecompiledHeader>
868 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.1|Win32'">NotUsing</PrecompiledHeader> 1033 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.1|Win32'">NotUsing</PrecompiledHeader>
869 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release LuaJIT|Win32'">NotUsing</PrecompiledHeader> 1034 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release LuaJIT|Win32'">NotUsing</PrecompiledHeader>
870 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release MoonJIT|Win32'">NotUsing</PrecompiledHeader> 1035 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release MoonJIT|Win32'">NotUsing</PrecompiledHeader>
871 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.4|Win32'">NotUsing</PrecompiledHeader> 1036 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.4|Win32'">NotUsing</PrecompiledHeader>
1037 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.5|Win32'">NotUsing</PrecompiledHeader>
872 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.2|Win32'">NotUsing</PrecompiledHeader> 1038 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.2|Win32'">NotUsing</PrecompiledHeader>
873 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.2|Win32'">NotUsing</PrecompiledHeader> 1039 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.2|Win32'">NotUsing</PrecompiledHeader>
874 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|x64'">NotUsing</PrecompiledHeader> 1040 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|x64'">NotUsing</PrecompiledHeader>
@@ -876,7 +1042,9 @@
876 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|Prospero'">NotUsing</PrecompiledHeader> 1042 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|Prospero'">NotUsing</PrecompiledHeader>
877 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.3|Prospero'">NotUsing</PrecompiledHeader> 1043 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.3|Prospero'">NotUsing</PrecompiledHeader>
878 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|x64'">NotUsing</PrecompiledHeader> 1044 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|x64'">NotUsing</PrecompiledHeader>
1045 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.5|x64'">NotUsing</PrecompiledHeader>
879 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|Prospero'">NotUsing</PrecompiledHeader> 1046 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|Prospero'">NotUsing</PrecompiledHeader>
1047 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.5|Prospero'">NotUsing</PrecompiledHeader>
880 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.1|x64'">NotUsing</PrecompiledHeader> 1048 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.1|x64'">NotUsing</PrecompiledHeader>
881 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.1|x64'">NotUsing</PrecompiledHeader> 1049 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.1|x64'">NotUsing</PrecompiledHeader>
882 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.1|Prospero'">NotUsing</PrecompiledHeader> 1050 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.1|Prospero'">NotUsing</PrecompiledHeader>
@@ -886,7 +1054,9 @@
886 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release LuaJIT|Prospero'">NotUsing</PrecompiledHeader> 1054 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release LuaJIT|Prospero'">NotUsing</PrecompiledHeader>
887 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release MoonJIT|Prospero'">NotUsing</PrecompiledHeader> 1055 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release MoonJIT|Prospero'">NotUsing</PrecompiledHeader>
888 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.4|x64'">NotUsing</PrecompiledHeader> 1056 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.4|x64'">NotUsing</PrecompiledHeader>
1057 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.5|x64'">NotUsing</PrecompiledHeader>
889 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.4|Prospero'">NotUsing</PrecompiledHeader> 1058 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.4|Prospero'">NotUsing</PrecompiledHeader>
1059 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.5|Prospero'">NotUsing</PrecompiledHeader>
890 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.2|x64'">NotUsing</PrecompiledHeader> 1060 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.2|x64'">NotUsing</PrecompiledHeader>
891 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.2|x64'">NotUsing</PrecompiledHeader> 1061 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.2|x64'">NotUsing</PrecompiledHeader>
892 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.2|Prospero'">NotUsing</PrecompiledHeader> 1062 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.2|Prospero'">NotUsing</PrecompiledHeader>
@@ -897,11 +1067,13 @@
897 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|Win32'">NotUsing</PrecompiledHeader> 1067 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|Win32'">NotUsing</PrecompiledHeader>
898 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.3|Win32'">NotUsing</PrecompiledHeader> 1068 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.3|Win32'">NotUsing</PrecompiledHeader>
899 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|Win32'">NotUsing</PrecompiledHeader> 1069 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|Win32'">NotUsing</PrecompiledHeader>
1070 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.5|Win32'">NotUsing</PrecompiledHeader>
900 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.1|Win32'">NotUsing</PrecompiledHeader> 1071 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.1|Win32'">NotUsing</PrecompiledHeader>
901 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.1|Win32'">NotUsing</PrecompiledHeader> 1072 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.1|Win32'">NotUsing</PrecompiledHeader>
902 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release LuaJIT|Win32'">NotUsing</PrecompiledHeader> 1073 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release LuaJIT|Win32'">NotUsing</PrecompiledHeader>
903 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release MoonJIT|Win32'">NotUsing</PrecompiledHeader> 1074 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release MoonJIT|Win32'">NotUsing</PrecompiledHeader>
904 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.4|Win32'">NotUsing</PrecompiledHeader> 1075 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.4|Win32'">NotUsing</PrecompiledHeader>
1076 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.5|Win32'">NotUsing</PrecompiledHeader>
905 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.2|Win32'">NotUsing</PrecompiledHeader> 1077 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.2|Win32'">NotUsing</PrecompiledHeader>
906 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.2|Win32'">NotUsing</PrecompiledHeader> 1078 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.2|Win32'">NotUsing</PrecompiledHeader>
907 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|x64'">NotUsing</PrecompiledHeader> 1079 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|x64'">NotUsing</PrecompiledHeader>
@@ -909,7 +1081,9 @@
909 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|Prospero'">NotUsing</PrecompiledHeader> 1081 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|Prospero'">NotUsing</PrecompiledHeader>
910 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.3|Prospero'">NotUsing</PrecompiledHeader> 1082 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.3|Prospero'">NotUsing</PrecompiledHeader>
911 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|x64'">NotUsing</PrecompiledHeader> 1083 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|x64'">NotUsing</PrecompiledHeader>
1084 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.5|x64'">NotUsing</PrecompiledHeader>
912 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|Prospero'">NotUsing</PrecompiledHeader> 1085 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|Prospero'">NotUsing</PrecompiledHeader>
1086 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.5|Prospero'">NotUsing</PrecompiledHeader>
913 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.1|x64'">NotUsing</PrecompiledHeader> 1087 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.1|x64'">NotUsing</PrecompiledHeader>
914 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.1|x64'">NotUsing</PrecompiledHeader> 1088 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.1|x64'">NotUsing</PrecompiledHeader>
915 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.1|Prospero'">NotUsing</PrecompiledHeader> 1089 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.1|Prospero'">NotUsing</PrecompiledHeader>
@@ -919,7 +1093,9 @@
919 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release LuaJIT|Prospero'">NotUsing</PrecompiledHeader> 1093 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release LuaJIT|Prospero'">NotUsing</PrecompiledHeader>
920 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release MoonJIT|Prospero'">NotUsing</PrecompiledHeader> 1094 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release MoonJIT|Prospero'">NotUsing</PrecompiledHeader>
921 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.4|x64'">NotUsing</PrecompiledHeader> 1095 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.4|x64'">NotUsing</PrecompiledHeader>
1096 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.5|x64'">NotUsing</PrecompiledHeader>
922 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.4|Prospero'">NotUsing</PrecompiledHeader> 1097 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.4|Prospero'">NotUsing</PrecompiledHeader>
1098 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.5|Prospero'">NotUsing</PrecompiledHeader>
923 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.2|x64'">NotUsing</PrecompiledHeader> 1099 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.2|x64'">NotUsing</PrecompiledHeader>
924 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.2|x64'">NotUsing</PrecompiledHeader> 1100 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.2|x64'">NotUsing</PrecompiledHeader>
925 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.2|Prospero'">NotUsing</PrecompiledHeader> 1101 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.2|Prospero'">NotUsing</PrecompiledHeader>
@@ -934,6 +1110,7 @@
934 <ClCompile Include="init_and_shutdown.cpp" /> 1110 <ClCompile Include="init_and_shutdown.cpp" />
935 <ClCompile Include="_pch.cpp"> 1111 <ClCompile Include="_pch.cpp">
936 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|Win32'">Create</PrecompiledHeader> 1112 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|Win32'">Create</PrecompiledHeader>
1113 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.5|Win32'">Create</PrecompiledHeader>
937 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|Win32'">Create</PrecompiledHeader> 1114 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|Win32'">Create</PrecompiledHeader>
938 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.3|Win32'">Create</PrecompiledHeader> 1115 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.3|Win32'">Create</PrecompiledHeader>
939 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.2|Win32'">Create</PrecompiledHeader> 1116 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.2|Win32'">Create</PrecompiledHeader>
@@ -943,8 +1120,11 @@
943 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release LuaJIT|Win32'">Create</PrecompiledHeader> 1120 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release LuaJIT|Win32'">Create</PrecompiledHeader>
944 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release MoonJIT|Win32'">Create</PrecompiledHeader> 1121 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release MoonJIT|Win32'">Create</PrecompiledHeader>
945 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.4|Win32'">Create</PrecompiledHeader> 1122 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.4|Win32'">Create</PrecompiledHeader>
1123 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.5|Win32'">Create</PrecompiledHeader>
946 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|x64'">Create</PrecompiledHeader> 1124 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|x64'">Create</PrecompiledHeader>
1125 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.5|x64'">Create</PrecompiledHeader>
947 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|Prospero'">Create</PrecompiledHeader> 1126 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|Prospero'">Create</PrecompiledHeader>
1127 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.5|Prospero'">Create</PrecompiledHeader>
948 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|x64'">Create</PrecompiledHeader> 1128 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|x64'">Create</PrecompiledHeader>
949 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.3|x64'">Create</PrecompiledHeader> 1129 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.3|x64'">Create</PrecompiledHeader>
950 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|Prospero'">Create</PrecompiledHeader> 1130 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|Prospero'">Create</PrecompiledHeader>
@@ -962,13 +1142,28 @@
962 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release LuaJIT|Prospero'">Create</PrecompiledHeader> 1142 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release LuaJIT|Prospero'">Create</PrecompiledHeader>
963 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release MoonJIT|Prospero'">Create</PrecompiledHeader> 1143 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release MoonJIT|Prospero'">Create</PrecompiledHeader>
964 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.4|x64'">Create</PrecompiledHeader> 1144 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.4|x64'">Create</PrecompiledHeader>
1145 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.5|x64'">Create</PrecompiledHeader>
965 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.4|Prospero'">Create</PrecompiledHeader> 1146 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.4|Prospero'">Create</PrecompiledHeader>
1147 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release 5.5|Prospero'">Create</PrecompiledHeader>
966 </ClCompile> 1148 </ClCompile>
967 </ItemGroup> 1149 </ItemGroup>
968 <ItemGroup> 1150 <ItemGroup>
969 <None Include="..\.runsettings" /> 1151 <None Include="..\.runsettings" />
1152 <None Include="scripts\coro\cancelling_suspended.lua" />
1153 <None Include="scripts\coro\collect_yielded_lane.lua" />
1154 <None Include="scripts\coro\join_suspended.lua" />
1155 <None Include="scripts\coro\linda_in_close_handler.lua" />
1156 <None Include="scripts\coro\regular_function.lua" />
1157 <None Include="scripts\coro\resume_basics.lua" />
1158 <None Include="scripts\coro\yielding_in_non_coro_errors.lua" />
1159 <None Include="scripts\lane\body_is_a_c_function.lua" />
1160 <None Include="scripts\lane\tasking_cancelling_with_hook.lua" />
1161 <None Include="scripts\linda\send_receive_func_and_string.lua" />
1162 <None Include="scripts\linda\wake_period.lua" />
1163 <None Include="scripts\misc\deeptest.lua" />
1164 <None Include="scripts\_utils54.lua" />
970 <None Include="UnitTests.makefile" /> 1165 <None Include="UnitTests.makefile" />
971 <None Include="scripts\coro\basics.lua" /> 1166 <None Include="scripts\coro\index_suspended.lua" />
972 <None Include="scripts\coro\error_handling.lua" /> 1167 <None Include="scripts\coro\error_handling.lua" />
973 <None Include="scripts\lane\cooperative_shutdown.lua" /> 1168 <None Include="scripts\lane\cooperative_shutdown.lua" />
974 <None Include="scripts\lane\stdlib_naming.lua" /> 1169 <None Include="scripts\lane\stdlib_naming.lua" />
diff --git a/unit_tests/UnitTests.vcxproj.filters b/unit_tests/UnitTests.vcxproj.filters
index 3b45009..df82447 100644
--- a/unit_tests/UnitTests.vcxproj.filters
+++ b/unit_tests/UnitTests.vcxproj.filters
@@ -54,6 +54,9 @@
54 <Filter Include="Make"> 54 <Filter Include="Make">
55 <UniqueIdentifier>{c62af5d9-9161-4ca1-9b58-6837e2907e35}</UniqueIdentifier> 55 <UniqueIdentifier>{c62af5d9-9161-4ca1-9b58-6837e2907e35}</UniqueIdentifier>
56 </Filter> 56 </Filter>
57 <Filter Include="Scripts\misc">
58 <UniqueIdentifier>{1fbb1341-2f93-4eaa-924c-1df79e083704}</UniqueIdentifier>
59 </Filter>
57 </ItemGroup> 60 </ItemGroup>
58 <ItemGroup> 61 <ItemGroup>
59 <None Include="scripts\linda\send_receive.lua"> 62 <None Include="scripts\linda\send_receive.lua">
@@ -95,7 +98,7 @@
95 <None Include="scripts\lane\tasking_join_test.lua"> 98 <None Include="scripts\lane\tasking_join_test.lua">
96 <Filter>Scripts\lane</Filter> 99 <Filter>Scripts\lane</Filter>
97 </None> 100 </None>
98 <None Include="scripts\coro\basics.lua"> 101 <None Include="scripts\coro\index_suspended.lua">
99 <Filter>Scripts\coro</Filter> 102 <Filter>Scripts\coro</Filter>
100 </None> 103 </None>
101 <None Include="scripts\coro\error_handling.lua"> 104 <None Include="scripts\coro\error_handling.lua">
@@ -113,5 +116,44 @@
113 <None Include="..\.runsettings"> 116 <None Include="..\.runsettings">
114 <Filter>Catch2</Filter> 117 <Filter>Catch2</Filter>
115 </None> 118 </None>
119 <None Include="scripts\lane\tasking_cancelling_with_hook.lua">
120 <Filter>Scripts\lane</Filter>
121 </None>
122 <None Include="scripts\linda\wake_period.lua">
123 <Filter>Scripts\linda</Filter>
124 </None>
125 <None Include="scripts\coro\collect_yielded_lane.lua">
126 <Filter>Scripts\coro</Filter>
127 </None>
128 <None Include="scripts\lane\body_is_a_c_function.lua">
129 <Filter>Scripts\lane</Filter>
130 </None>
131 <None Include="scripts\coro\regular_function.lua">
132 <Filter>Scripts\coro</Filter>
133 </None>
134 <None Include="scripts\coro\yielding_in_non_coro_errors.lua">
135 <Filter>Scripts\coro</Filter>
136 </None>
137 <None Include="scripts\coro\resume_basics.lua">
138 <Filter>Scripts\coro</Filter>
139 </None>
140 <None Include="scripts\coro\join_suspended.lua">
141 <Filter>Scripts\coro</Filter>
142 </None>
143 <None Include="scripts\_utils54.lua">
144 <Filter>Scripts</Filter>
145 </None>
146 <None Include="scripts\coro\linda_in_close_handler.lua">
147 <Filter>Scripts\coro</Filter>
148 </None>
149 <None Include="scripts\coro\cancelling_suspended.lua">
150 <Filter>Scripts\coro</Filter>
151 </None>
152 <None Include="scripts\linda\send_receive_func_and_string.lua">
153 <Filter>Scripts\linda</Filter>
154 </None>
155 <None Include="scripts\misc\deeptest.lua">
156 <Filter>Scripts\misc</Filter>
157 </None>
116 </ItemGroup> 158 </ItemGroup>
117</Project> \ No newline at end of file 159</Project> \ No newline at end of file
diff --git a/unit_tests/_pch.hpp b/unit_tests/_pch.hpp
index 1e98c5a..f6e5fff 100644
--- a/unit_tests/_pch.hpp
+++ b/unit_tests/_pch.hpp
@@ -1,5 +1,3 @@
1#pragma once
2
3#include <atomic> 1#include <atomic>
4#include <cassert> 2#include <cassert>
5#include <filesystem> 3#include <filesystem>
diff --git a/unit_tests/deep_tests.cpp b/unit_tests/deep_tests.cpp
index e21072c..f18ff81 100644
--- a/unit_tests/deep_tests.cpp
+++ b/unit_tests/deep_tests.cpp
@@ -92,4 +92,13 @@ TEST_CASE("misc.deep_userdata.example")
92 " assert(due.get_deep_count() == 0)" 92 " assert(due.get_deep_count() == 0)"
93 ); 93 );
94 } 94 }
95} \ No newline at end of file 95}
96
97#define MAKE_TEST_CASE(DIR, FILE, CONDITION) \
98 TEST_CASE("scripted_tests." #DIR "." #FILE) \
99 { \
100 FileRunner _runner(R"(.\unit_tests\scripts)"); \
101 _runner.performTest(FileRunnerParam{ #DIR "/" #FILE, TestType::CONDITION }); \
102 }
103
104MAKE_TEST_CASE(misc, deeptest, AssertNoLuaError)
diff --git a/unit_tests/embedded_tests.cpp b/unit_tests/embedded_tests.cpp
index 9a262d5..388548d 100644
--- a/unit_tests/embedded_tests.cpp
+++ b/unit_tests/embedded_tests.cpp
@@ -2,6 +2,7 @@
2#include "shared.h" 2#include "shared.h"
3#include "lanes/src/lanes.hpp" 3#include "lanes/src/lanes.hpp"
4 4
5#if defined __has_include && __has_include(<windows.h>)
5#include <windows.h> 6#include <windows.h>
6 7
7// ################################################################################################# 8// #################################################################################################
@@ -138,13 +139,13 @@ namespace
138 139
139// ################################################################################################# 140// #################################################################################################
140 141
141TEST_CASE("lanes.embedding.with default allocator") 142TEST_CASE("lanes.embedding.with_default_allocator")
142{ 143{
143 local::EmbeddedLuaState S; 144 local::EmbeddedLuaState S;
144 145
145 // --------------------------------------------------------------------------------------------- 146 // ---------------------------------------------------------------------------------------------
146 147
147 SECTION("single state") 148 SECTION("single_state")
148 { 149 {
149 // this sends data in a linda. current contents: 150 // this sends data in a linda. current contents:
150 // key: short string 151 // key: short string
@@ -157,7 +158,7 @@ TEST_CASE("lanes.embedding.with default allocator")
157 // function with an upvalue 158 // function with an upvalue
158 std::string_view const _script{ 159 std::string_view const _script{
159 " local lanes = require 'lanes'.configure{with_timers = false}" 160 " local lanes = require 'lanes'.configure{with_timers = false}"
160 " local l = lanes.linda'gleh'" 161 " local l = lanes.linda{name = 'gleh'}"
161 " local upvalue = 'oeauaoeuoeuaoeuaoeujaoefubycfjbycfybcfjybcfjybcfjbcf'" 162 " local upvalue = 'oeauaoeuoeuaoeuaoeujaoefubycfjbycfybcfjybcfjybcfjbcf'"
162 " local upvalued = function()" 163 " local upvalued = function()"
163 " return upvalue" 164 " return upvalue"
@@ -171,7 +172,7 @@ TEST_CASE("lanes.embedding.with default allocator")
171 172
172 // --------------------------------------------------------------------------------------------- 173 // ---------------------------------------------------------------------------------------------
173 174
174 SECTION("manual registration") 175 SECTION("manual_registration")
175 { 176 {
176 S.requireSuccess("require 'lanes'.configure{with_timers = false}"); 177 S.requireSuccess("require 'lanes'.configure{with_timers = false}");
177 178
@@ -183,7 +184,7 @@ TEST_CASE("lanes.embedding.with default allocator")
183 // try to send io.open into a linda, which fails if io base library is not loaded 184 // try to send io.open into a linda, which fails if io base library is not loaded
184 std::string_view const _script{ 185 std::string_view const _script{
185 " local lanes = require 'lanes'" 186 " local lanes = require 'lanes'"
186 " local l = lanes.linda'gleh'" 187 " local l = lanes.linda{name = 'gleh'}"
187 " l:set('yo', io.open)" 188 " l:set('yo', io.open)"
188 " return 'SUCCESS'" 189 " return 'SUCCESS'"
189 }; 190 };
@@ -191,7 +192,7 @@ TEST_CASE("lanes.embedding.with default allocator")
191 192
192 // try again after manual registration 193 // try again after manual registration
193 lua_pushcfunction(S, S.get_lanes_register()); // S: lanes_register 194 lua_pushcfunction(S, S.get_lanes_register()); // S: lanes_register
194 luaG_pushstring(S, LUA_IOLIBNAME); // S: lanes_register "io" 195 luaW_pushstring(S, LUA_IOLIBNAME); // S: lanes_register "io"
195 luaL_requiref(S, LUA_IOLIBNAME, luaopen_io, 1); // S: lanes_register "io" io 196 luaL_requiref(S, LUA_IOLIBNAME, luaopen_io, 1); // S: lanes_register "io" io
196 lua_call(S, 2, 0); // S: 197 lua_call(S, 2, 0); // S:
197 S.stackCheck(0); 198 S.stackCheck(0);
@@ -202,7 +203,8 @@ TEST_CASE("lanes.embedding.with default allocator")
202// ################################################################################################# 203// #################################################################################################
203 204
204// this is not really a test yet, just something sitting here until it is converted properly 205// this is not really a test yet, just something sitting here until it is converted properly
205TEST_CASE("lanes.embedding.with custom allocator") 206// currently it crashes with moonjit (but maybe I just need a more recent moonjit version)
207TEST_CASE("lanes.embedding.with_custom_allocator")
206{ 208{
207 static constexpr auto logPrint = +[](lua_State* L) { 209 static constexpr auto logPrint = +[](lua_State* L) {
208 lua_getglobal(L, "ID"); // ID 210 lua_getglobal(L, "ID"); // ID
@@ -218,7 +220,7 @@ TEST_CASE("lanes.embedding.with custom allocator")
218 220
219 static constexpr auto launch_lane = +[](lua_CFunction on_state_create_, int id_, int n_) { 221 static constexpr auto launch_lane = +[](lua_CFunction on_state_create_, int id_, int n_) {
220 char script[500]; 222 char script[500];
221 lua_State* L = lua_newstate(local::allocf, nullptr); 223 lua_State* L = luaW_newstate(local::allocf, nullptr, luaL_makeseed(nullptr));
222 // _G.ID = id_ 224 // _G.ID = id_
223 luaL_openlibs(L); 225 luaL_openlibs(L);
224 luaL_dostring(L, "lanes = require 'lanes'"); 226 luaL_dostring(L, "lanes = require 'lanes'");
@@ -264,4 +266,6 @@ TEST_CASE("lanes.embedding.with custom allocator")
264 lua_close(L3); 266 lua_close(L3);
265 lua_close(L2); 267 lua_close(L2);
266 lua_close(L1); 268 lua_close(L1);
267} \ No newline at end of file 269}
270
271#endif // windows.h
diff --git a/unit_tests/init_and_shutdown.cpp b/unit_tests/init_and_shutdown.cpp
index b8174fd..69e4f1b 100644
--- a/unit_tests/init_and_shutdown.cpp
+++ b/unit_tests/init_and_shutdown.cpp
@@ -3,7 +3,7 @@
3 3
4// ################################################################################################# 4// #################################################################################################
5 5
6TEST_CASE("lanes.require 'lanes'") 6TEST_CASE("Lua.require_lanes")
7{ 7{
8 LuaState L{ LuaState::WithBaseLibs{ false }, LuaState::WithFixture{ false } }; 8 LuaState L{ LuaState::WithBaseLibs{ false }, LuaState::WithFixture{ false } };
9 9
@@ -58,7 +58,7 @@ TEST_CASE("lanes.require 'lanes'")
58// ################################################################################################# 58// #################################################################################################
59 59
60// allocator should be "protected", a C function returning a suitable userdata, or nil 60// allocator should be "protected", a C function returning a suitable userdata, or nil
61TEST_CASE("lanes.configure.allocator") 61TEST_CASE("lanes.configure.allocator/bool_number_table_string")
62{ 62{
63 LuaState L{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } }; 63 LuaState L{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } };
64 64
@@ -90,49 +90,33 @@ TEST_CASE("lanes.configure.allocator")
90 90
91 // --------------------------------------------------------------------------------------------- 91 // ---------------------------------------------------------------------------------------------
92 92
93 SECTION("allocator = <Lua function>")
94 {
95 L.requireFailure("require 'lanes'.configure{allocator = function() return {}, 12, 'yoy' end}");
96 }
97
98 // ---------------------------------------------------------------------------------------------
99
100 SECTION("allocator = <bad C function>")
101 {
102 // a C function that doesn't return what we expect should cause an error too
103 // TODO: for some reason, we use os.getenv here because using 'print' as the culprit, the tests deadlock in Release builds
104 L.requireFailure("return type(require 'lanes'.configure{allocator = os.getenv})");
105 }
106
107 // ---------------------------------------------------------------------------------------------
108
109 SECTION("allocator = <string with a typo>") 93 SECTION("allocator = <string with a typo>")
110 { 94 {
111 // oops, a typo 95 // oops, a typo
112 L.requireFailure("require 'lanes'.configure{allocator = 'Protected'}"); 96 L.requireFailure("require 'lanes'.configure{allocator = 'Protected'}");
113 } 97 }
98}
99
100// #################################################################################################
101
102TEST_CASE("lanes.configure.allocator/bad_functions")
103{
104 LuaState L{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } };
114 105
115 // --------------------------------------------------------------------------------------------- 106 // ---------------------------------------------------------------------------------------------
116 107
117 SECTION("allocator = 'protected'") 108 SECTION("allocator = <Lua function>")
118 { 109 {
119 // no typo, should work 110 L.requireFailure("require 'lanes'.configure{allocator = function() return {}, 12, 'yoy' end}");
120 L.requireSuccess("require 'lanes'.configure{allocator = 'protected'}");
121 } 111 }
122 112
123 // --------------------------------------------------------------------------------------------- 113 // ---------------------------------------------------------------------------------------------
124 114
125 SECTION("allocator = <good custom C allocator>") 115 SECTION("allocator = <bad C function>")
126 { 116 {
127 // a function that provides what we expect is fine 117 // a C function that doesn't return what we expect should cause an error too
128 static constexpr lua_CFunction _provideAllocator = +[](lua_State* const L_) { 118 // TODO: for some reason, we use os.getenv here because using 'print' as the culprit, the tests deadlock in Release builds
129 lanes::AllocatorDefinition* const _def{ new (L_) lanes::AllocatorDefinition{} }; 119 L.requireFailure("return type(require 'lanes'.configure{allocator = os.getenv})");
130 _def->initFrom(L_);
131 return 1;
132 };
133 lua_pushcfunction(L, _provideAllocator);
134 lua_setglobal(L, "ProvideAllocator");
135 L.requireSuccess("require 'lanes'.configure{allocator = ProvideAllocator}");
136 } 120 }
137 121
138 // --------------------------------------------------------------------------------------------- 122 // ---------------------------------------------------------------------------------------------
@@ -191,6 +175,39 @@ TEST_CASE("lanes.configure.allocator")
191 175
192// ################################################################################################# 176// #################################################################################################
193 177
178TEST_CASE("lanes.configure.allocator/good_function")
179{
180 LuaState L{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } };
181
182 SECTION("allocator = <good custom C allocator>")
183 {
184 // a function that provides what we expect is fine
185 static constexpr lua_CFunction _provideAllocator = +[](lua_State* const L_) {
186 lanes::AllocatorDefinition* const _def{ new (L_) lanes::AllocatorDefinition{} };
187 _def->initFrom(L_);
188 return 1;
189 };
190 lua_pushcfunction(L, _provideAllocator);
191 lua_setglobal(L, "ProvideAllocator");
192 L.requireSuccess("require 'lanes'.configure{allocator = ProvideAllocator}");
193 }
194}
195
196// #################################################################################################
197
198// TODO: investigate why this test crashes under AppVerifier on lanes_core.dll unload when running against Lua 5.1, 5.2 and 5.4 RELEASE ONLY!
199// apparently, the mutex of ProtectedAllocator is deemed still in use. Crash goes away if I don't use it in protected_lua_Alloc
200TEST_CASE(("lanes.configure.allocator/protected"))
201{
202 LuaState L{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } };
203
204 // no typo, should work
205 L.requireSuccess("require 'lanes'.configure{allocator = 'protected'}");
206}
207
208
209// #################################################################################################
210
194TEST_CASE("lanes.configure.internal_allocator") 211TEST_CASE("lanes.configure.internal_allocator")
195{ 212{
196 LuaState L{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } }; 213 LuaState L{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } };
@@ -289,388 +306,467 @@ TEST_CASE("lanes.configure.keepers_gc_threshold")
289 306
290// ################################################################################################# 307// #################################################################################################
291 308
292TEST_CASE("lanes.configure.the rest") 309TEST_CASE("lanes.configure.linda_wake_period")
293{ 310{
294 LuaState L{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } }; 311 LuaState L{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } };
295 312
313 // linda_wake_period should be a number > 0, or 'never'
314
315 SECTION("linda_wake_period = <table>")
316 {
317 L.requireFailure("require 'lanes'.configure{linda_wake_period = {}}");
318 }
296 319
297 // --------------------------------------------------------------------------------------------- 320 // ---------------------------------------------------------------------------------------------
298 // nb_user_keepers should be a number in [0, 100]
299 321
300 SECTION("nb_user_keepers") 322 SECTION("linda_wake_period = <string>")
301 { 323 {
302 SECTION("nb_user_keepers = <table>") 324 L.requireFailure("require 'lanes'.configure{linda_wake_period = 'gluh'}");
303 { 325 }
304 L.requireFailure("require 'lanes'.configure{nb_user_keepers = {}}");
305 }
306 326
307 // ----------------------------------------------------------------------------------------- 327 // ---------------------------------------------------------------------------------------------
308 328
309 SECTION("nb_user_keepers = <string>") 329 SECTION("linda_wake_period = 'never'")
310 { 330 {
311 L.requireFailure("require 'lanes'.configure{nb_user_keepers = 'gluh'}"); 331 L.requireSuccess("require 'lanes'.configure{linda_wake_period = 'never'}");
312 } 332 }
313 333
314 // ----------------------------------------------------------------------------------------- 334 // ---------------------------------------------------------------------------------------------
315 335
316 SECTION("nb_user_keepers = -1") 336 SECTION("linda_wake_period = <negative number>")
317 { 337 {
318 L.requireFailure("require 'lanes'.configure{nb_user_keepers = -1}"); 338 L.requireFailure("require 'lanes'.configure{linda_wake_period = -0.001}");
319 } 339 }
320 340
321 // ----------------------------------------------------------------------------------------- 341 // ---------------------------------------------------------------------------------------------
322 342
323 SECTION("nb_user_keepers = 0") 343 SECTION("linda_wake_period = 0")
324 { 344 {
325 L.requireSuccess("require 'lanes'.configure{nb_user_keepers = 0}"); 345 L.requireFailure("require 'lanes'.configure{linda_wake_period = 0}");
326 } 346 }
327 347
328 // ----------------------------------------------------------------------------------------- 348 // ---------------------------------------------------------------------------------------------
329 349
330 SECTION("nb_user_keepers = 100") 350 SECTION("linda_wake_period = 0.0001s")
331 { 351 {
332 L.requireSuccess("require 'lanes'.configure{nb_user_keepers = 100}"); 352 L.requireSuccess("require 'lanes'.configure{linda_wake_period = 0.0001}");
333 } 353 }
334 354
335 // ----------------------------------------------------------------------------------------- 355 // ---------------------------------------------------------------------------------------------
336 356
337 SECTION("nb_user_keepers = 101") 357 SECTION("linda_wake_period = 1e30")
338 { 358 {
339 L.requireFailure("require 'lanes'.configure{nb_user_keepers = 101}"); 359 L.requireSuccess("require 'lanes'.configure{linda_wake_period = 1e30}");
340 } 360 }
361}
362
363// #################################################################################################
364
365TEST_CASE("lanes.configure.nb_user_keepers")
366{
367 LuaState L{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } };
368
369 // nb_user_keepers should be a number in [0, 100]
370
371 SECTION("nb_user_keepers = <table>")
372 {
373 L.requireFailure("require 'lanes'.configure{nb_user_keepers = {}}");
341 } 374 }
342 375
343 // --------------------------------------------------------------------------------------------- 376 // ---------------------------------------------------------------------------------------------
344 // on_state_create should be a function, either C or Lua, without upvalues
345 377
346 SECTION("on_state_create") 378 SECTION("nb_user_keepers = <string>")
347 { 379 {
348 SECTION("on_state_create = <table>") 380 L.requireFailure("require 'lanes'.configure{nb_user_keepers = 'gluh'}");
349 { 381 }
350 L.requireFailure("require 'lanes'.configure{on_state_create = {}}");
351 }
352 382
353 // ----------------------------------------------------------------------------------------- 383 // ---------------------------------------------------------------------------------------------
354 384
355 SECTION("on_state_create = <string>") 385 SECTION("nb_user_keepers = -1")
356 { 386 {
357 L.requireFailure("require 'lanes'.configure{on_state_create = 'gluh'}"); 387 L.requireFailure("require 'lanes'.configure{nb_user_keepers = -1}");
358 } 388 }
359 389
360 // ----------------------------------------------------------------------------------------- 390 // ---------------------------------------------------------------------------------------------
361 391
362 SECTION("on_state_create = <number>") 392 SECTION("nb_user_keepers = 0")
363 { 393 {
364 L.requireFailure("require 'lanes'.configure{on_state_create = 1}"); 394 L.requireSuccess("require 'lanes'.configure{nb_user_keepers = 0}");
365 } 395 }
366 396
367 // ----------------------------------------------------------------------------------------- 397 // ---------------------------------------------------------------------------------------------
368 398
369 SECTION("on_state_create = false") 399 SECTION("nb_user_keepers = 1")
370 { 400 {
371 L.requireFailure("require 'lanes'.configure{on_state_create = false}"); 401 L.requireSuccess("require 'lanes'.configure{nb_user_keepers = 1}");
372 } 402 }
373 403
374 // ----------------------------------------------------------------------------------------- 404 // ---------------------------------------------------------------------------------------------
375 405
376 SECTION("on_state_create = true") 406 SECTION("nb_user_keepers = 100")
377 { 407 {
378 L.requireFailure("require 'lanes'.configure{on_state_create = true}"); 408 L.requireSuccess("require 'lanes'.configure{nb_user_keepers = 100}");
379 } 409 }
380 410
381 // ----------------------------------------------------------------------------------------- 411 // -----------------------------------------------------------------------------------------
382 412
383 SECTION("on_state_create = <Lua function>") 413 SECTION("nb_user_keepers = 101")
384 { 414 {
385 // on_state_create isn't called inside a Keeper state if it's a Lua function (which is good as print() doesn't exist there!) 415 L.requireFailure("require 'lanes'.configure{nb_user_keepers = 101}");
386 L.requireSuccess("local print = print; require 'lanes'.configure{on_state_create = function() print 'hello' end}"); 416 }
387 } 417}
388 418
389 // ----------------------------------------------------------------------------------------- 419// #################################################################################################
390 420
391 SECTION("on_state_create = <C function>") 421TEST_CASE("lanes.configure.on_state_create/configuration")
392 { 422{
393 // funnily enough, in Lua 5.3, print() uses global tostring(), that doesn't exist in a keeper since we didn't open libs -> "attempt to call a nil value" 423 LuaState L{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } };
394 // conclusion, don't use print() as a fake on_state_create() callback! 424
395 // assert() should be fine since we pass a non-false argument to on_state_create 425 // on_state_create should be a function, either C or Lua, without upvalues
396 L.requireSuccess("require 'lanes'.configure{on_state_create = assert}"); 426
397 } 427 SECTION("on_state_create = <table>")
428 {
429 L.requireFailure("require 'lanes'.configure{on_state_create = {}}");
398 } 430 }
399 431
400 // --------------------------------------------------------------------------------------------- 432 // ---------------------------------------------------------------------------------------------
401 // shutdown_timeout should be a number in [0,3600]
402 433
403 SECTION("shutdown_timeout") 434 SECTION("on_state_create = <string>")
404 { 435 {
405 SECTION("shutdown_timeout = <table>") 436 L.requireFailure("require 'lanes'.configure{on_state_create = 'gluh'}");
406 { 437 }
407 L.requireFailure("require 'lanes'.configure{shutdown_timeout = {}}");
408 }
409 438
410 // ----------------------------------------------------------------------------------------- 439 // ---------------------------------------------------------------------------------------------
411 440
412 SECTION("shutdown_timeout = <string>") 441 SECTION("on_state_create = <number>")
413 { 442 {
414 L.requireFailure("require 'lanes'.configure{shutdown_timeout = 'gluh'}"); 443 L.requireFailure("require 'lanes'.configure{on_state_create = 1}");
415 } 444 }
416 445
417 // ----------------------------------------------------------------------------------------- 446 // ---------------------------------------------------------------------------------------------
418 447
419 SECTION("shutdown_timeout = <negative number>") 448 SECTION("on_state_create = false")
420 { 449 {
421 L.requireFailure("require 'lanes'.configure{shutdown_timeout = -0.001}"); 450 L.requireFailure("require 'lanes'.configure{on_state_create = false}");
422 } 451 }
423 452
424 // ----------------------------------------------------------------------------------------- 453 // ---------------------------------------------------------------------------------------------
425 454
426 SECTION("shutdown_timeout = 0") 455 SECTION("on_state_create = true")
427 { 456 {
428 L.requireSuccess("require 'lanes'.configure{shutdown_timeout = 0}"); 457 L.requireFailure("require 'lanes'.configure{on_state_create = true}");
429 } 458 }
430 459
431 // ----------------------------------------------------------------------------------------- 460 // ---------------------------------------------------------------------------------------------
432 461
433 SECTION("shutdown_timeout = 1s") 462 SECTION("on_state_create = <Lua function>")
434 { 463 {
435 L.requireSuccess("require 'lanes'.configure{shutdown_timeout = 1}"); 464 // on_state_create isn't called inside a Keeper state if it's a Lua function (which is good as print() doesn't exist there!)
436 } 465 L.requireSuccess("local print = print; require 'lanes'.configure{on_state_create = function() print 'hello' end}");
466 }
437 467
438 // ----------------------------------------------------------------------------------------- 468 // ---------------------------------------------------------------------------------------------
439 469
440 SECTION("shutdown_timeout = 3600s") 470 SECTION("on_state_create = <C function>")
441 { 471 {
442 L.requireSuccess("require 'lanes'.configure{shutdown_timeout = 3600}"); 472 // funnily enough, in Lua 5.3, print() uses global tostring(), that doesn't exist in a keeper since we didn't open libs -> "attempt to call a nil value"
443 } 473 // conclusion, don't use print() as a fake on_state_create() callback!
474 // assert() should be fine since we pass a non-false argument to on_state_create
475 L.requireSuccess("require 'lanes'.configure{on_state_create = assert}");
476 }
477}
444 478
445 // ----------------------------------------------------------------------------------------- 479// #################################################################################################
446 480
447 SECTION("shutdown_timeout = <too long>") 481TEST_CASE("lanes.configure.shutdown_timeout")
448 { 482{
449 L.requireFailure("require 'lanes'.configure{shutdown_timeout = 3600.001}"); 483 LuaState L{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } };
450 } 484
485 // shutdown_timeout should be a number in [0,3600]
486
487 SECTION("shutdown_timeout = <table>")
488 {
489 L.requireFailure("require 'lanes'.configure{shutdown_timeout = {}}");
451 } 490 }
452 491
453 // --------------------------------------------------------------------------------------------- 492 // ---------------------------------------------------------------------------------------------
454 // strip_functions should be a boolean
455 493
456 SECTION("strip_functions") 494 SECTION("shutdown_timeout = <string>")
457 { 495 {
458 SECTION("strip_functions = <table>") 496 L.requireFailure("require 'lanes'.configure{shutdown_timeout = 'gluh'}");
459 { 497 }
460 L.requireFailure("require 'lanes'.configure{strip_functions = {}}");
461 }
462 498
463 // ----------------------------------------------------------------------------------------- 499 // ---------------------------------------------------------------------------------------------
464 500
465 SECTION("strip_functions = <string>") 501 SECTION("shutdown_timeout = <negative number>")
466 { 502 {
467 L.requireFailure("require 'lanes'.configure{strip_functions = 'gluh'}"); 503 L.requireFailure("require 'lanes'.configure{shutdown_timeout = -0.001}");
468 } 504 }
469 505
470 // ----------------------------------------------------------------------------------------- 506 // ---------------------------------------------------------------------------------------------
471 507
472 SECTION("strip_functions = <number>") 508 SECTION("shutdown_timeout = 0")
473 { 509 {
474 L.requireFailure("require 'lanes'.configure{strip_functions = 1}"); 510 L.requireSuccess("require 'lanes'.configure{shutdown_timeout = 0}");
475 } 511 }
476 512
477 // ----------------------------------------------------------------------------------------- 513 // ---------------------------------------------------------------------------------------------
478 514
479 SECTION("strip_functions = <C function>") 515 SECTION("shutdown_timeout = 1s")
480 { 516 {
481 L.requireFailure("require 'lanes'.configure{strip_functions = print}"); 517 L.requireSuccess("require 'lanes'.configure{shutdown_timeout = 1}");
482 } 518 }
483 519
484 // ----------------------------------------------------------------------------------------- 520 // ---------------------------------------------------------------------------------------------
485 521
486 SECTION("strip_functions = false") 522 SECTION("shutdown_timeout = 3600s")
487 { 523 {
488 L.requireSuccess("require 'lanes'.configure{strip_functions = false}"); 524 L.requireSuccess("require 'lanes'.configure{shutdown_timeout = 3600}");
489 } 525 }
490 526
491 // ----------------------------------------------------------------------------------------- 527 // ---------------------------------------------------------------------------------------------
492 528
493 SECTION("strip_functions = true") 529 SECTION("shutdown_timeout = <too long>")
494 { 530 {
495 L.requireSuccess("require 'lanes'.configure{strip_functions = true}"); 531 L.requireFailure("require 'lanes'.configure{shutdown_timeout = 3600.001}");
496 } 532 }
533}
534
535// #################################################################################################
536
537TEST_CASE("lanes.configure.strip_functions")
538{
539 LuaState L{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } };
540
541 // strip_functions should be a boolean
542
543 SECTION("strip_functions = <table>")
544 {
545 L.requireFailure("require 'lanes'.configure{strip_functions = {}}");
497 } 546 }
498 547
499 // --------------------------------------------------------------------------------------------- 548 // ---------------------------------------------------------------------------------------------
500 // track_lanes should be a boolean
501 549
502 SECTION("track_lanes") 550 SECTION("strip_functions = <string>")
503 { 551 {
504 SECTION("track_lanes = <table>") 552 L.requireFailure("require 'lanes'.configure{strip_functions = 'gluh'}");
505 { 553 }
506 L.requireFailure("require 'lanes'.configure{track_lanes = {}}");
507 }
508 554
509 // ----------------------------------------------------------------------------------------- 555 // ---------------------------------------------------------------------------------------------
510 556
511 SECTION("track_lanes = <string>") 557 SECTION("strip_functions = <number>")
512 { 558 {
513 L.requireFailure("require 'lanes'.configure{track_lanes = 'gluh'}"); 559 L.requireFailure("require 'lanes'.configure{strip_functions = 1}");
514 } 560 }
515 561
516 // ----------------------------------------------------------------------------------------- 562 // ---------------------------------------------------------------------------------------------
517 563
518 SECTION("track_lanes = <number>") 564 SECTION("strip_functions = <C function>")
519 { 565 {
520 L.requireFailure("require 'lanes'.configure{track_lanes = 1}"); 566 L.requireFailure("require 'lanes'.configure{strip_functions = print}");
521 } 567 }
522 568
523 // ----------------------------------------------------------------------------------------- 569 // ---------------------------------------------------------------------------------------------
524 570
525 SECTION("track_lanes = <C function>") 571 SECTION("strip_functions = false")
526 { 572 {
527 L.requireFailure("require 'lanes'.configure{track_lanes = print}"); 573 L.requireSuccess("require 'lanes'.configure{strip_functions = false}");
528 } 574 }
529 575
530 // ----------------------------------------------------------------------------------------- 576 // ---------------------------------------------------------------------------------------------
531 577
532 SECTION("track_lanes = false") 578 SECTION("strip_functions = true")
533 { 579 {
534 L.requireSuccess("require 'lanes'.configure{track_lanes = false}"); 580 L.requireSuccess("require 'lanes'.configure{strip_functions = true}");
535 } 581 }
582}
536 583
537 // ----------------------------------------------------------------------------------------- 584// #################################################################################################
538 585
539 SECTION("track_lanes = true") 586TEST_CASE("lanes.configure.track_lanes")
540 { 587{
541 L.requireSuccess("require 'lanes'.configure{track_lanes = true}"); 588 LuaState L{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } };
542 } 589
590 // track_lanes should be a boolean
591
592 SECTION("track_lanes = <table>")
593 {
594 L.requireFailure("require 'lanes'.configure{track_lanes = {}}");
543 } 595 }
544 596
545 // --------------------------------------------------------------------------------------------- 597 // ---------------------------------------------------------------------------------------------
546 // verbose_errors should be a boolean
547 598
548 SECTION("verbose_errors") 599 SECTION("track_lanes = <string>")
549 { 600 {
550 SECTION("verbose_errors = <table>") 601 L.requireFailure("require 'lanes'.configure{track_lanes = 'gluh'}");
551 { 602 }
552 L.requireFailure("require 'lanes'.configure{verbose_errors = {}}");
553 }
554 603
555 // ----------------------------------------------------------------------------------------- 604 // ---------------------------------------------------------------------------------------------
556 605
557 SECTION("verbose_errors = <string>") 606 SECTION("track_lanes = <number>")
558 { 607 {
559 L.requireFailure("require 'lanes'.configure{verbose_errors = 'gluh'}"); 608 L.requireFailure("require 'lanes'.configure{track_lanes = 1}");
560 } 609 }
561 610
562 // ----------------------------------------------------------------------------------------- 611 // ---------------------------------------------------------------------------------------------
563 612
564 SECTION("verbose_errors = <number>") 613 SECTION("track_lanes = <C function>")
565 { 614 {
566 L.requireFailure("require 'lanes'.configure{verbose_errors = 1}"); 615 L.requireFailure("require 'lanes'.configure{track_lanes = print}");
567 } 616 }
568 617
569 // ----------------------------------------------------------------------------------------- 618 // ---------------------------------------------------------------------------------------------
570 619
571 SECTION("verbose_errors = <C function>") 620 SECTION("track_lanes = false")
572 { 621 {
573 L.requireFailure("require 'lanes'.configure{verbose_errors = print}"); 622 L.requireSuccess("require 'lanes'.configure{track_lanes = false}");
574 } 623 }
575 624
576 // ----------------------------------------------------------------------------------------- 625 // ---------------------------------------------------------------------------------------------
577 626
578 SECTION("verbose_errors = false") 627 SECTION("track_lanes = true")
579 { 628 {
580 L.requireSuccess("require 'lanes'.configure{verbose_errors = false}"); 629 L.requireSuccess("require 'lanes'.configure{track_lanes = true}");
581 } 630 }
631}
582 632
583 // ----------------------------------------------------------------------------------------- 633// #################################################################################################
584 634
585 SECTION("verbose_errors = true") 635TEST_CASE("lanes.configure.verbose_errors")
586 { 636{
587 L.requireSuccess("require 'lanes'.configure{verbose_errors = true}"); 637 LuaState L{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } };
588 } 638
639 // verbose_errors should be a boolean
640
641 SECTION("verbose_errors = <table>")
642 {
643 L.requireFailure("require 'lanes'.configure{verbose_errors = {}}");
589 } 644 }
590 645
591 // --------------------------------------------------------------------------------------------- 646 // ---------------------------------------------------------------------------------------------
592 // with_timers should be a boolean
593 647
594 SECTION("with_timers") 648 SECTION("verbose_errors = <string>")
595 { 649 {
596 SECTION("with_timers = <table>") 650 L.requireFailure("require 'lanes'.configure{verbose_errors = 'gluh'}");
597 { 651 }
598 L.requireFailure("require 'lanes'.configure{with_timers = {}}");
599 }
600 652
601 // ----------------------------------------------------------------------------------------- 653 // ---------------------------------------------------------------------------------------------
602 654
603 SECTION("with_timers = <string>") 655 SECTION("verbose_errors = <number>")
604 { 656 {
605 L.requireFailure("require 'lanes'.configure{with_timers = 'gluh'}"); 657 L.requireFailure("require 'lanes'.configure{verbose_errors = 1}");
606 } 658 }
607 659
608 // ----------------------------------------------------------------------------------------- 660 // ---------------------------------------------------------------------------------------------
609 661
610 SECTION("with_timers = <number>") 662 SECTION("verbose_errors = <C function>")
611 { 663 {
612 L.requireFailure("require 'lanes'.configure{with_timers = 1}"); 664 L.requireFailure("require 'lanes'.configure{verbose_errors = print}");
613 } 665 }
614 666
615 // ----------------------------------------------------------------------------------------- 667 // ---------------------------------------------------------------------------------------------
616 668
617 SECTION("with_timers = <C function>") 669 SECTION("verbose_errors = false")
618 { 670 {
619 L.requireFailure("require 'lanes'.configure{with_timers = print}"); 671 L.requireSuccess("require 'lanes'.configure{verbose_errors = false}");
620 } 672 }
621 673
622 // ----------------------------------------------------------------------------------------- 674 // ---------------------------------------------------------------------------------------------
623 675
624 SECTION("with_timers = false") 676 SECTION("verbose_errors = true")
625 { 677 {
626 L.requireSuccess("require 'lanes'.configure{with_timers = false}"); 678 L.requireSuccess("require 'lanes'.configure{verbose_errors = true}");
627 } 679 }
680}
628 681
629 // ----------------------------------------------------------------------------------------- 682// #################################################################################################
630 683
631 SECTION("with_timers = true") 684TEST_CASE("lanes.configure.with_timers")
632 { 685{
633 L.requireSuccess("require 'lanes'.configure{with_timers = true}"); 686 LuaState L{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } };
634 } 687
688 // with_timers should be a boolean
689
690 SECTION("with_timers = <table>")
691 {
692 L.requireFailure("require 'lanes'.configure{with_timers = {}}");
693 }
694
695 // ---------------------------------------------------------------------------------------------
696
697 SECTION("with_timers = <string>")
698 {
699 L.requireFailure("require 'lanes'.configure{with_timers = 'gluh'}");
635 } 700 }
636 701
637 // --------------------------------------------------------------------------------------------- 702 // ---------------------------------------------------------------------------------------------
703
704 SECTION("with_timers = <number>")
705 {
706 L.requireFailure("require 'lanes'.configure{with_timers = 1}");
707 }
708
709 // ---------------------------------------------------------------------------------------------
710
711 SECTION("with_timers = <C function>")
712 {
713 L.requireFailure("require 'lanes'.configure{with_timers = print}");
714 }
715
716 // ---------------------------------------------------------------------------------------------
717
718 SECTION("with_timers = false")
719 {
720 L.requireSuccess("require 'lanes'.configure{with_timers = false}");
721 }
722
723 // ---------------------------------------------------------------------------------------------
724
725 SECTION("with_timers = true")
726 {
727 L.requireSuccess("require 'lanes'.configure{with_timers = true}");
728 }
729}
730
731// #################################################################################################
732
733TEST_CASE("lanes.configure.unknown_setting")
734{
735 LuaState L{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } };
736
638 // any unknown setting should be rejected 737 // any unknown setting should be rejected
639 738
640 SECTION("unknown_setting") 739 SECTION("table setting")
641 { 740 {
642 SECTION("table setting") 741 L.requireFailure("require 'lanes'.configure{[{}] = {}}");
643 { 742 }
644 L.requireFailure("require 'lanes'.configure{[{}] = {}}");
645 }
646 743
647 // ----------------------------------------------------------------------------------------- 744 // ---------------------------------------------------------------------------------------------
648 745
649 SECTION("boolean setting") 746 SECTION("boolean setting")
650 { 747 {
651 L.requireFailure("require 'lanes'.configure{[true] = 'gluh'}"); 748 L.requireFailure("require 'lanes'.configure{[true] = 'gluh'}");
652 } 749 }
653 750
654 // ----------------------------------------------------------------------------------------- 751 // ---------------------------------------------------------------------------------------------
655 752
656 SECTION("function setting") 753 SECTION("function setting")
657 { 754 {
658 L.requireFailure("require 'lanes'.configure{[function() end] = 1}"); 755 L.requireFailure("require 'lanes'.configure{[function() end] = 1}");
659 } 756 }
660 757
661 // ----------------------------------------------------------------------------------------- 758 // ---------------------------------------------------------------------------------------------
662 759
663 SECTION("number setting") 760 SECTION("number setting")
664 { 761 {
665 L.requireFailure("require 'lanes'.configure{[1] = function() end}"); 762 L.requireFailure("require 'lanes'.configure{[1] = function() end}");
666 } 763 }
667 764
668 // ----------------------------------------------------------------------------------------- 765 // ---------------------------------------------------------------------------------------------
669 766
670 SECTION("unknown string setting") 767 SECTION("unknown string setting")
671 { 768 {
672 L.requireFailure("require 'lanes'.configure{['gluh'] = false}"); 769 L.requireFailure("require 'lanes'.configure{['gluh'] = false}");
673 }
674 } 770 }
675} 771}
676 772
@@ -679,7 +775,7 @@ TEST_CASE("lanes.configure.the rest")
679 775
680#if LUAJIT_FLAVOR() == 0 776#if LUAJIT_FLAVOR() == 0
681// TODO: this test crashes inside S.close() against LuaJIT. to be investigated 777// TODO: this test crashes inside S.close() against LuaJIT. to be investigated
682TEST_CASE("lanes.finally.no fixture") 778TEST_CASE("lanes.finally.no_fixture")
683{ 779{
684 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } }; 780 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } };
685 // we need Lanes to be up. Since we run several 'scripts', we store it as a global 781 // we need Lanes to be up. Since we run several 'scripts', we store it as a global
@@ -700,7 +796,7 @@ TEST_CASE("lanes.finally.no fixture")
700 796
701// ################################################################################################# 797// #################################################################################################
702 798
703TEST_CASE("lanes.finally.with fixture") 799TEST_CASE("lanes.finally.with_fixture")
704{ 800{
705 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } }; 801 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } };
706 802
@@ -718,7 +814,7 @@ TEST_CASE("lanes.finally.with fixture")
718 814
719// ################################################################################################# 815// #################################################################################################
720 816
721TEST_CASE("lanes.finally.shutdown with an uncooperative lane") 817TEST_CASE("lanes.finally.shutdown_with_an_uncooperative_lane")
722{ 818{
723 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } }; 819 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } };
724 S.requireSuccess("lanes = require 'lanes'.configure()"); 820 S.requireSuccess("lanes = require 'lanes'.configure()");
@@ -767,7 +863,7 @@ namespace
767 863
768// ################################################################################################# 864// #################################################################################################
769 865
770TEST_CASE("lanes.on_state_create setting") 866TEST_CASE("lanes.configure.on_state_create/details")
771{ 867{
772 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } }; 868 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } };
773 869
diff --git a/unit_tests/lane_tests.cpp b/unit_tests/lane_tests.cpp
index d6ef2e0..b6fb188 100644
--- a/unit_tests/lane_tests.cpp
+++ b/unit_tests/lane_tests.cpp
@@ -1,5 +1,7 @@
1#include "_pch.hpp" 1#include "_pch.hpp"
2
2#include "shared.h" 3#include "shared.h"
4#include "lanes/src/threading.hpp"
3 5
4// ################################################################################################# 6// #################################################################################################
5// ################################################################################################# 7// #################################################################################################
@@ -33,7 +35,77 @@ TEST_CASE("lanes.nameof")
33// ################################################################################################# 35// #################################################################################################
34// ################################################################################################# 36// #################################################################################################
35 37
36TEST_CASE("lanes.sleep.argument validation") 38TEST_CASE("lanes.thread_priority_range")
39{
40 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } };
41 S.requireSuccess("lanes = require 'lanes'.configure()");
42
43 S.requireSuccess("a, b = lanes.thread_priority_range(); print(a, b)");
44 S.requireSuccess("assert(type(a) == 'number' and type(b) == 'number' and b > a)");
45 S.requireSuccess("c, d = lanes.thread_priority_range('native'); print(c, d)");
46 S.requireSuccess("assert(type(c) == 'number' and type(d) == 'number' and d > c)");
47
48 // can't really test the range of values from pthread as they are platform-dependent
49 if constexpr (THREADAPI == THREADAPI_WINDOWS) {
50 // windows constants THREAD_PRIORITY_IDLE and THREAD_PRIORITY_TIME_CRITICAL
51 S.requireSuccess("assert(c == -15 and d == 15)");
52 }
53}
54
55// #################################################################################################
56// #################################################################################################
57
58TEST_CASE("lanes.set_thread_priority")
59{
60 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } };
61 S.requireSuccess("lanes = require 'lanes'.configure()");
62
63 SECTION("mapped priorities")
64 {
65 std::string_view const _script{
66 " min_prio, max_prio = lanes.thread_priority_range()"
67 " for prio = min_prio, max_prio do"
68 " lanes.set_thread_priority(prio)"
69 " end"
70 };
71 S.requireSuccess(_script);
72
73 S.requireFailure("lanes.set_thread_priority(min_prio - 1)");
74 S.requireFailure("lanes.set_thread_priority(max_prio + 1)");
75 }
76
77 SECTION("native priorities")
78 {
79 S.requireSuccess("min_prio, max_prio = lanes.thread_priority_range('native')");
80 if constexpr (THREADAPI == THREADAPI_WINDOWS) {
81 // Win32 range is -15 to 15, but only some values are accepted
82 S.requireSuccess("lanes.set_thread_priority(-15, 'native')"); // THREAD_PRIORITY_IDLE
83 S.requireFailure("lanes.set_thread_priority(-3, 'native')");
84 S.requireSuccess("lanes.set_thread_priority(-2, 'native')"); // THREAD_PRIORITY_LOWEST
85 S.requireSuccess("lanes.set_thread_priority(-1, 'native')"); // THREAD_PRIORITY_BELOW_NORMAL
86 S.requireSuccess("lanes.set_thread_priority(0, 'native')"); // THREAD_PRIORITY_NORMAL
87 S.requireSuccess("lanes.set_thread_priority(1, 'native')"); // THREAD_PRIORITY_ABOVE_NORMAL
88 S.requireSuccess("lanes.set_thread_priority(2, 'native')"); // THREAD_PRIORITY_HIGHEST
89 S.requireFailure("lanes.set_thread_priority(3, 'native')");
90 S.requireSuccess("lanes.set_thread_priority(-15, 'native')"); // THREAD_PRIORITY_TIME_CRITICAL
91 } else {
92 // until proven otherwise, the full set of values is supported by pthread
93 std::string_view const _script{
94 " for prio = min_prio, max_prio do"
95 " lanes.set_thread_priority(prio, 'native')"
96 " end"
97 };
98 S.requireSuccess(_script);
99 }
100 S.requireFailure("lanes.set_thread_priority(min_prio - 1)");
101 S.requireFailure("lanes.set_thread_priority(max_prio + 1)");
102 }
103}
104
105// #################################################################################################
106// #################################################################################################
107
108TEST_CASE("lanes.sleep.argument_validation/not_numbers")
37{ 109{
38 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } }; 110 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } };
39 S.requireSuccess("lanes = require 'lanes'.configure()"); 111 S.requireSuccess("lanes = require 'lanes'.configure()");
@@ -44,6 +116,14 @@ TEST_CASE("lanes.sleep.argument validation")
44 S.requireFailure("lanes.sleep('a string')"); 116 S.requireFailure("lanes.sleep('a string')");
45 S.requireFailure("lanes.sleep(lanes.null)"); 117 S.requireFailure("lanes.sleep(lanes.null)");
46 S.requireFailure("lanes.sleep(print)"); 118 S.requireFailure("lanes.sleep(print)");
119}
120
121// #################################################################################################
122
123TEST_CASE("lanes.sleep.argument_validation/numbers")
124{
125 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } };
126 S.requireSuccess("lanes = require 'lanes'.configure()");
47 127
48 // negative durations are not supported 128 // negative durations are not supported
49 S.requireFailure("lanes.sleep(-1)"); 129 S.requireFailure("lanes.sleep(-1)");
@@ -97,88 +177,109 @@ TEST_CASE("lanes.sleep.interactions with timers")
97// ################################################################################################# 177// #################################################################################################
98// ################################################################################################# 178// #################################################################################################
99 179
100TEST_CASE("lanes.gen") 180TEST_CASE("lanes.gen.argument_checks")
101{ 181{
102 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } }; 182 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } };
103 S.requireSuccess("lanes = require 'lanes'.configure()"); 183 S.requireSuccess("lanes = require 'lanes'.configure()");
104 184
105 // --------------------------------------------------------------------------------------------- 185 // ---------------------------------------------------------------------------------------------
106 186
107 SECTION("argument checks") 187 // no argument is bad
108 { 188 S.requireFailure("lanes.gen()");
109 // no parameter is bad 189
110 S.requireFailure("lanes.gen()"); 190 // minimal generator needs a function
111 191 S.requireSuccess("lanes.gen(function() end)");
112 // minimal generator needs a function 192
113 S.requireSuccess("lanes.gen(function() end)"); 193 // acceptable arguments for the generator are strings, tables, nil, followed by the function body
114 194 S.requireSuccess("lanes.gen(nil, function() end)");
115 // acceptable parameters for the generator are strings, tables, nil, followed by the function body 195 S.requireSuccess("lanes.gen('', function() end)");
116 S.requireSuccess("lanes.gen(nil, function() end)"); 196 S.requireSuccess("lanes.gen({}, function() end)");
117 S.requireSuccess("lanes.gen('', function() end)"); 197 S.requireSuccess("lanes.gen('', {}, function() end)");
118 S.requireSuccess("lanes.gen({}, function() end)"); 198 S.requireSuccess("lanes.gen({}, '', function() end)");
119 S.requireSuccess("lanes.gen('', {}, function() end)"); 199 S.requireSuccess("lanes.gen('', '', function() end)");
120 S.requireSuccess("lanes.gen({}, '', function() end)"); 200 S.requireSuccess("lanes.gen({}, {}, function() end)");
121 S.requireSuccess("lanes.gen('', '', function() end)"); 201
122 S.requireSuccess("lanes.gen({}, {}, function() end)"); 202 // anything different should fail: booleans, numbers, any userdata
123 203 S.requireFailure("lanes.gen(false, function() end)");
124 // anything different should fail: booleans, numbers, any userdata 204 S.requireFailure("lanes.gen(true, function() end)");
125 S.requireFailure("lanes.gen(false, function() end)"); 205 S.requireFailure("lanes.gen(42, function() end)");
126 S.requireFailure("lanes.gen(true, function() end)"); 206 S.requireFailure("lanes.gen(io.stdin, function() end)");
127 S.requireFailure("lanes.gen(42, function() end)"); 207 S.requireFailure("lanes.gen(lanes.linda(), function() end)");
128 S.requireFailure("lanes.gen(io.stdin, function() end)"); 208 S.requireFailure("lanes.gen(lanes.linda():deep(), function() end)");
129 S.requireFailure("lanes.gen(lanes.linda(), function() end)"); 209
130 S.requireFailure("lanes.gen(lanes.linda():deep(), function() end)"); 210 // even if argument types are correct, the function must come last
131 211 S.requireFailure("lanes.gen(function() end, '')");
132 // even if parameter types are correct, the function must come last 212
133 S.requireFailure("lanes.gen(function() end, '')"); 213 // the strings should only list "known base libraries", in any order, or "*"
134 214 // if the particular Lua flavor we build for doesn't support them, they raise an error unless postfixed by '?'
135 // the strings should only list "known base libraries", in any order, or "*" 215 S.requireSuccess("lanes.gen('base', function() end)");
136 // if the particular Lua flavor we build for doesn't support them, they raise an error unless postfixed by '?' 216
137 S.requireSuccess("lanes.gen('base', function() end)"); 217 // bit, ffi, jit are LuaJIT-specific
138
139 // bit, ffi, jit are LuaJIT-specific
140#if LUAJIT_FLAVOR() == 0 218#if LUAJIT_FLAVOR() == 0
141 S.requireFailure("lanes.gen('bit,ffi,jit', function() end)"); 219 S.requireFailure("lanes.gen('bit,ffi,jit', function() end)");
142 S.requireSuccess("lanes.gen('bit?,ffi?,jit?', function() end)"); 220 S.requireSuccess("lanes.gen('bit?,ffi?,jit?', function() end)");
143#endif // LUAJIT_FLAVOR() 221#endif // LUAJIT_FLAVOR()
144 222
145 // bit32 library existed only in Lua 5.2, there is still a loader that will raise an error in Lua 5.3 223 // bit32 library existed only in Lua 5.2, there is still a loader that will raise an error in Lua 5.3
146#if LUA_VERSION_NUM == 502 || LUA_VERSION_NUM == 503 224#if LUA_VERSION_NUM == 502 || LUA_VERSION_NUM == 503
147 S.requireSuccess("lanes.gen('bit32', function() end)"); 225 S.requireSuccess("lanes.gen('bit32', function() end)");
148#else // LUA_VERSION_NUM == 502 || LUA_VERSION_NUM == 503 226#else // LUA_VERSION_NUM == 502 || LUA_VERSION_NUM == 503
149 S.requireFailure("lanes.gen('bit32', function() end)"); 227 S.requireFailure("lanes.gen('bit32', function() end)");
150 S.requireSuccess("lanes.gen('bit32?', function() end)"); 228 S.requireSuccess("lanes.gen('bit32?', function() end)");
151#endif // LUA_VERSION_NUM == 502 || LUA_VERSION_NUM == 503 229#endif // LUA_VERSION_NUM == 502 || LUA_VERSION_NUM == 503
152 230
153 // coroutine library appeared with Lua 5.2 231 // coroutine library appeared with Lua 5.2
154#if LUA_VERSION_NUM == 501 232#if LUA_VERSION_NUM == 501
155 S.requireFailure("lanes.gen('coroutine', function() end)"); 233 S.requireFailure("lanes.gen('coroutine', function() end)");
156 S.requireSuccess("lanes.gen('coroutine?', function() end)"); 234 S.requireSuccess("lanes.gen('coroutine?', function() end)");
157#endif // LUA_VERSION_NUM == 501 235#endif // LUA_VERSION_NUM == 501
158 236
159 S.requireSuccess("lanes.gen('debug', function() end)"); 237 S.requireSuccess("lanes.gen('debug', function() end)");
160 S.requireSuccess("lanes.gen('io', function() end)"); 238 S.requireSuccess("lanes.gen('io', function() end)");
161 S.requireSuccess("lanes.gen('math', function() end)"); 239 S.requireSuccess("lanes.gen('math', function() end)");
162 S.requireSuccess("lanes.gen('os', function() end)"); 240 S.requireSuccess("lanes.gen('os', function() end)");
163 S.requireSuccess("lanes.gen('package', function() end)"); 241 S.requireSuccess("lanes.gen('package', function() end)");
164 S.requireSuccess("lanes.gen('string', function() end)"); 242 S.requireSuccess("lanes.gen('string', function() end)");
165 S.requireSuccess("lanes.gen('table', function() end)"); 243 S.requireSuccess("lanes.gen('table', function() end)");
166 244
167 // utf8 library appeared with Lua 5.3 245 // utf8 library appeared with Lua 5.3
168#if LUA_VERSION_NUM < 503 246#if LUA_VERSION_NUM < 503
169 S.requireFailure("lanes.gen('utf8', function() end)"); 247 S.requireFailure("lanes.gen('utf8', function() end)");
170 S.requireSuccess("lanes.gen('utf8?', function() end)"); 248 S.requireSuccess("lanes.gen('utf8?', function() end)");
171#endif // LUA_VERSION_NUM < 503 249#endif // LUA_VERSION_NUM < 503
172 250
173 S.requireSuccess("lanes.gen('lanes_core', function() end)"); 251 S.requireSuccess("lanes.gen('lanes_core', function() end)");
174 // "*" repeated or combined with anything else is forbidden 252 // "*" repeated or combined with anything else is forbidden
175 S.requireFailure("lanes.gen('*', '*', function() end)"); 253 S.requireFailure("lanes.gen('*', '*', function() end)");
176 S.requireFailure("lanes.gen('base', '*', function() end)"); 254 S.requireFailure("lanes.gen('base', '*', function() end)");
177 // unknown names are forbidden 255 // unknown names are forbidden
178 S.requireFailure("lanes.gen('Base', function() end)"); 256 S.requireFailure("lanes.gen('Base', function() end)");
179 // repeating the same library more than once is forbidden 257 // repeating the same library more than once is forbidden
180 S.requireFailure("lanes.gen('base,base', function() end)"); 258 S.requireFailure("lanes.gen('base,base', function() end)");
181 } 259}
260
261// #################################################################################################
262// #################################################################################################
263
264TEST_CASE("lanes.gen.priority")
265{
266 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } };
267 S.requireSuccess("lanes = require 'lanes'.configure()");
268
269 S.requireSuccess("lanes.gen({priority=1}, function() end)");
270 // AFAICT, 1 is accepted by all pthread flavors and win32 API
271 S.requireSuccess("lanes.gen({native_priority=1}, function() end)");
272 // shouldn't be able to provide 2 priority settings
273 S.requireFailure("lanes.gen({priority=1, native_priority=1}, function() end)");
274}
275
276// #################################################################################################
277// #################################################################################################
278
279TEST_CASE("lanes.gen.thread_naming")
280{
281 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } };
282 S.requireSuccess("lanes = require 'lanes'.configure()");
182 283
183 // --------------------------------------------------------------------------------------------- 284 // ---------------------------------------------------------------------------------------------
184 285
@@ -319,19 +420,24 @@ TEST_CASE("lane.cancel")
319// unfortunately, VS Test adapter does not list individual sections, 420// unfortunately, VS Test adapter does not list individual sections,
320// so let's create a separate test case for each file with an ugly macro... 421// so let's create a separate test case for each file with an ugly macro...
321 422
322#define MAKE_TEST_CASE(DIR, FILE, CONDITION)\ 423#define MAKE_TEST_CASE(DIR, FILE, CONDITION) \
323TEST_CASE("scripted tests." #DIR "." #FILE) \ 424TEST_CASE("scripted_tests." #DIR "." #FILE) \
324{ \ 425{ \
325 FileRunner _runner(R"(.\unit_tests\scripts)"); \ 426 FileRunner _runner(R"(.\unit_tests\scripts)"); \
326 _runner.performTest(FileRunnerParam{ #DIR "/" #FILE, TestType::CONDITION }); \ 427 _runner.performTest(FileRunnerParam{ #DIR "/" #FILE, TestType::CONDITION }); \
327} 428}
328 429
329MAKE_TEST_CASE(lane, cooperative_shutdown, AssertNoLuaError) 430#if LUA_VERSION_NUM >= 504 // this makes use of to-be-closed variables, a Lua 5.4 feature
330#if LUA_VERSION_NUM >= 504 // // warnings are a Lua 5.4 feature 431#define MAKE_TEST_CASE_54(DIR, FILE, CONDITION) MAKE_TEST_CASE(DIR, FILE, CONDITION)
331// NOTE: when this test ends, there are resource leaks and a dangling thread 432#else // LUA_VERSION_NUM
332MAKE_TEST_CASE(lane, uncooperative_shutdown, AssertWarns) 433#define MAKE_TEST_CASE_54(DIR, FILE, CONDITION)
333#endif // LUA_VERSION_NUM 434#endif // LUA_VERSION_NUM
435
436MAKE_TEST_CASE(lane, body_is_a_c_function, AssertNoLuaError)
437MAKE_TEST_CASE(lane, cooperative_shutdown, AssertNoLuaError)
438MAKE_TEST_CASE_54(lane, uncooperative_shutdown, AssertWarns) // NOTE: when this test ends, there are resource leaks and a dangling thread
334MAKE_TEST_CASE(lane, tasking_basic, AssertNoLuaError) 439MAKE_TEST_CASE(lane, tasking_basic, AssertNoLuaError)
440MAKE_TEST_CASE(lane, tasking_cancelling_with_hook, AssertNoLuaError)
335MAKE_TEST_CASE(lane, tasking_cancelling, AssertNoLuaError) 441MAKE_TEST_CASE(lane, tasking_cancelling, AssertNoLuaError)
336MAKE_TEST_CASE(lane, tasking_comms_criss_cross, AssertNoLuaError) 442MAKE_TEST_CASE(lane, tasking_comms_criss_cross, AssertNoLuaError)
337MAKE_TEST_CASE(lane, tasking_communications, AssertNoLuaError) 443MAKE_TEST_CASE(lane, tasking_communications, AssertNoLuaError)
@@ -339,19 +445,27 @@ MAKE_TEST_CASE(lane, tasking_error, AssertNoLuaError)
339MAKE_TEST_CASE(lane, tasking_join_test, AssertNoLuaError) 445MAKE_TEST_CASE(lane, tasking_join_test, AssertNoLuaError)
340MAKE_TEST_CASE(lane, tasking_send_receive_code, AssertNoLuaError) 446MAKE_TEST_CASE(lane, tasking_send_receive_code, AssertNoLuaError)
341MAKE_TEST_CASE(lane, stdlib_naming, AssertNoLuaError) 447MAKE_TEST_CASE(lane, stdlib_naming, AssertNoLuaError)
342MAKE_TEST_CASE(coro, basics, AssertNoLuaError) 448MAKE_TEST_CASE(coro, cancelling_suspended, AssertNoLuaError)
449MAKE_TEST_CASE_54(coro, collect_yielded_lane, AssertNoLuaError)
343#if LUAJIT_FLAVOR() == 0 450#if LUAJIT_FLAVOR() == 0
344// TODO: for some reason, the test fails with LuaJIT. To be investigated 451// TODO: for some reason, the test fails with LuaJIT. To be investigated
345MAKE_TEST_CASE(coro, error_handling, AssertNoLuaError) 452MAKE_TEST_CASE(coro, error_handling, AssertNoLuaError)
346#endif // LUAJIT_FLAVOR() 453#endif // LUAJIT_FLAVOR()
454MAKE_TEST_CASE(coro, index_suspended, AssertNoLuaError)
455MAKE_TEST_CASE(coro, join_suspended, AssertNoLuaError)
456MAKE_TEST_CASE_54(coro, linda_in_close_handler, AssertNoLuaError)
457MAKE_TEST_CASE(coro, regular_function, AssertNoLuaError)
458MAKE_TEST_CASE(coro, resume_basics, AssertNoLuaError)
459MAKE_TEST_CASE(coro, yielding_in_non_coro_errors, AssertNoLuaError)
347 460
348/* 461/*
349TEST_CASE("lanes.scripted tests") 462TEST_CASE("lanes.scripted_tests")
350{ 463{
351 auto const& _testParam = GENERATE( 464 auto const& _testParam = GENERATE(
352 FileRunnerParam{ PUC_LUA_ONLY("lane/cooperative_shutdown"), TestType::AssertNoLuaError }, // 0 465 FileRunnerParam{ PUC_LUA_ONLY("lane/cooperative_shutdown"), TestType::AssertNoLuaError }, // 0
353 FileRunnerParam{ "lane/uncooperative_shutdown", TestType::AssertWarns }, 466 FileRunnerParam{ "lane/uncooperative_shutdown", TestType::AssertWarns },
354 FileRunnerParam{ "lane/tasking_basic", TestType::AssertNoLuaError }, // 2 467 FileRunnerParam{ "lane/tasking_basic", TestType::AssertNoLuaError }, // 2
468 FileRunnerParam{ "lane/tasking_cancelling_with_hook", TestType::AssertNoLuaError }, // 3
355 FileRunnerParam{ "lane/tasking_cancelling", TestType::AssertNoLuaError }, // 3 469 FileRunnerParam{ "lane/tasking_cancelling", TestType::AssertNoLuaError }, // 3
356 FileRunnerParam{ "lane/tasking_comms_criss_cross", TestType::AssertNoLuaError }, // 4 470 FileRunnerParam{ "lane/tasking_comms_criss_cross", TestType::AssertNoLuaError }, // 4
357 FileRunnerParam{ "lane/tasking_communications", TestType::AssertNoLuaError }, 471 FileRunnerParam{ "lane/tasking_communications", TestType::AssertNoLuaError },
diff --git a/unit_tests/legacy_tests.cpp b/unit_tests/legacy_tests.cpp
index 7f2f31d..84581d2 100644
--- a/unit_tests/legacy_tests.cpp
+++ b/unit_tests/legacy_tests.cpp
@@ -11,7 +11,7 @@
11// so let's create a separate test case for each file with an ugly macro... 11// so let's create a separate test case for each file with an ugly macro...
12 12
13#define MAKE_TEST_CASE(FILE) \ 13#define MAKE_TEST_CASE(FILE) \
14TEST_CASE("scripted tests.legacy." #FILE) \ 14TEST_CASE("scripted_tests.legacy." #FILE) \
15{ \ 15{ \
16 FileRunner _runner(R"(.\tests\)"); \ 16 FileRunner _runner(R"(.\tests\)"); \
17 _runner.performTest(FileRunnerParam{ #FILE, TestType::AssertNoLuaError }); \ 17 _runner.performTest(FileRunnerParam{ #FILE, TestType::AssertNoLuaError }); \
@@ -49,7 +49,7 @@ MAKE_TEST_CASE(tobeclosed)
49MAKE_TEST_CASE(track_lanes) 49MAKE_TEST_CASE(track_lanes)
50 50
51/* 51/*
52TEST_CASE("lanes.legacy scripted tests") 52TEST_CASE("lanes.legacy_scripted_tests")
53{ 53{
54 auto const& _testParam = GENERATE( 54 auto const& _testParam = GENERATE(
55 FileRunnerParam{ "appendud", TestType::AssertNoLuaError } // 0 55 FileRunnerParam{ "appendud", TestType::AssertNoLuaError } // 0
diff --git a/unit_tests/linda_tests.cpp b/unit_tests/linda_tests.cpp
index efdb8a5..90630a7 100644
--- a/unit_tests/linda_tests.cpp
+++ b/unit_tests/linda_tests.cpp
@@ -3,154 +3,216 @@
3 3
4// ################################################################################################# 4// #################################################################################################
5 5
6TEST_CASE("linda.single Keeper") 6TEST_CASE("linda.single_keeper.creation/no_argument")
7{ 7{
8 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } }; 8 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } };
9 S.requireSuccess("lanes = require 'lanes'"); 9 S.requireSuccess("lanes = require 'lanes'");
10 10
11 SECTION("Linda creation") 11 // no argument is ok
12 { 12 S.requireSuccess("lanes.linda()");
13 // no parameters is ok 13 S.requireNotReturnedString("return tostring(lanes.linda())", R"===(Linda: <not a string>)==="); // unspecified name should not result in <not a string>
14 S.requireSuccess("lanes.linda()"); 14}
15 S.requireNotReturnedString("return tostring(lanes.linda())", R"===(Linda: <not a string>)==="); // unspecified name should not result in <not a string>
16
17 // since we have only one keeper, only group 0 is authorized
18 S.requireFailure("lanes.linda(-1)");
19 S.requireSuccess("lanes.linda(0)");
20 S.requireFailure("lanes.linda(1)");
21
22 // any name is ok
23 S.requireSuccess("lanes.linda('')"); // an empty name results in a string conversion of the form "Linda: <some hex value>" that we can't test (but it works)
24 S.requireReturnedString("return tostring(lanes.linda('short name'))", R"===(Linda: short name)===");
25 S.requireReturnedString("return tostring(lanes.linda('very very very very very very long name'))", R"===(Linda: very very very very very very long name)===");
26 S.requireReturnedString("return tostring(lanes.linda('auto'))", R"===(Linda: [string "return tostring(lanes.linda('auto'))"]:1)===");
27
28 if constexpr (LUA_VERSION_NUM == 504) {
29 // a function is acceptable as a __close handler
30 S.requireSuccess("local l <close> = lanes.linda(function() end)");
31 // a callable table too (a callable full userdata as well, but I have none here)
32 S.requireSuccess("local l <close> = lanes.linda(setmetatable({}, {__call = function() end}))");
33 // if the function raises an error, we should get it
34 S.requireFailure("local l <close> = lanes.linda(function() error 'gluh' end)");
35 } else {
36 // no __close support before Lua 5.4
37 S.requireFailure("lanes.linda(function() end)");
38 S.requireFailure("lanes.linda(setmetatable({}, {__call = function() end}))");
39 }
40 15
41 // mixing parameters in any order is ok: 2 out of 3 16// #################################################################################################
42 S.requireSuccess("lanes.linda(0, 'name')");
43 S.requireSuccess("lanes.linda('name', 0)");
44 if constexpr (LUA_VERSION_NUM == 504) {
45 S.requireSuccess("lanes.linda(0, function() end)");
46 S.requireSuccess("lanes.linda(function() end, 0)");
47 S.requireSuccess("lanes.linda('name', function() end)");
48 S.requireSuccess("lanes.linda(function() end, 'name')");
49 }
50 17
51 // mixing parameters in any order is ok: 3 out of 3 18TEST_CASE("linda.single_keeper.creation/non_table_arguments")
52 if constexpr (LUA_VERSION_NUM == 504) { 19{
53 S.requireSuccess("lanes.linda(0, 'name', function() end)"); 20 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } };
54 S.requireSuccess("lanes.linda(0, function() end, 'name')"); 21 S.requireSuccess("lanes = require 'lanes'");
55 S.requireSuccess("lanes.linda('name', 0, function() end)"); 22
56 S.requireSuccess("lanes.linda('name', function() end, 0)"); 23 // any argument that is not a table is not ok
57 S.requireSuccess("lanes.linda(function() end, 0, 'name')"); 24 S.requireFailure("lanes.linda(0)");
58 S.requireSuccess("lanes.linda(function() end, 'name', 0)"); 25 S.requireFailure("lanes.linda('bob')");
59 } 26 S.requireFailure("lanes.linda(false)");
27 S.requireFailure("lanes.linda(function() end)");
28 S.requireFailure("lanes.linda(lanes.cancel_error)");
29}
30
31// #################################################################################################
60 32
61 // unsupported parameters should fail 33TEST_CASE("linda.single_keeper.creation/close_handler")
62 S.requireFailure("lanes.linda(true)"); 34{
63 S.requireFailure("lanes.linda(false)"); 35 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } };
64 // uncallable table or full userdata 36 S.requireSuccess("lanes = require 'lanes'");
65 S.requireFailure("lanes.linda({})"); 37
66 S.requireFailure("lanes.linda(lanes.linda())"); 38 if constexpr (LUA_VERSION_NUM >= 504) {
39 // a function is acceptable as a __close handler
40 S.requireSuccess("local l <close> = lanes.linda{close_handler = function() end}");
41 // a callable table too (a callable full userdata as well, but I have none here)
42 S.requireSuccess("local l <close> = lanes.linda{close_handler = setmetatable({}, {__call = function() end})}");
43 } else {
44 // no __close support before Lua 5.4, field is ignored (therefore invalid values are accepted too!)
45 S.requireSuccess("lanes.linda{close_handler = 'a string'}");
46 S.requireSuccess("lanes.linda{close_handler = function() end}");
47 S.requireSuccess("lanes.linda{close_handler = setmetatable({}, {__call = function() end})}");
67 } 48 }
49}
68 50
69 // --------------------------------------------------------------------------------------------- 51// #################################################################################################
52
53TEST_CASE("linda.single_keeper.creation/table_argument")
54{
55 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } };
56 S.requireSuccess("lanes = require 'lanes'");
57
58 // one table is fine
59 S.requireSuccess("lanes.linda{}");
60 // anything beyond that is not
61 S.requireFailure("lanes.linda({},{})");
62 S.requireFailure("lanes.linda({},'bob')");
63 S.requireFailure("lanes.linda({},42)");
64}
65
66// #################################################################################################
67
68TEST_CASE("linda.single_keeper.creation/group")
69{
70 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } };
71 S.requireSuccess("lanes = require 'lanes'");
72
73 // since we have only one keeper, only group 0 is authorized
74 S.requireFailure("lanes.linda{group = -1}");
75 S.requireSuccess("lanes.linda{group = 0}");
76 S.requireFailure("lanes.linda{group = 1}");
77}
78
79// #################################################################################################
80
81TEST_CASE("linda.single_keeper.creation/name")
82{
83 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } };
84 S.requireSuccess("lanes = require 'lanes'");
85
86 // any name is ok
87 S.requireSuccess("lanes.linda{name = ''}"); // an empty name results in a string conversion of the form "Linda: <some hex value>" that we can't test (but it works)
88 S.requireReturnedString("return tostring(lanes.linda{name = 'short name'})", R"===(Linda: short name)===");
89 S.requireReturnedString("return tostring(lanes.linda{name = 'very very very very very very long name'})", R"===(Linda: very very very very very very long name)===");
90 S.requireReturnedString("return tostring(lanes.linda{name = 'auto'})", R"===(Linda: [string "return tostring(lanes.linda{name = 'auto'})"]:1)===");
91}
92
93// #################################################################################################
94
95TEST_CASE("linda.single_keeper.creation/wake_period")
96{
97 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } };
98 S.requireSuccess("lanes = require 'lanes'");
99
100 // wake_period should be a number > 0
101 S.requireFailure("lanes.linda{wake_period = false}");
102 S.requireFailure("lanes.linda{wake_period = 'bob'}");
103 S.requireFailure("lanes.linda{wake_period = {}}");
104 S.requireFailure("lanes.linda{wake_period = -1}");
105 S.requireFailure("lanes.linda{wake_period = 0}");
106 S.requireSuccess("lanes.linda{wake_period = 0.0001}");
107 S.requireSuccess("lanes.linda{wake_period = 'never'}");
108}
109
110// #################################################################################################
70 111
71 SECTION("Linda indexing") 112TEST_CASE("linda.single_keeper.indexing")
113{
114 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } };
115 S.requireSuccess("lanes = require 'lanes'.configure()");
116
117 // indexing the linda with an unknown string key should fail
118 S.requireFailure("return lanes.linda().gouikra");
119 // indexing the linda with an unsupported key type should fail
120 S.requireFailure("return lanes.linda()[5]");
121 S.requireFailure("return lanes.linda()[false]");
122 S.requireFailure("return lanes.linda()[{}]");
123 S.requireFailure("return lanes.linda()[function() end]");
124}
125
126// #################################################################################################
127
128TEST_CASE("linda.single_keeper.send()")
129{
130 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } };
131 S.requireSuccess("lanes = require 'lanes'.configure()");
132
133 SECTION("timeout")
72 { 134 {
73 // indexing the linda with an unknown string key should fail 135 // timeout checks
74 S.requireFailure("return lanes.linda().gouikra"); 136 // linda:send() should fail if the timeout is bad
75 // indexing the linda with an unsupported key type should fail 137 S.requireFailure("lanes.linda():send(-1, 'k', 'v')");
76 S.requireFailure("return lanes.linda()[5]"); 138 // any positive value is ok
77 S.requireFailure("return lanes.linda()[false]"); 139 S.requireSuccess("lanes.linda():send(0, 'k', 'v')");
78 S.requireFailure("return lanes.linda()[{}]"); 140 S.requireSuccess("lanes.linda():send(1e20, 'k', 'v')");
79 S.requireFailure("return lanes.linda()[function() end]"); 141 // nil too (same as 'forever')
142 S.requireSuccess("lanes.linda():send(nil, 'k', 'v')");
80 } 143 }
81 144
82 // --------------------------------------------------------------------------------------------- 145 // -----------------------------------------------------------------------------------------
83 SECTION("linda:send()") 146
147 SECTION("fails on bad keys")
84 { 148 {
85 SECTION("timeout") 149 // key checks
86 { 150 // linda:send() should fail if the key is unsupported (nil, table, function, full userdata, reserved light userdata)
87 // timeout checks 151 S.requireFailure("lanes.linda():send(0, nil, 'v')");
88 // linda:send() should fail if the timeout is bad 152 S.requireFailure("lanes.linda():send(0, {}, 'v')");
89 S.requireFailure("lanes.linda():send(-1, 'k', 'v')"); 153 S.requireFailure("lanes.linda():send(0, function() end, 'v')");
90 // any positive value is ok 154 S.requireFailure("lanes.linda():send(0, io.stdin, 'v')");
91 S.requireSuccess("lanes.linda():send(0, 'k', 'v')"); 155 S.requireFailure("lanes.linda():send(0, lanes.null, 'v')");
92 S.requireSuccess("lanes.linda():send(1e20, 'k', 'v')"); 156 S.requireFailure("lanes.linda():send(0, lanes.cancel_error, 'v')");
93 // nil too (same as 'forever') 157 }
94 S.requireSuccess("lanes.linda():send(nil, 'k', 'v')");
95 }
96 158
97 // ----------------------------------------------------------------------------------------- 159 // -----------------------------------------------------------------------------------------
98 160
99 SECTION("fails on bad keys") 161 SECTION("succeeds on supported keys")
100 { 162 {
101 // key checks 163 // supported keys are ok: boolean, number, string, light userdata, deep userdata
102 // linda:send() should fail if the key is unsupported (nil, table, function, full userdata, reserved light userdata) 164 S.requireSuccess("lanes.linda():send(0, true, 'v')");
103 S.requireFailure("lanes.linda():send(0, nil, 'v')"); 165 S.requireSuccess("lanes.linda():send(0, false, 'v')");
104 S.requireFailure("lanes.linda():send(0, {}, 'v')"); 166 S.requireSuccess("lanes.linda():send(0, 99, 'v')");
105 S.requireFailure("lanes.linda():send(0, function() end, 'v')"); 167 S.requireSuccess("local l = lanes.linda(); l:send(0, l:deep(), 'v')");
106 S.requireFailure("lanes.linda():send(0, io.stdin, 'v')"); 168 }
107 S.requireFailure("lanes.linda():send(0, lanes.null, 'v')");
108 S.requireFailure("lanes.linda():send(0, lanes.cancel_error, 'v')");
109 S.requireFailure("local l = lanes.linda(); l:send(0, l.batched, 'v')");
110 }
111 169
112 // ----------------------------------------------------------------------------------------- 170 // -----------------------------------------------------------------------------------------
113 171
114 SECTION("succeeds on supported keys") 172 SECTION("succeeds on deep userdata key")
115 { 173 {
116 // supported keys are ok: boolean, number, string, light userdata, deep userdata 174 S.requireSuccess("local l = lanes.linda(); l:send(0, l, 'v')");
117 S.requireSuccess("lanes.linda():send(0, true, 'v')"); 175 }
118 S.requireSuccess("lanes.linda():send(0, false, 'v')");
119 S.requireSuccess("lanes.linda():send(0, 99, 'v')");
120 S.requireSuccess("local l = lanes.linda(); l:send(0, l:deep(), 'v')");
121 }
122 176
123 // ----------------------------------------------------------------------------------------- 177 // -----------------------------------------------------------------------------------------
124 178
125 SECTION("succeeds on deep userdata key") 179 SECTION(". fails")
126 { 180 {
127 S.requireSuccess("local l = lanes.linda(); l:send(0, l, 'v')"); 181 // misuse checks, . instead of :
128 } 182 S.requireFailure("lanes.linda().send(nil, 'k', 'v')");
183 }
129 184
130 // ----------------------------------------------------------------------------------------- 185 // -----------------------------------------------------------------------------------------
131 186
132 SECTION(". fails") 187 SECTION("unsupported values fail")
133 { 188 {
134 // misuse checks, . instead of : 189 // value checks
135 S.requireFailure("lanes.linda().send(nil, 'k', 'v')"); 190 // linda:send() should fail if we don't send anything
136 } 191 S.requireFailure("lanes.linda():send()");
192 S.requireFailure("lanes.linda():send(0)");
193 S.requireFailure("lanes.linda():send(0, 'k')");
194 // or non-deep userdata
195 S.requireFailure("lanes.linda():send(0, 'k', fixture.newuserdata())");
196 // or something with a converter that raises an error (maybe that should go to a dedicated __lanesconvert test!)
197 S.requireFailure("lanes.linda():send(0, 'k', setmetatable({}, {__lanesconvert = function(where_) error (where_ .. ': should not send me' end}))");
198 // but a registered non-deep userdata should work
199 S.requireSuccess("lanes.linda():send(0, 'k', io.stdin)");
200 }
201}
137 202
138 // ----------------------------------------------------------------------------------------- 203// #################################################################################################
139 204
140 SECTION("unsupported values fail") 205TEST_CASE("linda.single_keeper.the_rest")
141 { 206{
142 // value checks 207 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } };
143 // linda:send() should fail if we don't send anything 208 S.requireSuccess("lanes = require 'lanes'");
144 S.requireFailure("lanes.linda():send()"); 209
145 S.requireFailure("lanes.linda():send(0)"); 210 // ---------------------------------------------------------------------------------------------
146 S.requireFailure("lanes.linda():send(0, 'k')"); 211
147 // or non-deep userdata 212 SECTION("error in close handler is propagated")
148 S.requireFailure("lanes.linda():send(0, 'k', fixture.newuserdata())"); 213 {
149 // or something with a converter that raises an error (maybe that should go to a dedicated __lanesconvert test!) 214 // if the function raises an error, we should get it
150 S.requireFailure("lanes.linda():send(0, 'k', setmetatable({}, {__lanesconvert = function(where_) error (where_ .. ': should not send me' end}))"); 215 S.requireFailure("local l <close> = lanes.linda{close_handler = function() error 'gluh' end}");
151 // but a registered non-deep userdata should work
152 S.requireSuccess("lanes.linda():send(0, 'k', io.stdin)");
153 }
154 } 216 }
155 217
156 // --------------------------------------------------------------------------------------------- 218 // ---------------------------------------------------------------------------------------------
@@ -312,12 +374,12 @@ TEST_CASE("linda.multi Keeper")
312 374
313 S.requireSuccess("lanes = require 'lanes'.configure{nb_user_keepers = 3}"); 375 S.requireSuccess("lanes = require 'lanes'.configure{nb_user_keepers = 3}");
314 376
315 S.requireFailure("lanes.linda(-1)"); 377 S.requireFailure("lanes.linda{group = -1}");
316 S.requireSuccess("lanes.linda(0)"); 378 S.requireSuccess("lanes.linda{group = 0}");
317 S.requireSuccess("lanes.linda(1)"); 379 S.requireSuccess("lanes.linda{group = 1}");
318 S.requireSuccess("lanes.linda(2)"); 380 S.requireSuccess("lanes.linda{group = 2}");
319 S.requireSuccess("lanes.linda(3)"); 381 S.requireSuccess("lanes.linda{group = 3}");
320 S.requireFailure("lanes.linda(4)"); 382 S.requireFailure("lanes.linda{group = 4}");
321} 383}
322 384
323// ################################################################################################# 385// #################################################################################################
@@ -327,23 +389,26 @@ TEST_CASE("linda.multi Keeper")
327// so let's create a separate test case for each file with an ugly macro... 389// so let's create a separate test case for each file with an ugly macro...
328 390
329#define MAKE_TEST_CASE(DIR, FILE) \ 391#define MAKE_TEST_CASE(DIR, FILE) \
330TEST_CASE("scripted tests." #DIR "." #FILE) \ 392TEST_CASE("scripted_tests." #DIR "." #FILE) \
331{ \ 393{ \
332 FileRunner _runner(R"(.\unit_tests\scripts)"); \ 394 FileRunner _runner(R"(.\unit_tests\scripts)"); \
333 _runner.performTest(FileRunnerParam{ #DIR "/" #FILE, TestType::AssertNoLuaError }); \ 395 _runner.performTest(FileRunnerParam{ #DIR "/" #FILE, TestType::AssertNoLuaError }); \
334} 396}
335 397
398MAKE_TEST_CASE(linda, multiple_keepers)
336MAKE_TEST_CASE(linda, send_receive) 399MAKE_TEST_CASE(linda, send_receive)
400MAKE_TEST_CASE(linda, send_receive_func_and_string)
337MAKE_TEST_CASE(linda, send_registered_userdata) 401MAKE_TEST_CASE(linda, send_registered_userdata)
338MAKE_TEST_CASE(linda, multiple_keepers) 402MAKE_TEST_CASE(linda, wake_period)
339 403
340/* 404/*
341TEST_CASE("linda.scripted tests") 405TEST_CASE("linda.scripted_tests")
342{ 406{
343 auto const& _testParam = GENERATE( 407 auto const& _testParam = GENERATE(
408 FileRunnerParam{ "linda/multiple_keepers", TestType::AssertNoLuaError },
344 FileRunnerParam{ "linda/send_receive", TestType::AssertNoLuaError }, 409 FileRunnerParam{ "linda/send_receive", TestType::AssertNoLuaError },
345 FileRunnerParam{ "linda/send_registered_userdata", TestType::AssertNoLuaError }, 410 FileRunnerParam{ "linda/send_registered_userdata", TestType::AssertNoLuaError },
346 FileRunnerParam{ "linda/multiple_keepers", TestType::AssertNoLuaError } 411 FileRunnerParam{ "linda/wake_period", TestType::AssertNoLuaError }
347 ); 412 );
348 413
349 FileRunner _runner(R"(.\unit_tests\scripts)"); 414 FileRunner _runner(R"(.\unit_tests\scripts)");
diff --git a/unit_tests/scripts/_utils.lua b/unit_tests/scripts/_utils.lua
index d710702..9f46237 100644
--- a/unit_tests/scripts/_utils.lua
+++ b/unit_tests/scripts/_utils.lua
@@ -68,8 +68,26 @@ local function dump_error_stack(error_reporting_mode_, stack)
68 end 68 end
69end 69end
70 70
71-- a function that yields back what got in, one element at a time
72local yield_one_by_one = function(...)
73 local PRINT = MAKE_PRINT()
74 PRINT "In lane"
75 for _i = 1, select('#', ...) do
76 local _val = select(_i, ...)
77 PRINT("yielding #", _i, _val)
78 local _ack = coroutine.yield(_val)
79 if cancel_test and cancel_test() then -- cancel_test does not exist when run immediately (not in a Lane)
80 return "cancelled!"
81 end
82 -- of course, if we are cancelled, we were not resumed, and yield() didn't return what we expect
83 assert(_ack == _i)
84 end
85 return "bye!"
86end
87
71return { 88return {
72 MAKE_PRINT = MAKE_PRINT, 89 MAKE_PRINT = MAKE_PRINT,
73 tables_match = tables_match, 90 tables_match = tables_match,
74 dump_error_stack = dump_error_stack 91 dump_error_stack = dump_error_stack,
92 yield_one_by_one = yield_one_by_one
75} 93}
diff --git a/unit_tests/scripts/_utils54.lua b/unit_tests/scripts/_utils54.lua
new file mode 100644
index 0000000..a511563
--- /dev/null
+++ b/unit_tests/scripts/_utils54.lua
@@ -0,0 +1,30 @@
1local utils = require "_utils"
2
3-- expand _utils module with Lua5.4 specific stuff
4
5-- a lane body that yields stuff
6utils.yielder_with_to_be_closed = function(out_linda_, wait_)
7 local fixture = assert(require "fixture")
8 -- here is a to-be-closed variable that, when closed, sends "Closed!" in the "out" slot of the provided linda
9 local t <close> = setmetatable(
10 { text = "Closed!" }, {
11 __close = function(self, err)
12 if wait_ then
13 fixture.block_for(wait_)
14 end
15 out_linda_:send("out", self.text)
16 end
17 }
18 )
19 -- yield forever, but be cancel-friendly
20 local n = 1
21 while true do
22 coroutine.yield("I yield!", n)
23 if cancel_test and cancel_test() then -- cancel_test does not exist when run immediately (not in a Lane)
24 return "I am cancelled"
25 end
26 n = n + 1
27 end
28end
29
30return utils
diff --git a/unit_tests/scripts/coro/basics.lua b/unit_tests/scripts/coro/basics.lua
deleted file mode 100644
index cd2f410..0000000
--- a/unit_tests/scripts/coro/basics.lua
+++ /dev/null
@@ -1,97 +0,0 @@
1local lanes = require "lanes"
2
3local fixture = require "fixture"
4lanes.finally(fixture.throwing_finalizer)
5
6local utils = lanes.require "_utils"
7local PRINT = utils.MAKE_PRINT()
8
9if true then
10 -- a lane body that just returns some value
11 local lane = function(msg_)
12 local utils = lanes.require "_utils"
13 local PRINT = utils.MAKE_PRINT()
14 PRINT "In lane"
15 assert(msg_ == "hi")
16 return "bye"
17 end
18
19 -- the generator
20 local g1 = lanes.coro("*", {name = "auto"}, lane)
21
22 -- launch lane
23 local h1 = g1("hi")
24
25 local r = h1[1]
26 assert(r == "bye")
27end
28
29-- a lane coroutine that yields back what got in, one element at a time
30local yielder = function(...)
31 local utils = lanes.require "_utils"
32 local PRINT = utils.MAKE_PRINT()
33 PRINT "In lane"
34 for _i = 1, select('#', ...) do
35 local _val = select(_i, ...)
36 PRINT("yielding #", _i, _val)
37 local _ack = coroutine.yield(_val)
38 assert(_ack == _i)
39 end
40 return "done!"
41end
42
43if true then
44 -- if we start a non-coroutine lane with a yielding function, we should get an error, right?
45 local fun_g = lanes.gen("*", { name = 'auto' }, yielder)
46 local h = fun_g("hello", "world", "!")
47 local err, status, stack = h:join()
48 PRINT(err, status, stack)
49 -- the actual error message is not the same for Lua 5.1
50 -- of course, it also has to be different for LuaJIT as well
51 -- also, LuaJIT prepends a file:line to the actual error message, which Lua5.1 does not.
52 local msgs = {
53 ["Lua 5.1"] = jit and "attempt to yield across C-call boundary" or "attempt to yield across metamethod/C-call boundary",
54 ["Lua 5.2"] = "attempt to yield from outside a coroutine",
55 ["Lua 5.3"] = "attempt to yield from outside a coroutine",
56 ["Lua 5.4"] = "attempt to yield from outside a coroutine"
57 }
58 local expected_msg = msgs[_VERSION]
59 PRINT("expected_msg = " .. expected_msg)
60 assert(err == nil and string.find(status, expected_msg, 1, true) and stack == nil, "status = " .. status)
61end
62
63-- the generator
64local coro_g = lanes.coro("*", {name = "auto"}, yielder)
65
66if true then
67 -- launch coroutine lane
68 local h2 = coro_g("hello", "world", "!")
69 -- read the yielded values, sending back the expected index
70 assert(h2:resume(1) == "hello")
71 assert(h2:resume(2) == "world")
72 assert(h2:resume(3) == "!")
73 -- the lane return value is available as usual
74 local r = h2[1]
75 assert(r == "done!")
76end
77
78if true then
79 -- another coroutine lane
80 local h3 = coro_g("hello", "world", "!")
81
82 -- yielded values are available as regular return values
83 assert(h3[1] == "hello" and h3.status == "suspended")
84 -- since we consumed the returned values, they should not be here when we resume
85 assert(h3:resume(1) == nil)
86
87 -- similarly, we can get them with join()
88 assert(h3:join() == "world" and h3.status == "suspended")
89 -- since we consumed the returned values, they should not be here when we resume
90 assert(h3:resume(2) == nil)
91
92 -- the rest should work as usual
93 assert(h3:resume(3) == "!")
94
95 -- the final return value of the lane body remains to be read
96 assert(h3:join() == "done!" and h3.status == "done")
97end
diff --git a/unit_tests/scripts/coro/cancelling_suspended.lua b/unit_tests/scripts/coro/cancelling_suspended.lua
new file mode 100644
index 0000000..3a29e55
--- /dev/null
+++ b/unit_tests/scripts/coro/cancelling_suspended.lua
@@ -0,0 +1,31 @@
1local fixture = require "fixture"
2local lanes = require "lanes".configure{on_state_create = fixture.on_state_create}
3
4local fixture = require "fixture"
5lanes.finally(fixture.throwing_finalizer)
6
7local utils = lanes.require "_utils"
8local PRINT = utils.MAKE_PRINT()
9
10--------------------------------------------------
11-- TEST: cancelling a suspended Lane should end it
12--------------------------------------------------
13if true then
14 -- the generator
15 local coro_g = lanes.coro("*", utils.yield_one_by_one)
16
17 -- start the lane
18 local h = coro_g("hello", "world", "!")
19 repeat until h.status == "suspended"
20
21 -- first cancellation attempt: don't wake the lane
22 local b, r = h:cancel("soft", 0.5)
23 -- the lane is still blocked in its suspended state
24 assert(b == false and r == "timeout" and h.status == "suspended", "got " .. tostring(b) .. " " .. tostring(r) .. " " .. h.status)
25
26 -- cancel the Lane again, this time waking it. it will resume, and yielder()'s will break out of its infinite loop
27 h:cancel("soft", nil, true)
28
29 -- lane should be done, because it returned cooperatively when detecting a soft cancel
30 assert(h.status == "done", "got " .. h.status)
31end
diff --git a/unit_tests/scripts/coro/collect_yielded_lane.lua b/unit_tests/scripts/coro/collect_yielded_lane.lua
new file mode 100644
index 0000000..2ee58f8
--- /dev/null
+++ b/unit_tests/scripts/coro/collect_yielded_lane.lua
@@ -0,0 +1,64 @@
1local fixture = require "fixture"
2local lanes = require "lanes".configure{on_state_create = fixture.on_state_create}
3
4local fixture = require "fixture"
5lanes.finally(fixture.throwing_finalizer)
6
7-- this test is only for Lua 5.4+
8local utils = lanes.require "_utils54"
9local PRINT = utils.MAKE_PRINT()
10
11local out_linda = lanes.linda()
12
13------------------------------------------------------------------------------
14-- TEST: to-be-closed variables are properly closed when the lane is collected
15------------------------------------------------------------------------------
16if true then
17 -- the generator
18 local coro_g = lanes.coro("*", utils.yielder_with_to_be_closed)
19
20 -- start the lane
21 local h = coro_g(out_linda)
22
23 -- join the lane. it should be done and give back the values resulting of the first yield point
24 local r, v1, v2 = h:join()
25 assert(r == true and v1 == "I yield!" and v2 == 1, "got " .. tostring(r) .. " " .. tostring(v1) .. " " .. tostring(v2))
26 assert(h.status == "done", "got " .. h.status)
27
28 -- force collection of the lane
29 h = nil
30 collectgarbage()
31
32 -- I want the to-be-closed variable of the coroutine linda to be properly closed
33 local s, r = out_linda:receive(0, "out")
34 assert(s == "out" and r == "Closed!", "coro got " .. tostring(s) .. " " .. tostring(r)) -- THIS TEST FAILS
35end
36
37---------------------------------------------------------------------------------------------------
38-- TEST: if a to-be-closed handler takes longer than the join timeout, everything works as expected
39---------------------------------------------------------------------------------------------------
40if true then
41 -- the generator
42 local coro_g = lanes.coro("*", utils.yielder_with_to_be_closed)
43
44 -- start the lane. The to-be-closed handler will sleep for 1 second
45 local h = coro_g(out_linda, 1)
46
47 -- first join attempt should timeout
48 local r, v = h:join(0.6)
49 assert(r == nil and v == "timeout", "got " .. tostring(r) .. " " .. tostring(v))
50 assert(h.status == "running", "got " .. h.status)
51
52 -- join the lane again. it should be done and give back the values resulting of the first yield point
53 local r, v1, v2 = h:join(0.6)
54 assert(r == true and v1 == "I yield!" and v2 == 1, "got " .. tostring(r) .. " " .. tostring(v1) .. " " .. tostring(v2))
55 assert(h.status == "done", "got " .. h.status)
56
57 -- force collection of the lane
58 h = nil
59 collectgarbage()
60
61 -- I want the to-be-closed variable of the coroutine linda to be properly closed
62 local s, r = out_linda:receive(0, "out")
63 assert(s == "out" and r == "Closed!", "coro got " .. tostring(s) .. " " .. tostring(r)) -- THIS TEST FAILS
64end
diff --git a/unit_tests/scripts/coro/error_handling.lua b/unit_tests/scripts/coro/error_handling.lua
index ba6cff6..1cfb8c8 100644
--- a/unit_tests/scripts/coro/error_handling.lua
+++ b/unit_tests/scripts/coro/error_handling.lua
@@ -38,15 +38,15 @@ local force_error_test = function(error_trace_level_)
38 utils.dump_error_stack(error_trace_level_, c) 38 utils.dump_error_stack(error_trace_level_, c)
39end 39end
40 40
41if false then 41if true then
42 force_error_test("minimal") 42 force_error_test("minimal")
43end 43end
44 44
45if false then 45if true then
46 force_error_test("basic") 46 force_error_test("basic")
47end 47end
48 48
49if false then 49if true then
50 force_error_test("extended") 50 force_error_test("extended")
51end 51end
52 52
diff --git a/unit_tests/scripts/coro/index_suspended.lua b/unit_tests/scripts/coro/index_suspended.lua
new file mode 100644
index 0000000..2cd8c28
--- /dev/null
+++ b/unit_tests/scripts/coro/index_suspended.lua
@@ -0,0 +1,28 @@
1local lanes = require "lanes"
2
3local fixture = require "fixture"
4lanes.finally(fixture.throwing_finalizer)
5
6local utils = lanes.require "_utils"
7local PRINT = utils.MAKE_PRINT()
8
9-- the coroutine generator
10local coro_g = lanes.coro("*", {name = "auto"}, utils.yield_one_by_one)
11
12-------------------------------------------------------------------------
13-- TEST: if we index a yielded lane, we should get the last yielded value
14-------------------------------------------------------------------------
15if true then
16 -- launch coroutine lane
17 local h = coro_g("hello", "world", "!")
18 -- read the first yielded value, sending back the expected index
19 assert(h:resume(1) == "hello")
20 -- indexing multiple times gives back the same us the same yielded value
21 local r1 = h[1]
22 local r2 = h[1]
23 local r3 = h[1]
24 assert(r1 == "world" and r2 == "world" and r3 == "world", "got " .. r1 .. " " .. r2 .. " " .. r3)
25 -- once the lane was indexed, it is no longer resumable (just like after join)
26 local b, e = pcall(h.resume, h, 2)
27 assert(b == false and e == "cannot resume non-suspended coroutine Lane")
28end
diff --git a/unit_tests/scripts/coro/join_suspended.lua b/unit_tests/scripts/coro/join_suspended.lua
new file mode 100644
index 0000000..33be406
--- /dev/null
+++ b/unit_tests/scripts/coro/join_suspended.lua
@@ -0,0 +1,24 @@
1local lanes = require "lanes"
2
3local fixture = require "fixture"
4lanes.finally(fixture.throwing_finalizer)
5
6local utils = lanes.require "_utils"
7local PRINT = utils.MAKE_PRINT()
8
9-- the coroutine generator
10local coro_g = lanes.coro("*", {name = "auto"}, utils.yield_one_by_one)
11
12---------------------------------------------------
13-- TEST: if we join a yielded lane, the lane aborts
14---------------------------------------------------
15if true then
16 -- launch coroutine lane
17 local h = coro_g("hello", "world", "!")
18 -- read the first yielded value, sending back the expected index
19 assert(h:resume(1) == "hello")
20 -- join the lane. since it will reach a yield point, it unblocks and ends. last yielded values are returned normally
21 local b, r = h:join(0.5)
22 local s = h.status
23 assert(s == "done" and b == true and r == "world", "got " .. s .. " " .. tostring(b) .. " " .. tostring(r))
24end
diff --git a/unit_tests/scripts/coro/linda_in_close_handler.lua b/unit_tests/scripts/coro/linda_in_close_handler.lua
new file mode 100644
index 0000000..8636f01
--- /dev/null
+++ b/unit_tests/scripts/coro/linda_in_close_handler.lua
@@ -0,0 +1,43 @@
1local fixture = require "fixture"
2local lanes = require "lanes".configure{on_state_create = fixture.on_state_create}
3
4local fixture = require "fixture"
5lanes.finally(fixture.throwing_finalizer)
6
7-- this test is only for Lua 5.4+
8local utils = lanes.require "_utils54"
9local PRINT = utils.MAKE_PRINT()
10
11local out_linda = lanes.linda()
12
13local test_close = function(what_, f_)
14 local c = coroutine.create(f_)
15 for i = 1, 10 do
16 local t, r1, r2 = coroutine.resume(c, out_linda) -- returns true + <yielded values>
17 assert(t == true and r1 == "I yield!" and r2 == i, "got " .. tostring(t) .. " " .. tostring(r1) .. " " .. tostring(r2))
18 local s = coroutine.status(c)
19 assert(s == "suspended")
20 end
21 local r, s = coroutine.close(c)
22 assert(r == true and s == nil)
23 -- the local variable inside the yielder body should be closed
24 local s, r = out_linda:receive(0, "out")
25 assert(s == "out" and r == "Closed!", what_ .. " got " .. tostring(s) .. " " .. tostring(r))
26end
27
28---------------------------------------------------------
29-- TEST: first, try the close mechanism outside of a lane
30---------------------------------------------------------
31if true then
32 assert(type(utils.yielder_with_to_be_closed) == "function")
33 test_close("base", utils.yielder_with_to_be_closed)
34end
35
36---------------------------------------------------------------
37-- TEST: try again with a function obtained through dump/undump
38---------------------------------------------------------------
39if true then
40 -- note this means our yielder implementation can't have upvalues, as they are lost in the process
41 test_close("dumped", load(string.dump(utils.yielder_with_to_be_closed)))
42end
43
diff --git a/unit_tests/scripts/coro/regular_function.lua b/unit_tests/scripts/coro/regular_function.lua
new file mode 100644
index 0000000..09aa3b7
--- /dev/null
+++ b/unit_tests/scripts/coro/regular_function.lua
@@ -0,0 +1,38 @@
1local lanes = require "lanes".configure()
2
3local utils = lanes.require "_utils"
4local PRINT = utils.MAKE_PRINT()
5
6-- a lane body that just returns some value
7local returner = function(msg_)
8 local utils = lanes.require "_utils"
9 local PRINT = utils.MAKE_PRINT()
10 PRINT "In lane"
11 assert(msg_ == "hi")
12 return "bye"
13end
14
15-- a function that returns some value can run in a coroutine
16if true then
17 -- the generator
18 local g = lanes.coro("*", {name = "auto"}, returner)
19
20 -- launch lane
21 local h = g("hi")
22
23 local r = h[1]
24 assert(r == "bye")
25end
26
27-- can't resume a coro after the lane body has returned
28if true then
29 -- the generator
30 local g = lanes.coro("*", {name = "auto"}, returner)
31
32 -- launch lane
33 local h = g("hi")
34
35 -- resuming a lane that terminated execution should raise an error
36 local b, e = pcall(h.resume, h)
37 assert(b == false and type(e) == "string")
38end
diff --git a/unit_tests/scripts/coro/resume_basics.lua b/unit_tests/scripts/coro/resume_basics.lua
new file mode 100644
index 0000000..5b124f5
--- /dev/null
+++ b/unit_tests/scripts/coro/resume_basics.lua
@@ -0,0 +1,40 @@
1local lanes = require "lanes"
2
3local fixture = require "fixture"
4lanes.finally(fixture.throwing_finalizer)
5
6local utils = lanes.require "_utils"
7local PRINT = utils.MAKE_PRINT()
8
9-- the coroutine generator
10local coro_g = lanes.coro("*", {name = "auto"}, utils.yield_one_by_one)
11
12-------------------------------------------------------------------------------------------------
13-- TEST: we can resume as many times as the lane yields, then read the returned value on indexing
14-------------------------------------------------------------------------------------------------
15if true then
16 -- launch coroutine lane
17 local h = coro_g("hello", "world", "!")
18 -- read the yielded values, sending back the expected index
19 assert(h:resume(1) == "hello")
20 assert(h:resume(2) == "world")
21 assert(h:resume(3) == "!")
22 -- the lane return value is available as usual
23 local r = h[1]
24 assert(r == "bye!")
25end
26
27---------------------------------------------------------------------------------------------
28-- TEST: we can resume as many times as the lane yields, then read the returned value on join
29---------------------------------------------------------------------------------------------
30if true then
31 -- launch coroutine lane
32 local h = coro_g("hello", "world", "!")
33 -- read the yielded values, sending back the expected index
34 assert(h:resume(1) == "hello")
35 assert(h:resume(2) == "world")
36 assert(h:resume(3) == "!")
37 -- the lane return value is available as usual
38 local s, r = h:join()
39 assert(h.status == "done" and s == true and r == "bye!")
40end
diff --git a/unit_tests/scripts/coro/yielding_in_non_coro_errors.lua b/unit_tests/scripts/coro/yielding_in_non_coro_errors.lua
new file mode 100644
index 0000000..fc0c072
--- /dev/null
+++ b/unit_tests/scripts/coro/yielding_in_non_coro_errors.lua
@@ -0,0 +1,28 @@
1local lanes = require "lanes"
2
3local fixture = require "fixture"
4lanes.finally(fixture.throwing_finalizer)
5
6local utils = lanes.require "_utils"
7local PRINT = utils.MAKE_PRINT()
8
9--------------------------------------------------------------------------------------------------
10-- TEST: if we start a non-coroutine lane with a yielding function, we should get an error, right?
11--------------------------------------------------------------------------------------------------
12local fun_g = lanes.gen("*", { name = 'auto' }, utils.yield_one_by_one)
13local h = fun_g("hello", "world", "!")
14local err, status, stack = h:join()
15PRINT(err, status, stack)
16-- the actual error message is not the same for Lua 5.1
17-- of course, it also has to be different for LuaJIT as well
18-- also, LuaJIT prepends a file:line to the actual error message, which Lua5.1 does not.
19local msgs = {
20 ["Lua 5.1"] = jit and "attempt to yield across C-call boundary" or "attempt to yield across metamethod/C-call boundary",
21 ["Lua 5.2"] = "attempt to yield from outside a coroutine",
22 ["Lua 5.3"] = "attempt to yield from outside a coroutine",
23 ["Lua 5.4"] = "attempt to yield from outside a coroutine",
24 ["Lua 5.5"] = "attempt to yield from outside a coroutine"
25}
26local expected_msg = msgs[_VERSION]
27PRINT("expected_msg = " .. expected_msg)
28assert(err == nil and string.find(status, expected_msg, 1, true) and stack == nil, "status = " .. status)
diff --git a/unit_tests/scripts/lane/body_is_a_c_function.lua b/unit_tests/scripts/lane/body_is_a_c_function.lua
new file mode 100644
index 0000000..d8d329f
--- /dev/null
+++ b/unit_tests/scripts/lane/body_is_a_c_function.lua
@@ -0,0 +1,28 @@
1local lanes = require "lanes".configure()
2
3-- ##################################################################################################
4-- ##################################################################################################
5-- ##################################################################################################
6
7-- we can create a generator where the lane body is a C function
8do
9 local b, g = pcall(lanes.gen, "*", print)
10 assert(b == true and type(g) == "function")
11 -- we can start the lane
12 local b, h = pcall(g, "hello")
13 -- the lane runs normally
14 h:join()
15 assert(h.status == "done")
16end
17
18-- we can create a generator where the lane body is a C function that raises an error
19do
20 local b, g = pcall(lanes.gen, "*", error)
21 assert(b == true and type(g) == "function")
22 -- we can start the lane
23 local b, h = pcall(g, "this is an error")
24 -- this provides the error that occurred in the lane
25 local s, e, t = h:join()
26 assert(h.status == "error")
27 assert(s == nil and e == "this is an error" and t == nil)
28end
diff --git a/unit_tests/scripts/lane/cooperative_shutdown.lua b/unit_tests/scripts/lane/cooperative_shutdown.lua
index 756e33c..0a0943e 100644
--- a/unit_tests/scripts/lane/cooperative_shutdown.lua
+++ b/unit_tests/scripts/lane/cooperative_shutdown.lua
@@ -1,10 +1,10 @@
1local lanes = require "lanes" 1local lanes = require "lanes".configure{on_state_create = require "fixture".on_state_create}
2 2
3-- launch lanes that cooperate properly with cancellation request 3-- launch lanes that cooperate properly with cancellation request
4 4
5local lane1 = function() 5local lane1 = function()
6 lane_threadname("lane1") 6 lane_threadname("lane1")
7 -- loop breaks on cancellation request 7 -- loop breaks on soft cancellation request
8 repeat 8 repeat
9 lanes.sleep(0) 9 lanes.sleep(0)
10 until cancel_test() 10 until cancel_test()
@@ -23,7 +23,6 @@ end
23local lane3 = function() 23local lane3 = function()
24 lane_threadname("lane3") 24 lane_threadname("lane3")
25 -- this one cooperates too, because of the hook cancellation modes that Lanes will be using 25 -- this one cooperates too, because of the hook cancellation modes that Lanes will be using
26 -- but not with LuaJIT, because the function is compiled, and we don't call anyone, so no hook triggers
27 local fixture = require "fixture" 26 local fixture = require "fixture"
28 repeat until fixture.give_me_back(false) 27 repeat until fixture.give_me_back(false)
29end 28end
@@ -43,7 +42,14 @@ local h2 = g2(linda)
43 42
44local h3 = g3() 43local h3 = g3()
45 44
46-- wait until they are both started 45lanes.sleep(0.1)
47repeat until h1.status == "running" and h2.status == "waiting" and h3.status == "running" 46
47local is_running = function(lane_h)
48 local status = lane_h.status
49 return status == "running" or status == "waiting"
50end
51
52-- wait until they are all started
53repeat until is_running(h1) and is_running(h2) and is_running(h3)
48 54
49-- let the script terminate, Lanes should not crash at shutdown 55-- let the script terminate, Lanes should not crash at shutdown
diff --git a/unit_tests/scripts/lane/tasking_cancelling.lua b/unit_tests/scripts/lane/tasking_cancelling.lua
index 85600ab..d153ffa 100644
--- a/unit_tests/scripts/lane/tasking_cancelling.lua
+++ b/unit_tests/scripts/lane/tasking_cancelling.lua
@@ -1,4 +1,7 @@
1local require_lanes_result_1, require_lanes_result_2 = require "lanes".configure(config).configure() 1local require_fixture_result_1, require_fixture_result_2 = require "fixture"
2local fixture = assert(require_fixture_result_1)
3
4local require_lanes_result_1, require_lanes_result_2 = require "lanes".configure{on_state_create = fixture.on_state_create}.configure()
2print("require_lanes_result:", require_lanes_result_1, require_lanes_result_2) 5print("require_lanes_result:", require_lanes_result_1, require_lanes_result_2)
3local lanes = require_lanes_result_1 6local lanes = require_lanes_result_1
4 7
@@ -15,69 +18,34 @@ local lanes_linda = assert(lanes.linda)
15-- ################################################################################################## 18-- ##################################################################################################
16-- ################################################################################################## 19-- ##################################################################################################
17 20
18local function task(a, b, c) 21-- cancellation of cooperating lanes
19 lane_threadname("task("..a..","..b..","..c..")") 22local cooperative = function()
20 --error "111" -- testing error messages 23 local fixture = assert(require "fixture")
21 assert(hey) 24 local which_cancel
22 local v=0 25 repeat
23 for i=a,b,c do 26 fixture.block_for(0.2)
24 v= v+i 27 which_cancel = cancel_test()
25 end 28 until which_cancel
26 return v, hey 29 return which_cancel
27end
28
29local gc_cb = function(name_, status_)
30 PRINT(" ---> lane '" .. name_ .. "' collected with status '" .. status_ .. "'")
31end 30end
31-- soft and hard are behaviorally equivalent when no blocking linda operation is involved
32local cooperative_lane_soft = lanes_gen("*", { name = 'auto' }, cooperative)()
33local a, b = cooperative_lane_soft:cancel("soft", 0) -- issue request, do not wait for lane to terminate
34assert(a == false and b == "timeout", "got " .. tostring(a) .. " " .. tostring(b))
35assert(cooperative_lane_soft[1] == "soft") -- return value of the lane body is the value returned by cancel_test()
36local cooperative_lane_hard = lanes_gen("*", { name = 'auto' }, cooperative)()
37local c, d = cooperative_lane_hard:cancel("hard", 0) -- issue request, do not wait for lane to terminate
38assert(a == false and b == "timeout", "got " .. tostring(c) .. " " .. tostring(d))
39assert(cooperative_lane_hard[1] == "hard") -- return value of the lane body is the value returned by cancel_test()
32 40
33-- ################################################################################################## 41-- ##################################################################################################
34-- ##################################################################################################
35-- ##################################################################################################
36
37PRINT("\n\n", "---=== Tasking (cancelling) ===---", "\n\n")
38
39local task_launch2 = lanes_gen("", { name = 'auto', globals={hey=true}, gc_cb = gc_cb }, task)
40
41local N=999999999
42local lane9= task_launch2(1,N,1) -- huuuuuuge...
43
44-- Wait until state changes "pending"->"running"
45--
46local st
47local t0= os.time()
48while os.time()-t0 < 5 do
49 st= lane9.status
50 io.stderr:write((i==1) and st.." " or '.')
51 if st~="pending" then break end
52end
53PRINT(" "..st)
54
55if st=="error" then
56 local _= lane9[0] -- propagate the error here
57end
58if st=="done" then
59 error("Looping to "..N.." was not long enough (cannot test cancellation)")
60end
61assert(st=="running", "st == " .. st)
62
63-- when running under luajit, the function is JIT-ed, and the instruction count isn't hit, so we need a different hook
64lane9:cancel(jit and "line" or "count", 100) -- 0 timeout, hook triggers cancelslation when reaching the specified count
65
66local t0= os.time()
67while os.time()-t0 < 5 do
68 st= lane9.status
69 io.stderr:write((i==1) and st.." " or '.')
70 if st~="running" then break end
71end
72PRINT(" "..st)
73assert(st == "cancelled", "st is '" .. st .. "' instead of 'cancelled'")
74 42
75-- cancellation of lanes waiting on a linda 43-- cancellation of lanes waiting on a linda
76local limited = lanes_linda("limited") 44local limited = lanes_linda{name = "limited"}
77assert.fails(function() limited:limit("key", -1) end) 45assert.fails(function() limited:limit("key", -1) end)
78assert.failsnot(function() limited:limit("key", 1) end) 46assert.failsnot(function() limited:limit("key", 1) end)
79-- [[################################################ 47-- [[################################################
80limited:send("key", "hello") -- saturate linda 48limited:send("key", "hello") -- saturate linda, so that subsequent sends will block
81for k, v in pairs(limited:dump()) do 49for k, v in pairs(limited:dump()) do
82 PRINT("limited[" .. tostring(k) .. "] = " .. tostring(v)) 50 PRINT("limited[" .. tostring(k) .. "] = " .. tostring(v))
83end 51end
@@ -88,11 +56,15 @@ local wait_send = function()
88end 56end
89 57
90local wait_send_lane = lanes_gen("*", { name = 'auto' }, wait_send)() 58local wait_send_lane = lanes_gen("*", { name = 'auto' }, wait_send)()
91repeat until wait_send_lane.status == "waiting" 59repeat
92print "wait_send_lane is waiting" 60 io.stderr:write('!')
61 -- currently mingw64 builds can deadlock if we cancel the lane too early (before the linda blocks, at it causes the linda condvar not to be signalled)
62 lanes.sleep(0.1)
63until wait_send_lane.status == "waiting"
64PRINT "wait_send_lane is waiting"
93wait_send_lane:cancel() -- hard cancel, 0 timeout 65wait_send_lane:cancel() -- hard cancel, 0 timeout
94repeat until wait_send_lane.status == "cancelled" 66repeat until wait_send_lane.status == "cancelled"
95print "wait_send_lane is cancelled" 67PRINT "wait_send_lane is cancelled"
96--################################################]] 68--################################################]]
97local wait_receive = function() 69local wait_receive = function()
98 local k, v 70 local k, v
@@ -101,22 +73,30 @@ local wait_receive = function()
101end 73end
102 74
103local wait_receive_lane = lanes_gen("*", { name = 'auto' }, wait_receive)() 75local wait_receive_lane = lanes_gen("*", { name = 'auto' }, wait_receive)()
104repeat until wait_receive_lane.status == "waiting" 76repeat
105print "wait_receive_lane is waiting" 77 io.stderr:write('!')
78 -- currently mingw64 builds can deadlock if we cancel the lane too early (before the linda blocks, at it causes the linda condvar not to be signalled)
79 lanes.sleep(0.1)
80until wait_receive_lane.status == "waiting"
81PRINT "wait_receive_lane is waiting"
106wait_receive_lane:cancel() -- hard cancel, 0 timeout 82wait_receive_lane:cancel() -- hard cancel, 0 timeout
107repeat until wait_receive_lane.status == "cancelled" 83repeat until wait_receive_lane.status == "cancelled"
108print "wait_receive_lane is cancelled" 84PRINT "wait_receive_lane is cancelled"
109--################################################]] 85--################################################]]
110local wait_receive_batched = function() 86local wait_receive_batched = function()
111 local k, v1, v2 87 local k, v1, v2
112 set_finalizer(function() print("wait_receive_batched", k, v1, v2) end) 88 set_finalizer(function() print("wait_receive_batched", k, v1, v2) end)
113 k, v1, v2 = limited:receive(limited.batched, "dummy", 2) -- infinite timeout, returns only when lane is cancelled 89 k, v1, v2 = limited:receive_batched("dummy", 2) -- infinite timeout, returns only when lane is cancelled
114end 90end
115 91
116local wait_receive_batched_lane = lanes_gen("*", { name = 'auto' }, wait_receive_batched)() 92local wait_receive_batched_lane = lanes_gen("*", { name = 'auto' }, wait_receive_batched)()
117repeat until wait_receive_batched_lane.status == "waiting" 93repeat
118print "wait_receive_batched_lane is waiting" 94 io.stderr:write('!')
95 -- currently mingw64 builds can deadlock if we cancel the lane too early (before the linda blocks, at it causes the linda condvar not to be signalled)
96 lanes.sleep(0.1)
97until wait_receive_batched_lane.status == "waiting"
98PRINT "wait_receive_batched_lane is waiting"
119wait_receive_batched_lane:cancel() -- hard cancel, 0 timeout 99wait_receive_batched_lane:cancel() -- hard cancel, 0 timeout
120repeat until wait_receive_batched_lane.status == "cancelled" 100repeat until wait_receive_batched_lane.status == "cancelled"
121print "wait_receive_batched_lane is cancelled" 101PRINT "wait_receive_batched_lane is cancelled"
122--################################################]] 102--################################################]]
diff --git a/unit_tests/scripts/lane/tasking_cancelling_with_hook.lua b/unit_tests/scripts/lane/tasking_cancelling_with_hook.lua
new file mode 100644
index 0000000..56b934f
--- /dev/null
+++ b/unit_tests/scripts/lane/tasking_cancelling_with_hook.lua
@@ -0,0 +1,68 @@
1local require_lanes_result_1, require_lanes_result_2 = require "lanes".configure(config).configure()
2print("require_lanes_result:", require_lanes_result_1, require_lanes_result_2)
3local lanes = require_lanes_result_1
4
5local require_assert_result_1, require_assert_result_2 = require "_assert"
6print("require_assert_result:", require_assert_result_1, require_assert_result_2)
7
8local utils = lanes.require "_utils"
9local PRINT = utils.MAKE_PRINT()
10
11-- ##################################################################################################
12-- ##################################################################################################
13-- ##################################################################################################
14
15local function task(a, b, c)
16 lane_threadname("task("..a..","..b..","..c..")")
17 --error "111" -- testing error messages
18 assert(hey)
19 local v=0
20 for i=a,b,c do
21 v= v+i
22 end
23 return v, hey
24end
25
26local gc_cb = function(name_, status_)
27 PRINT(" ---> lane '" .. name_ .. "' collected with status '" .. status_ .. "'")
28end
29
30-- ##################################################################################################
31-- ##################################################################################################
32-- ##################################################################################################
33
34local generator = lanes.gen("", { name = 'auto', globals={hey=true}, gc_cb = gc_cb }, task)
35
36local N = 999999999
37local lane_h = generator(1,N,1) -- huuuuuuge...
38
39-- Wait until state changes "pending"->"running"
40--
41local st
42local t0 = os.time()
43while os.time()-t0 < 5 do
44 st = lane_h.status
45 io.stderr:write((i==1) and st.." " or '.')
46 if st~="pending" then break end
47end
48PRINT(" "..st)
49
50if st == "error" then
51 local _ = lane_h[0] -- propagate the error here
52end
53if st == "done" then
54 error("Looping to "..N.." was not long enough (cannot test cancellation)")
55end
56assert(st == "running", "st == " .. st)
57
58-- when running under luajit, the function is JIT-ed, and the instruction count isn't hit, so we need a different hook
59lane_h:cancel(jit and "line" or "count", 100) -- 0 timeout, hook triggers cancelslation when reaching the specified count
60
61local t0 = os.time()
62while os.time()-t0 < 5 do
63 st = lane_h.status
64 io.stderr:write((i==1) and st.." " or '.')
65 if st~="running" then break end
66end
67PRINT(" "..st)
68assert(st == "cancelled", "st is '" .. st .. "' instead of 'cancelled'")
diff --git a/unit_tests/scripts/lane/tasking_comms_criss_cross.lua b/unit_tests/scripts/lane/tasking_comms_criss_cross.lua
index 497e81d..610da8b 100644
--- a/unit_tests/scripts/lane/tasking_comms_criss_cross.lua
+++ b/unit_tests/scripts/lane/tasking_comms_criss_cross.lua
@@ -42,7 +42,7 @@ local tc = lanes_gen("io", { name = 'auto', gc_cb = gc_cb },
42 end 42 end
43) 43)
44 44
45local linda= lanes_linda("criss cross") 45local linda= lanes_linda{name = "criss cross"}
46 46
47local a,b= tc(linda, "A","B"), tc(linda, "B","A") -- launching two lanes, twisted comms 47local a,b= tc(linda, "A","B"), tc(linda, "B","A") -- launching two lanes, twisted comms
48 48
diff --git a/unit_tests/scripts/lane/tasking_communications.lua b/unit_tests/scripts/lane/tasking_communications.lua
index 1fd43b0..01842b4 100644
--- a/unit_tests/scripts/lane/tasking_communications.lua
+++ b/unit_tests/scripts/lane/tasking_communications.lua
@@ -72,7 +72,7 @@ local chunk= function(linda)
72 WR("chunk ", "Lane ends!\n") 72 WR("chunk ", "Lane ends!\n")
73end 73end
74 74
75local linda = lanes_linda("communications") 75local linda = lanes_linda{name = "communications"}
76assert(type(linda) == "userdata" and tostring(linda) == "Linda: communications") 76assert(type(linda) == "userdata" and tostring(linda) == "Linda: communications")
77 -- 77 --
78 -- ["->"] master -> slave 78 -- ["->"] master -> slave
@@ -90,7 +90,7 @@ local b,x,y,z,w = linda:get("<->", 4)
90assert(b == 3 and x == "x" and y == "y" and z == "z" and w == nil) 90assert(b == 3 and x == "x" and y == "y" and z == "z" and w == nil)
91local k, x = linda:receive("<->") 91local k, x = linda:receive("<->")
92assert(k == "<->" and x == "x") 92assert(k == "<->" and x == "x")
93local k,y,z = linda:receive(linda.batched, "<->", 2) 93local k,y,z = linda:receive_batched("<->", 2)
94assert(k == "<->" and y == "y" and z == "z") 94assert(k == "<->" and y == "y" and z == "z")
95linda:set("<->") 95linda:set("<->")
96local b,x,y,z,w = linda:get("<->", 4) 96local b,x,y,z,w = linda:get("<->", 4)
diff --git a/unit_tests/scripts/lane/tasking_join_test.lua b/unit_tests/scripts/lane/tasking_join_test.lua
index 2fbce6c..495a709 100644
--- a/unit_tests/scripts/lane/tasking_join_test.lua
+++ b/unit_tests/scripts/lane/tasking_join_test.lua
@@ -30,14 +30,19 @@ end
30 30
31PRINT("---=== :join test ===---", "\n\n") 31PRINT("---=== :join test ===---", "\n\n")
32 32
33-- a lane body that returns nothing is successfully joined with true, nil
34local r, ret = lanes_gen(function() end)():join()
35assert(r == true and ret == nil)
36
33-- NOTE: 'unpack()' cannot be used on the lane handle; it will always return nil 37-- NOTE: 'unpack()' cannot be used on the lane handle; it will always return nil
34-- (unless [1..n] has been read earlier, in which case it would seemingly 38-- (unless [1..n] has been read earlier, in which case it would seemingly
35-- work). 39-- work).
36 40
37local S= lanes_gen("table", { name = 'auto', gc_cb = gc_cb }, 41local S = lanes_gen("table", { name = 'auto', gc_cb = gc_cb },
38 function(arg) 42 function(arg)
39 lane_threadname "join test lane" 43 lane_threadname "join test lane"
40 set_finalizer(function() end) 44 set_finalizer(function() end)
45 -- take arg table, reverse its contents in aux, then return the unpacked result
41 local aux= {} 46 local aux= {}
42 for i, v in ipairs(arg) do 47 for i, v in ipairs(arg) do
43 table.insert(aux, 1, v) 48 table.insert(aux, 1, v)
@@ -46,15 +51,16 @@ local S= lanes_gen("table", { name = 'auto', gc_cb = gc_cb },
46 return (unpack or table.unpack)(aux) 51 return (unpack or table.unpack)(aux)
47end) 52end)
48 53
49h= S { 12, 13, 14 } -- execution starts, h[1..3] will get the return values 54local h = S { 12, 13, 14 } -- execution starts, h[1..3] will get the return values
50-- wait a bit so that the lane has a chance to set its debug name 55-- wait a bit so that the lane has a chance to set its debug name
51SLEEP(0.5) 56SLEEP(0.5)
52print("joining with '" .. h:get_threadname() .. "'") 57print("joining with '" .. h:get_threadname() .. "'")
53local a,b,c,d= h:join() 58local r, a, b, c, d = h:join()
54if h.status == "error" then 59if h.status == "error" then
55 print(h:get_threadname(), "error: " , a, b, c, d) 60 print(h:get_threadname(), "error: " , r, a, b, c, d)
56else 61else
57 print(h:get_threadname(), a,b,c,d) 62 print(h:get_threadname(), r, a, b, c, d)
63 assert(r==true, "r == " .. tostring(r))
58 assert(a==14, "a == " .. tostring(a)) 64 assert(a==14, "a == " .. tostring(a))
59 assert(b==13, "b == " .. tostring(b)) 65 assert(b==13, "b == " .. tostring(b))
60 assert(c==12, "c == " .. tostring(c)) 66 assert(c==12, "c == " .. tostring(c))
diff --git a/unit_tests/scripts/lane/tasking_send_receive_code.lua b/unit_tests/scripts/lane/tasking_send_receive_code.lua
index e329a88..fdc2602 100644
--- a/unit_tests/scripts/lane/tasking_send_receive_code.lua
+++ b/unit_tests/scripts/lane/tasking_send_receive_code.lua
@@ -53,28 +53,26 @@ local function chunk2(linda)
53 assert(info.linedefined == 32, "bad linedefined") -- start of 'chunk2' 53 assert(info.linedefined == 32, "bad linedefined") -- start of 'chunk2'
54 assert(config.strip_functions and info.currentline==-1 or info.currentline > info.linedefined, "bad currentline") -- line of 'debug.getinfo' 54 assert(config.strip_functions and info.currentline==-1 or info.currentline > info.linedefined, "bad currentline") -- line of 'debug.getinfo'
55 assert(info.lastlinedefined > info.currentline, "bad lastlinedefined") -- end of 'chunk2' 55 assert(info.lastlinedefined > info.currentline, "bad lastlinedefined") -- end of 'chunk2'
56 local k,func= linda:receive("down") 56 assert(linda:count("down") == 2, "bad linda contents") -- function, "ok"
57 assert(type(func)=="function", "not a function") 57 local k,func,str= linda:receive_batched("down", 2)
58 assert(k=="down") 58 assert(k=="down")
59 assert(type(func)=="function", "not a function")
60 assert(str=="ok", "bad receive result: " .. tostring(k) .. " -> ".. tostring(str))
61 assert(linda:count("down") == 0, "bad linda contents") -- nothing
59 62
60 func(linda) 63 func(linda)
61
62 local k,str= linda:receive("down")
63 assert(str=="ok", "bad receive result")
64
65 linda:send("up", function() return ":)" end, "ok2") 64 linda:send("up", function() return ":)" end, "ok2")
66end 65end
67 66
68local linda = lanes_linda("auto") 67local linda = lanes_linda{name = "auto"}
69local t2= lanes_gen("debug,package,string,io", { name = 'auto', gc_cb = gc_cb }, chunk2)(linda) -- prepare & launch 68local t2= lanes_gen("debug,package,string,io", { name = 'auto', gc_cb = gc_cb }, chunk2)(linda) -- prepare & launch
70linda:send("down", function(linda) linda:send("up", "ready!") end, 69linda:send("down", function(linda) linda:send("up", "ready!") end, "ok")
71 "ok")
72-- wait to see if the tiny function gets executed 70-- wait to see if the tiny function gets executed
73-- 71--
74local k,s= linda:receive(1, "up") 72local k,s= linda:receive(1, "up")
75if t2.status == "error" then 73if t2.status == "error" then
76 PRINT("t2 error: " , t2:join()) 74 local n,err,s = t2:join()
77 assert(false) 75 assert(false, "t2 error: " .. err)
78end 76end
79PRINT(s) 77PRINT(s)
80assert(s=="ready!", s .. " is not 'ready!'") 78assert(s=="ready!", s .. " is not 'ready!'")
diff --git a/unit_tests/scripts/lane/uncooperative_shutdown.lua b/unit_tests/scripts/lane/uncooperative_shutdown.lua
index 89e1ff8..eb89ed3 100644
--- a/unit_tests/scripts/lane/uncooperative_shutdown.lua
+++ b/unit_tests/scripts/lane/uncooperative_shutdown.lua
@@ -8,7 +8,7 @@ local lanes = require "lanes".configure{shutdown_timeout = 0.001, on_state_creat
8-- launch lanes that blocks forever 8-- launch lanes that blocks forever
9local lane = function() 9local lane = function()
10 local fixture = require "fixture" 10 local fixture = require "fixture"
11 fixture.sleep_for() 11 fixture.block_for()
12end 12end
13 13
14-- the generator 14-- the generator
diff --git a/unit_tests/scripts/linda/multiple_keepers.lua b/unit_tests/scripts/linda/multiple_keepers.lua
index 8733087..267d874 100644
--- a/unit_tests/scripts/linda/multiple_keepers.lua
+++ b/unit_tests/scripts/linda/multiple_keepers.lua
@@ -2,9 +2,9 @@
2local require_lanes_result_1, require_lanes_result_2 = require "lanes".configure{nb_user_keepers = 3, keepers_gc_threshold = 500} 2local require_lanes_result_1, require_lanes_result_2 = require "lanes".configure{nb_user_keepers = 3, keepers_gc_threshold = 500}
3local lanes = require_lanes_result_1 3local lanes = require_lanes_result_1
4 4
5local a = lanes.linda("A", 1) 5local a = lanes.linda{name = "A", group = 1}
6local b = lanes.linda("B", 2) 6local b = lanes.linda{name = "B", group = 2}
7local c = lanes.linda("C", 3) 7local c = lanes.linda{name = "C", group = 3}
8 8
9-- store each linda in the other 2 9-- store each linda in the other 2
10do 10do
diff --git a/unit_tests/scripts/linda/send_receive_func_and_string.lua b/unit_tests/scripts/linda/send_receive_func_and_string.lua
new file mode 100644
index 0000000..188cfcd
--- /dev/null
+++ b/unit_tests/scripts/linda/send_receive_func_and_string.lua
@@ -0,0 +1,13 @@
1local lanes = require "lanes"
2
3-- a newly created linda doesn't contain anything
4local l = lanes.linda()
5
6-- send a function and a string, make sure that's what we read back
7l:send("k", function() end, "str")
8local c = l:count("k")
9assert(c == 2, "got " .. c)
10local k, v1, v2 = l:receive_batched("k", 2)
11local tv1, tv2 = type(v1), type(v2)
12assert(k == "k" and tv1 == "function" and tv2 == "string", "got " .. tv1 .. " " .. tv2)
13assert(l:count("k") == 0)
diff --git a/unit_tests/scripts/linda/send_registered_userdata.lua b/unit_tests/scripts/linda/send_registered_userdata.lua
index 2c0195a..90c05c9 100644
--- a/unit_tests/scripts/linda/send_registered_userdata.lua
+++ b/unit_tests/scripts/linda/send_registered_userdata.lua
@@ -1,5 +1,5 @@
1local lanes = require 'lanes'.configure{with_timers = false} 1local lanes = require 'lanes'.configure{with_timers = false}
2local l = lanes.linda'gleh' 2local l = lanes.linda{name = 'gleh'}
3l:set('yo', io.stdin) 3l:set('yo', io.stdin)
4local n, stdin_out = l:get('yo') 4local n, stdin_out = l:get('yo')
5assert(n == 1 and stdin_out == io.stdin, tostring(stdin_out) .. " ~= " .. tostring(io.stdin)) 5assert(n == 1 and stdin_out == io.stdin, tostring(stdin_out) .. " ~= " .. tostring(io.stdin))
diff --git a/unit_tests/scripts/linda/wake_period.lua b/unit_tests/scripts/linda/wake_period.lua
new file mode 100644
index 0000000..d2dccc3
--- /dev/null
+++ b/unit_tests/scripts/linda/wake_period.lua
@@ -0,0 +1,42 @@
1-- default wake period is 0.5 seconds
2local require_lanes_result_1, require_lanes_result_2 = require "lanes".configure{linda_wake_period = 0.5}
3local lanes = require_lanes_result_1
4
5-- a lane that performs a blocking operation for 2 seconds
6local body = function(linda_)
7 -- a blocking read that lasts longer than the tested wake_period values
8 linda_:receive(2, "empty_slot")
9 return "done"
10end
11
12-- if we don't cancel the lane, we should wait the whole duration
13local function check_wake_duration(linda_, expected_, do_cancel_)
14 local h = lanes.gen(body)(linda_)
15 -- wait until the linda is blocked
16 repeat until h.status == "waiting"
17 local t0 = lanes.now_secs()
18 -- soft cancel, no timeout, no waking
19 if do_cancel_ then
20 local result, reason = h:cancel('soft', 0, false)
21 -- should say there was a timeout, since the lane didn't actually cancel (normal since we did not wake it)
22 assert(result == false and reason == 'timeout', "unexpected cancel result")
23 end
24 -- this should wait until the linda wakes by itself before the actual receive timeout and sees the cancel request
25 local r, ret = h:join()
26 assert(r == true and ret == "done")
27 local t1 = lanes.now_secs()
28 local delta = t1 - t0
29 -- the linda should check for cancellation at about the expected period, not earlier
30 assert(delta >= expected_, tostring(linda_) .. " woke too early:" .. delta)
31 -- the lane shouldn't terminate too long after cancellation was processed
32 assert(delta <= expected_ * 1.1, tostring(linda_) .. " woke too late: " .. delta)
33end
34
35-- legacy behavior: linda waits until operation timeout
36check_wake_duration(lanes.linda{name = "A", wake_period = 'never'}, 2, true)
37-- early wake behavior: linda wakes after the expected time, sees a cancellation requests, and aborts the operation early
38check_wake_duration(lanes.linda{name = "B", wake_period = 0.25}, 0.25, true)
39check_wake_duration(lanes.linda{name = "C"}, 0.5, true) -- wake_period defaults to 0.5 (see above)
40check_wake_duration(lanes.linda{name = "D", wake_period = 1}, 1, true)
41-- even when there is a wake_period, the operation should reach full timeout if not cancelled early
42check_wake_duration(lanes.linda{name = "E", wake_period = 0.1}, 2, false)
diff --git a/unit_tests/scripts/misc/deeptest.lua b/unit_tests/scripts/misc/deeptest.lua
new file mode 100644
index 0000000..542c35b
--- /dev/null
+++ b/unit_tests/scripts/misc/deeptest.lua
@@ -0,0 +1,161 @@
1local fixture = require "fixture"
2local lanes = require("lanes").configure{on_state_create = fixture.on_state_create}
3local l = lanes.linda{name = "my linda"}
4
5local table_unpack = table.unpack or unpack -- Lua 5.1 support
6
7-- we will transfer userdata created by this module, so we need to make Lanes aware of it
8local dt = lanes.require "deep_userdata_example"
9
10-- set DEEP to any non-false value to run the Deep Userdata tests. "gc" selects a special test for debug purposes
11DEEP = DEEP or true
12-- set CLONABLE to any non-false value to run the Clonable Userdata tests
13CLONABLE = CLONABLE or true
14
15-- lua 5.1->5.2 support a single table uservalue
16-- lua 5.3->5.4 supports an arbitrary type uservalue
17local test_uvtype = (_VERSION == "Lua 5.4") and "function" or (_VERSION == "Lua 5.3") and "string" or "table"
18-- lua 5.4 supports multiple uservalues
19local nupvals = _VERSION == "Lua 5.4" and 3 or 1
20
21local makeUserValue = function( obj_)
22 if test_uvtype == "table" then
23 return {"some uservalue"}
24 elseif test_uvtype == "string" then
25 return "some uservalue"
26 elseif test_uvtype == "function" then
27 -- a function that pull the userdata as upvalue
28 local f = function()
29 return "-> '" .. tostring( obj_) .. "'"
30 end
31 return f
32 end
33end
34
35local printDeep = function( prefix_, obj_, t_)
36 print( prefix_, obj_)
37 for uvi = 1, nupvals do
38 local uservalue = obj_:getuv(uvi)
39 print ("uv #" .. uvi, type( uservalue), uservalue, type(uservalue) == "function" and uservalue() or "")
40 end
41 if t_ then
42 local count = 0
43 for k, v in ipairs( t_) do
44 print( "t["..tostring(k).."]", v)
45 count = count + 1
46 end
47 -- we should have only 2 indexed entries with the same value
48 assert(count == 2 and t_[1] == t_[2])
49 end
50 print()
51end
52
53local performTest = function( obj_)
54 -- setup the userdata with some value and a uservalue
55 obj_:set( 666)
56 obj_:setuv( 1, makeUserValue( obj_))
57 if nupvals > 1 then
58 -- keep uv #2 as nil
59 obj_:setuv( 3, "ENDUV")
60 end
61
62 local t =
63 {
64 -- two indices with an identical value: we should also have identical values on the other side (even if not the same as the original ones when they are clonables)
65 obj_,
66 obj_,
67 -- this one won't transfer because we don't support full uservalue as keys
68 [obj_] = "val"
69 }
70
71 -- read back the contents of the object
72 printDeep( "immediate:", obj_, t)
73
74 -- send the object in a linda, get it back out, read the contents
75 l:set( "key", obj_, t)
76 -- when obj_ is a deep userdata, out is the same userdata as obj_ (not another one pointing on the same deep memory block) because of an internal cache table [deep*] -> proxy)
77 -- when obj_ is a clonable userdata, we get a different clone everytime we cross a linda or lane barrier
78 local _n, _val1, _val2 = l:get( "key", 2)
79 assert(_n == (_val2 and 2 or 1))
80 printDeep( "out of linda:", _val1, _val2)
81
82 -- send the object in a lane through argument passing, the lane body returns it as return value, read the contents
83 local g = lanes.gen(
84 "package"
85 , {
86 name = 'auto',
87 required = { "deep_userdata_example"} -- we will transfer userdata created by this module, so we need to make this lane aware of it
88 }
89 , function( arg_, t_)
90 -- read contents inside lane: arg_ and t_ by argument
91 printDeep( "in lane, as arguments:", arg_, t_)
92 -- read contents inside lane: obj_ and t by upvalue
93 printDeep( "in lane, as upvalues:", obj_, t)
94 -- read contents inside lane: in linda
95 local _n, _val1, _val2 = l:get( "key", 2)
96 assert(_n == (_val2 and 2 or 1))
97 printDeep( "in lane, from linda:", _val1, _val2)
98 return arg_, t_
99 end
100 )
101 h = g( obj_, t)
102 -- when obj_ is a deep userdata, from_lane is the same userdata as obj_ (not another one pointing on the same deep memory block) because of an internal cache table [deep*] -> proxy)
103 -- when obj_ is a clonable userdata, we get a different clone everytime we cross a linda or lane barrier
104 printDeep( "from lane:", h[1], h[2])
105end
106
107if DEEP then
108 print "================================================================"
109 print "DEEP"
110 local d = dt.new_deep(nupvals)
111 if type(DEEP) == "string" then
112 local gc_tests = {
113 thrasher = function(repeat_, size_)
114 print "in thrasher"
115 -- result is a table of repeat_ tables, each containing size_ entries
116 local result = {}
117 for i = 1, repeat_ do
118 local batch_values = {}
119 for j = 1, size_ do
120 table.insert(batch_values, j)
121 end
122 table.insert(result, batch_values)
123 end
124 print "thrasher done"
125 return result
126 end,
127 stack_abuser = function(repeat_, size_)
128 print "in stack_abuser"
129 for i = 1, repeat_ do
130 local batch_values = {}
131 for j = 1, size_ do
132 table.insert(batch_values, j)
133 end
134 -- return size_ values
135 local _ = table_unpack(batch_values)
136 end
137 print "stack_abuser done"
138 return result
139 end
140 }
141 -- have the object call the function from inside one of its functions, to detect if it gets collected from there (while in use!)
142 local testf = gc_tests[DEEP]
143 if testf then
144 local r = d:invoke(gc_tests[DEEP], REPEAT or 10, SIZE or 10)
145 print("invoke -> ", tostring(r))
146 else
147 print("unknown test '" .. DEEP .. "'")
148 end
149 else
150 performTest(d)
151 end
152end
153
154if CLONABLE then
155 print "================================================================"
156 print "CLONABLE"
157 performTest( dt.new_clonable(nupvals))
158end
159
160print "================================================================"
161print "TEST OK" \ No newline at end of file
diff --git a/unit_tests/shared.cpp b/unit_tests/shared.cpp
index 2e2af73..9f3b08e 100644
--- a/unit_tests/shared.cpp
+++ b/unit_tests/shared.cpp
@@ -18,9 +18,9 @@ namespace
18 { 18 {
19 STACK_CHECK_START_REL(L_, 0); 19 STACK_CHECK_START_REL(L_, 0);
20 lua_getglobal(L_, "package"); // L_: package 20 lua_getglobal(L_, "package"); // L_: package
21 std::ignore = luaG_getfield(L_, kIdxTop, "preload"); // L_: package package.preload 21 std::ignore = luaW_getfield(L_, kIdxTop, "preload"); // L_: package package.preload
22 lua_pushcfunction(L_, openf_); // L_: package package.preload openf_ 22 lua_pushcfunction(L_, openf_); // L_: package package.preload openf_
23 luaG_setfield(L_, StackIndex{ -2 }, name_); // L_: package package.preload 23 luaW_setfield(L_, StackIndex{ -2 }, name_); // L_: package package.preload
24 lua_pop(L_, 2); 24 lua_pop(L_, 2);
25 STACK_CHECK(L_, 0); 25 STACK_CHECK(L_, 0);
26 } 26 }
@@ -32,7 +32,7 @@ namespace
32 lua_CFunction sFreezingFinalizer = +[](lua_State* const L_) { 32 lua_CFunction sFreezingFinalizer = +[](lua_State* const L_) {
33 std::lock_guard _guard{ sCallCountsLock }; 33 std::lock_guard _guard{ sCallCountsLock };
34 sFinalizerHits[L_].test_and_set(); 34 sFinalizerHits[L_].test_and_set();
35 luaG_pushstring(L_, "freeze"); // just freeze the thread in place so that it can be debugged 35 luaW_pushstring(L_, "freeze"); // just freeze the thread in place so that it can be debugged
36 return 1; 36 return 1;
37 }; 37 };
38 38
@@ -47,22 +47,22 @@ namespace
47 }; 47 };
48 48
49 lua_CFunction sNewUserData = +[](lua_State* const L_) { 49 lua_CFunction sNewUserData = +[](lua_State* const L_) {
50 std::ignore = luaG_newuserdatauv<int>(L_, UserValueCount{ 0 }); 50 std::ignore = luaW_newuserdatauv<int>(L_, UserValueCount{ 0 });
51 return 1; 51 return 1;
52 }; 52 };
53 53
54 // a function that enables any lane to require "fixture" 54 // a function that enables any lane to require "fixture" and "deep_userdata_example"
55 lua_CFunction sOnStateCreate = +[](lua_State* const L_) { 55 lua_CFunction sOnStateCreate = +[](lua_State* const L_) {
56 PreloadModule(L_, "fixture", luaopen_fixture); 56 PreloadModule(L_, "fixture", luaopen_fixture);
57 PreloadModule(L_, "deep_userdata_example", luaopen_deep_userdata_example); 57 PreloadModule(L_, "deep_userdata_example", luaopen_deep_userdata_example);
58 return 0; 58 return 0;
59 }; 59 };
60 60
61 // a function that sleeps for the specified duration (in seconds) 61 // a function that blocks for the specified duration (in seconds) by putting the current thread to sleep
62 lua_CFunction sSleepFor = +[](lua_State* const L_) { 62 lua_CFunction sBlockFor = +[](lua_State* const L_) {
63 std::chrono::time_point<std::chrono::steady_clock> _until{ std::chrono::time_point<std::chrono::steady_clock>::max() }; 63 std::chrono::time_point<std::chrono::steady_clock> _until{ std::chrono::time_point<std::chrono::steady_clock>::max() };
64 lua_settop(L_, 1); 64 lua_settop(L_, 1);
65 if (luaG_type(L_, kIdxTop) == LuaType::NUMBER) { // we don't want to use lua_isnumber() because of autocoercion 65 if (luaW_type(L_, kIdxTop) == LuaType::NUMBER) { // we don't want to use lua_isnumber() because of autocoercion
66 lua_Duration const _duration{ lua_tonumber(L_, kIdxTop) }; 66 lua_Duration const _duration{ lua_tonumber(L_, kIdxTop) };
67 if (_duration.count() >= 0.0) { 67 if (_duration.count() >= 0.0) {
68 _until = std::chrono::steady_clock::now() + std::chrono::duration_cast<std::chrono::steady_clock::duration>(_duration); 68 _until = std::chrono::steady_clock::now() + std::chrono::duration_cast<std::chrono::steady_clock::duration>(_duration);
@@ -82,17 +82,17 @@ namespace
82 std::lock_guard _guard{ sCallCountsLock }; 82 std::lock_guard _guard{ sCallCountsLock };
83 sFinalizerHits[L_].test_and_set(); 83 sFinalizerHits[L_].test_and_set();
84 bool const _allLanesTerminated = lua_toboolean(L_, kIdxTop); 84 bool const _allLanesTerminated = lua_toboolean(L_, kIdxTop);
85 luaG_pushstring(L_, "Finalizer%s", _allLanesTerminated ? "" : ": Uncooperative lanes detected"); 85 luaW_pushstring(L_, "Finalizer%s", _allLanesTerminated ? "" : ": Uncooperative lanes detected");
86 return 1; 86 return 1;
87 }; 87 };
88 88
89 static luaL_Reg const sFixture[] = { 89 static luaL_Reg const sFixture[] = {
90 { "freezing_finalizer", sFreezingFinalizer }, 90 { "freezing_finalizer", sFreezingFinalizer },
91 { "give_me_back()", sGiveMeBack }, 91 { "give_me_back", sGiveMeBack },
92 { "newlightuserdata", sNewLightUserData }, 92 { "newlightuserdata", sNewLightUserData },
93 { "newuserdata", sNewUserData }, 93 { "newuserdata", sNewUserData },
94 { "on_state_create", sOnStateCreate }, 94 { "on_state_create", sOnStateCreate },
95 { "sleep_for", sSleepFor }, 95 { "block_for", sBlockFor },
96 { "throwing_finalizer", sThrowingFinalizer }, 96 { "throwing_finalizer", sThrowingFinalizer },
97 { nullptr, nullptr } 97 { nullptr, nullptr }
98 }; 98 };
@@ -103,7 +103,7 @@ namespace
103 int luaopen_fixture(lua_State* L_) 103 int luaopen_fixture(lua_State* L_)
104 { 104 {
105 STACK_CHECK_START_REL(L_, 0); 105 STACK_CHECK_START_REL(L_, 0);
106 luaG_newlib<std::size(local::sFixture)>(L_, local::sFixture); // M 106 luaW_newlib<std::size(local::sFixture)>(L_, local::sFixture); // M
107 STACK_CHECK(L_, 1); 107 STACK_CHECK(L_, 1);
108 return 1; 108 return 1;
109 } 109 }
@@ -246,7 +246,7 @@ LuaError LuaState::doString(std::string_view const& str_) const
246 return _loadErr; 246 return _loadErr;
247 } 247 }
248 LuaError const _callErr{ lua_pcall(L, 0, 1, 0) }; // L: "<msg>"? 248 LuaError const _callErr{ lua_pcall(L, 0, 1, 0) }; // L: "<msg>"?
249 [[maybe_unused]] std::string_view const _out{ luaG_tostring(L, kIdxTop) }; 249 [[maybe_unused]] std::string_view const _out{ luaW_tostring(L, kIdxTop) };
250 STACK_CHECK(L, 1); 250 STACK_CHECK(L, 1);
251 return _callErr; 251 return _callErr;
252} 252}
@@ -257,8 +257,8 @@ std::string_view LuaState::doStringAndRet(std::string_view const& str_) const
257{ 257{
258 lua_settop(L, 0); 258 lua_settop(L, 0);
259 if (str_.empty()) { 259 if (str_.empty()) {
260 luaG_pushstring(L, ""); 260 luaW_pushstring(L, "");
261 return luaG_tostring(L, kIdxTop); 261 return luaW_tostring(L, kIdxTop);
262 } 262 }
263 STACK_CHECK_START_REL(L, 0); 263 STACK_CHECK_START_REL(L, 0);
264 LuaError const _loadErr{ luaL_loadstring(L, str_.data()) }; // L: chunk() 264 LuaError const _loadErr{ luaL_loadstring(L, str_.data()) }; // L: chunk()
@@ -268,7 +268,7 @@ std::string_view LuaState::doStringAndRet(std::string_view const& str_) const
268 } 268 }
269 [[maybe_unused]] LuaError const _callErr{ lua_pcall(L, 0, 1, 0) }; // L: "<msg>"?|retstring 269 [[maybe_unused]] LuaError const _callErr{ lua_pcall(L, 0, 1, 0) }; // L: "<msg>"?|retstring
270 STACK_CHECK(L, 1); 270 STACK_CHECK(L, 1);
271 return luaG_tostring(L, kIdxTop); 271 return luaW_tostring(L, kIdxTop);
272} 272}
273 273
274// ################################################################################################# 274// #################################################################################################
@@ -336,7 +336,7 @@ void LuaState::requireFailure(std::string_view const& script_)
336{ 336{
337 auto const _result{ doString(script_) }; 337 auto const _result{ doString(script_) };
338 if (_result == LuaError::OK) { 338 if (_result == LuaError::OK) {
339 WARN(luaG_tostring(L, kIdxTop)); 339 WARN(luaW_tostring(L, kIdxTop));
340 } 340 }
341 REQUIRE(_result != LuaError::OK); 341 REQUIRE(_result != LuaError::OK);
342 lua_settop(L, 0); 342 lua_settop(L, 0);
@@ -372,7 +372,7 @@ void LuaState::requireSuccess(std::string_view const& script_)
372{ 372{
373 auto const _result{ doString(script_) }; 373 auto const _result{ doString(script_) };
374 if (_result != LuaError::OK) { 374 if (_result != LuaError::OK) {
375 WARN(luaG_tostring(L, kIdxTop)); 375 WARN(luaW_tostring(L, kIdxTop));
376 } 376 }
377 REQUIRE(_result == LuaError::OK); 377 REQUIRE(_result == LuaError::OK);
378 lua_settop(L, 0); 378 lua_settop(L, 0);
@@ -384,7 +384,7 @@ void LuaState::requireSuccess(std::filesystem::path const& root_, std::string_vi
384{ 384{
385 auto const _result{ doFile(root_, path_) }; 385 auto const _result{ doFile(root_, path_) };
386 if (_result != LuaError::OK) { 386 if (_result != LuaError::OK) {
387 WARN(luaG_tostring(L, kIdxTop)); 387 WARN(luaW_tostring(L, kIdxTop));
388 } 388 }
389 REQUIRE(_result == LuaError::OK); 389 REQUIRE(_result == LuaError::OK);
390 lua_settop(L, 0); 390 lua_settop(L, 0);
@@ -407,20 +407,20 @@ TEST_CASE("LuaState.doString")
407{ 407{
408 LuaState _L{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } }; 408 LuaState _L{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } };
409 // if the script fails to load, we should find the error message at the top of the stack 409 // if the script fails to load, we should find the error message at the top of the stack
410 REQUIRE([&L = _L]() { std::ignore = L.doString("function end"); return lua_gettop(L) == 1 && luaG_type(L, StackIndex{1}) == LuaType::STRING; }()); 410 REQUIRE([&L = _L]() { std::ignore = L.doString("function end"); return lua_gettop(L) == 1 && luaW_type(L, StackIndex{1}) == LuaType::STRING; }());
411 411
412 // if the script runs, the stack should contain its return value 412 // if the script runs, the stack should contain its return value
413 REQUIRE([&L = _L]() { std::ignore = L.doString("return true"); return lua_gettop(L) == 1 && luaG_type(L, StackIndex{1}) == LuaType::BOOLEAN; }()); 413 REQUIRE([&L = _L]() { std::ignore = L.doString("return true"); return lua_gettop(L) == 1 && luaW_type(L, StackIndex{1}) == LuaType::BOOLEAN; }());
414 REQUIRE([&L = _L]() { std::ignore = L.doString("return 'hello'"); return lua_gettop(L) == 1 && luaG_tostring(L, StackIndex{1}) == "hello"; }()); 414 REQUIRE([&L = _L]() { std::ignore = L.doString("return 'hello'"); return lua_gettop(L) == 1 && luaW_tostring(L, StackIndex{1}) == "hello"; }());
415 // or nil if it didn't return anything 415 // or nil if it didn't return anything
416 REQUIRE([&L = _L]() { std::ignore = L.doString("return"); return lua_gettop(L) == 1 && luaG_type(L, StackIndex{1}) == LuaType::NIL; }()); 416 REQUIRE([&L = _L]() { std::ignore = L.doString("return"); return lua_gettop(L) == 1 && luaW_type(L, StackIndex{1}) == LuaType::NIL; }());
417 417
418 // on failure, doStringAndRet returns "", and the error message is on the stack 418 // on failure, doStringAndRet returns "", and the error message is on the stack
419 REQUIRE([&L = _L]() { return L.doStringAndRet("function end") == "" && lua_gettop(L) == 1 && luaG_type(L, StackIndex{ 1 }) == LuaType::STRING && luaG_tostring(L, StackIndex{ 1 }) != ""; }()); 419 REQUIRE([&L = _L]() { return L.doStringAndRet("function end") == "" && lua_gettop(L) == 1 && luaW_type(L, StackIndex{ 1 }) == LuaType::STRING && luaW_tostring(L, StackIndex{ 1 }) != ""; }());
420 // on success doStringAndRet returns the string returned by the script, that is also at the top of the stack 420 // on success doStringAndRet returns the string returned by the script, that is also at the top of the stack
421 REQUIRE([&L = _L]() { return L.doStringAndRet("return 'hello'") == "hello" && lua_gettop(L) == 1 && luaG_type(L, StackIndex{ 1 }) == LuaType::STRING && luaG_tostring(L, StackIndex{ 1 }) == "hello"; }()); 421 REQUIRE([&L = _L]() { return L.doStringAndRet("return 'hello'") == "hello" && lua_gettop(L) == 1 && luaW_type(L, StackIndex{ 1 }) == LuaType::STRING && luaW_tostring(L, StackIndex{ 1 }) == "hello"; }());
422 // if the returned value is not (convertible to) a string, we should get an empty string out of doStringAndRet 422 // if the returned value is not (convertible to) a string, we should get an empty string out of doStringAndRet
423 REQUIRE([&L = _L]() { return L.doStringAndRet("return function() end") == "" && lua_gettop(L) == 1 && luaG_type(L, StackIndex{ 1 }) == LuaType::FUNCTION && luaG_tostring(L, StackIndex{ 1 }) == ""; }()); 423 REQUIRE([&L = _L]() { return L.doStringAndRet("return function() end") == "" && lua_gettop(L) == 1 && luaW_type(L, StackIndex{ 1 }) == LuaType::FUNCTION && luaW_tostring(L, StackIndex{ 1 }) == ""; }());
424} 424}
425 425
426// ################################################################################################# 426// #################################################################################################
@@ -436,9 +436,9 @@ FileRunner::FileRunner(std::string_view const& where_)
436 // because the VS Test Explorer doesn't appreciate the text output of some scripts, so absorb them 436 // because the VS Test Explorer doesn't appreciate the text output of some scripts, so absorb them
437 if constexpr (1) { 437 if constexpr (1) {
438 auto const _nullprint = +[](lua_State* const L_) { return 0; }; 438 auto const _nullprint = +[](lua_State* const L_) { return 0; };
439 luaG_pushglobaltable(L); 439 luaW_pushglobaltable(L);
440 lua_pushcfunction(L, _nullprint); 440 lua_pushcfunction(L, _nullprint);
441 luaG_setfield(L, StackIndex{ -2 }, std::string_view{ "print" }); 441 luaW_setfield(L, StackIndex{ -2 }, std::string_view{ "print" });
442 lua_pop(L, 1); 442 lua_pop(L, 1);
443 stackCheck(0); 443 stackCheck(0);
444 } 444 }
@@ -476,6 +476,7 @@ void FileRunner::performTest(FileRunnerParam const& testParam_)
476 INFO(testParam_.script); 476 INFO(testParam_.script);
477 switch (testParam_.test) { 477 switch (testParam_.test) {
478 case TestType::AssertNoLuaError: 478 case TestType::AssertNoLuaError:
479 lua_atpanic(L, _atPanic);
479 requireSuccess(root, testParam_.script); 480 requireSuccess(root, testParam_.script);
480 break; 481 break;
481 482
diff --git a/unit_tests/shared.h b/unit_tests/shared.h
index b884df0..c6c3339 100644
--- a/unit_tests/shared.h
+++ b/unit_tests/shared.h
@@ -56,7 +56,7 @@ class LuaState
56 56
57 friend std::ostream& operator<<(std::ostream& os_, LuaState const& s_) 57 friend std::ostream& operator<<(std::ostream& os_, LuaState const& s_)
58 { 58 {
59 os_ << luaG_tostring(s_.L, kIdxTop); 59 os_ << luaW_tostring(s_.L, kIdxTop);
60 return os_; 60 return os_;
61 } 61 }
62}; 62};