@@ -59,7 +59,7 @@ type UpToDate() =
5959 File.AppendAllText( embedPath, " some embedded resource" )
6060
6161 Assert.IsFalse( config.IsUpToDate( logger, true ))
62- project.Build( configNameDebug, output, " Build" ) |> ignore
62+ project.Build( configNameDebug, output, " Build" ) |> AssertBuildSuccessful
6363 Assert.IsTrue( config.IsUpToDate( logger, true ))
6464
6565// None items should not affect up-to-date (unless captured by well-known items, e.g. App.config)
@@ -111,7 +111,7 @@ type UpToDate() =
111111
112112 project.SetConfiguration( config.ConfigCanonicalName);
113113 Assert.IsFalse( config.IsUpToDate( logger, true ))
114- project.Build( configNameDebug, output, " Build" ) |> ignore
114+ project.Build( configNameDebug, output, " Build" ) |> AssertBuildSuccessful
115115 Assert.IsTrue( config.IsUpToDate( logger, true ))
116116
117117for pathin [ verPath; keyPath] do
@@ -146,7 +146,7 @@ type UpToDate() =
146146 File.AppendAllText( absFilePath, " printfn\" hello\" " )
147147
148148 Assert.IsFalse( config.IsUpToDate( logger, true ))
149- project.Build( configNameDebug, output, " Build" ) |> ignore
149+ project.Build( configNameDebug, output, " Build" ) |> AssertBuildSuccessful
150150 Assert.IsTrue( config.IsUpToDate( logger, true ))
151151
152152// touch proj file
@@ -177,7 +177,7 @@ type UpToDate() =
177177let config1 = project1.ConfigProvider.GetProjectConfiguration( configNameDebug)
178178
179179 Assert.IsFalse( config1.IsUpToDate( logger, true ))
180- project1.Build( configNameDebug, output, " Build" ) |> ignore
180+ project1.Build( configNameDebug, output, " Build" ) |> AssertBuildSuccessful
181181 Assert.IsTrue( config1.IsUpToDate( logger, true ))
182182
183183let output1 = Path.Combine( project1.ProjectFolder, " bin\\ debug" , project1.OutputFileName)
@@ -196,7 +196,7 @@ type UpToDate() =
196196let startTime = DateTime.Now
197197
198198 Assert.IsFalse( config2.IsUpToDate( logger, true ))
199- project2.Build( configNameDebug, output, " Build" ) |> ignore
199+ project2.Build( configNameDebug, output, " Build" ) |> AssertBuildSuccessful
200200 Assert.IsTrue( config2.IsUpToDate( logger, true ))
201201
202202// reference is updated
@@ -214,6 +214,9 @@ type UpToDate() =
214214[<Test>]
215215member public this.OutputFiles () =
216216 this.MakeProjectAndDo([ " file1.fs" ], [], @"
217+ <ItemGroup>
218+ <None Include="" App.config"" />
219+ </ItemGroup>
217220 <PropertyGroup>
218221 <DocumentationFile>bin\Debug\Test.XML</DocumentationFile>
219222 <DebugSymbols>true</DebugSymbols>
@@ -224,22 +227,25 @@ type UpToDate() =
224227let output = VsMocks.vsOutputWindowPane( ref[])
225228let logger = OutputWindowLogger.CreateUpToDateCheckLogger( output)
226229let sourcePath = Path.Combine( project.ProjectFolder, " file1.fs" )
230+ let appConfigPath = Path.Combine( project.ProjectFolder, " App.config" )
227231
228232let exeObjPath = Path.Combine( project.ProjectFolder, " obj\\ x86\\ debug" , project.OutputFileName)
229233let exeBinpath = Path.Combine( project.ProjectFolder, " bin\\ debug\\ " , project.OutputFileName)
230234let pdbObjPath = Regex.Replace( exeObjPath, " exe$" , " pdb" )
231235let pdbBinPath = Regex.Replace( exeBinpath, " exe$" , " pdb" )
232236let xmlDocPath = Regex.Replace( exeBinpath, " exe$" , " xml" )
237+ let exeConfigPath = Regex.Replace( exeBinpath, " exe$" , " exe.config" )
233238
234239 File.AppendAllText( sourcePath, " printfn\" hello\" " )
240+ File.AppendAllText( appConfigPath, """ <?xml version="1.0" encoding="utf-8" ?><configuration></configuration>""" )
235241
236242 Assert.IsFalse( config.IsUpToDate( logger, true ))
237- project.Build( configNameDebug, output, " Build" ) |> ignore
243+ project.Build( configNameDebug, output, " Build" ) |> AssertBuildSuccessful
238244 Assert.IsTrue( config.IsUpToDate( logger, true ))
239245
240246let startTime = DateTime.Now
241247
242- for pathin [ exeObjPath; exeBinpath; pdbObjPath; pdbBinPath; xmlDocPath] do
248+ for pathin [ exeObjPath; exeBinpath; pdbObjPath; pdbBinPath; xmlDocPath; exeConfigPath ] do
243249 printfn" Testing output%s " path
244250
245251// touch file
@@ -283,25 +289,25 @@ type UpToDate() =
283289 Assert.IsFalse( debugConfigAnyCPU.IsUpToDate( logger, true ))
284290 Assert.IsFalse( releaseConfigAnyCPU.IsUpToDate( logger, true ))
285291
286- project.Build( configNameDebugx86, output, " Build" ) |> ignore
292+ project.Build( configNameDebugx86, output, " Build" ) |> AssertBuildSuccessful
287293 Assert.IsTrue( debugConfigx86.IsUpToDate( logger, true ))
288294 Assert.IsFalse( releaseConfigx86.IsUpToDate( logger, true ))
289295 Assert.IsFalse( debugConfigAnyCPU.IsUpToDate( logger, true ))
290296 Assert.IsFalse( releaseConfigAnyCPU.IsUpToDate( logger, true ))
291297
292- project.Build( configNameReleasex86, output, " Build" ) |> ignore
298+ project.Build( configNameReleasex86, output, " Build" ) |> AssertBuildSuccessful
293299 Assert.IsTrue( debugConfigx86.IsUpToDate( logger, true ))
294300 Assert.IsTrue( releaseConfigx86.IsUpToDate( logger, true ))
295301 Assert.IsFalse( debugConfigAnyCPU.IsUpToDate( logger, true ))
296302 Assert.IsFalse( releaseConfigAnyCPU.IsUpToDate( logger, true ))
297303
298- project.Build( configNameDebugAnyCPU, output, " Build" ) |> ignore
304+ project.Build( configNameDebugAnyCPU, output, " Build" ) |> AssertBuildSuccessful
299305 Assert.IsTrue( debugConfigx86.IsUpToDate( logger, true ))
300306 Assert.IsTrue( releaseConfigx86.IsUpToDate( logger, true ))
301307 Assert.IsTrue( debugConfigAnyCPU.IsUpToDate( logger, true ))
302308 Assert.IsFalse( releaseConfigAnyCPU.IsUpToDate( logger, true ))
303309
304- project.Build( configNameReleaseAnyCPU, output, " Build" ) |> ignore
310+ project.Build( configNameReleaseAnyCPU, output, " Build" ) |> AssertBuildSuccessful
305311 Assert.IsTrue( debugConfigx86.IsUpToDate( logger, true ))
306312 Assert.IsTrue( releaseConfigx86.IsUpToDate( logger, true ))
307313 Assert.IsTrue( debugConfigAnyCPU.IsUpToDate( logger, true ))
@@ -320,3 +326,55 @@ type UpToDate() =
320326
321327 Assert.IsFalse( config.IsFastUpToDateCheckEnabled())
322328))
329+
330+ [<TestFixture>]
331+ type ``UpToDate PreserveNewest`` () =
332+
333+ [<Test>]
334+ member public this.IsUpToDatePreserveNewest () =
335+
336+ let test ( input , inputTimestamp ) ( output , outputTimestamp ) =
337+ let logs = ref[]
338+ let outputPanel = VsMocks.vsOutputWindowPane( logs)
339+ let logger = OutputWindowLogger.CreateUpToDateCheckLogger( outputPanel)
340+
341+ let tryTimestamp ( path : string ) ( _l : OutputWindowLogger ) =
342+ let toN = function Some d-> Nullable<_>( d) | None-> Nullable<_>()
343+ match pathwith
344+ | xwhen x= input-> toN inputTimestamp
345+ | xwhen x= output-> toN outputTimestamp
346+ | _ -> failwithf" unexpected%s " path
347+
348+ let u = ProjectConfig.IsUpToDatePreserveNewest( logger, ( Func<_,_,_>( tryTimestamp)), input, output)
349+ u, ! logs
350+
351+ let now = System.DateTime.Now
352+ let before = now.AddHours(- 1.0 )
353+
354+ let ``no input -> not up - to - date and log`` =
355+ let u , logs = test( " readme.md" , None) ( " leggimi.md" , None)
356+ Assert.IsFalse( u)
357+ logs
358+ |> List.exists( fun s -> s.Contains( " readme.md" ) && s.Contains( " can't find expected input" ))
359+ |> Assert.IsTrue
360+
361+ let ``no output -> not up - to - date and log`` =
362+ let u , logs = test( " from.txt" , Some now) ( " to.txt" , None)
363+ Assert.IsFalse( u)
364+ logs
365+ |> List.exists( fun s -> s.Contains( " to.txt" ) && s.Contains( " can't find expected output" ))
366+ |> Assert.IsTrue
367+
368+ let ``a newer version of output file is ok`` =
369+ let u , logs = test( " before.doc" , Some before) ( " after.doc" , Some now)
370+ Assert.True( u)
371+ logs|> AssertEqual[]
372+
373+ let ``stale output file -> not up - to - date and log`` =
374+ let u , logs = test( " logo.png" , Some now) ( " animatedlogo.gif" , Some before)
375+ Assert.IsFalse( u)
376+ logs
377+ |> List.exists( fun s -> s.Contains( " animatedlogo.gif" ) && s.Contains( " stale" ))
378+ |> Assert.IsTrue
379+
380+ ()