public Task eval_epoch_with_common_and_custom_handlers(string expression, string expected)
        {
            var myFormat = "yyyy/MM/dd HH:mm:ss";
            var eval     = new SubstitutionEvaluator <DateTime>()
                           .AddCommonHandlers()
                           .AddHandler("DATETIME_KINDS", (d, _) =>
                                       string.Join(",", Enum.GetNames(typeof(DateTimeKind)).OrderBy(k => k)))
                           .AddHandler("THE_YEAR", (d, _) => d.Year.ToString())
                           .AddHandler("THE_MONTH", (d, _) => d.Month.ToString())
                           .AddHandler("THE_DAY", (d, _) => d.Day.ToString())
                           .AddHandler("THE_DOW", (d, _) => d.ToString("ddd"))
                           .AddHandler("THE_DAYOFWEEK", (d, _) => d.ToString("dddd"))
                           .AddHandlers(new Dictionary <string, Func <DateTime, string, string> >
            {
                ["MY_FORMAT"] = (d, _) => d.ToString(myFormat),
                ["TOSTRING"]  = (d, fmt) => d.ToString(fmt),
                ["ADD"]       = (d, tspan) => d.Add(TimeSpan.Parse(tspan)).ToString(myFormat),
                ["ADD_SECS"]  = (d, secs) => d.AddSeconds(int.Parse(secs)).ToString(myFormat),
                ["ADD_MINS"]  = (d, mins) => d.AddMinutes(int.Parse(mins)).ToString(myFormat),
            });
            var proc = Process.GetCurrentProcess();

            Assert.Equal(expected, eval.Evaluate(expression, DateTime.UnixEpoch));
            return(Task.CompletedTask);
        }
        public Task eval_escape_forms(string expression, string expected)
        {
            var eval = new SubstitutionEvaluator <object>()
                       .AddCommonHandlers();

            Assert.Equal(expected, eval.Evaluate(expression, null));
            return(Task.CompletedTask);
        }
        public Task eval_with_only_common_handlers(string expression, string expected)
        {
            System.Environment.SetEnvironmentVariable(TestEnvVarName, TestEnvVarValue,
                                                      EnvironmentVariableTarget.Process);

            var eval = new SubstitutionEvaluator <Process>()
                       .AddCommonHandlers();
            var proc = Process.GetCurrentProcess();

            Assert.Equal(expected, eval.Evaluate(expression, proc));
            return(Task.CompletedTask);
        }
        // ** These don't work because we can't get StartInfo for a process we didn't start :-( **
        // [InlineData("%START_VERB%", "dotnet")]
        // [InlineData("%START_VERBS%", "dotnet")]
        // [InlineData("%START_ENV%", "")]
        // [InlineData("%START_ENV:%", "")]
        // [InlineData("%START_ENV:%", "")]
        // [InlineData("%START_ENV:NoSuchEnvVar%", "")]
        // [InlineData("%START_ENV:" + TestEnvVarName + "%", TestEnvVarValue)]
        public Task eval_proc_with_common_and_custom_handlers(string expression, string expected)
        {
            System.Environment.SetEnvironmentVariable(TestEnvVarName, TestEnvVarValue,
                                                      EnvironmentVariableTarget.Process);

            var eval = new SubstitutionEvaluator <Process>()
                       .AddCommonHandlers()
                       .AddHandler("PROC_NAME", (p, _) => p.ProcessName)
                       .AddHandler("START_TIME", (p, _) => p.StartTime.ToString())
                       .AddHandlers(new Dictionary <string, Func <Process, string, string> >
            {
                ["PROC_EXITED"] = (p, _) => p.HasExited.ToString(),
                ["PROC_HOST"]   = (p, _) => p.MachineName,
                ["START_USER"]  = (p, _) => p.StartInfo.UserName,
                ["START_VERB"]  = (p, _) => p.StartInfo.Verb,
                ["START_VERBS"] = (p, _) => string.Join(",", p.StartInfo.Verbs),
                ["START_ENV"]   = (p, a) => p.StartInfo.EnvironmentVariables[a],
            });
            var proc = Process.GetCurrentProcess();

            Assert.Equal(expected, eval.Evaluate(expression, proc));
            return(Task.CompletedTask);
        }