Beispiel #1
0
    public void NoCommand()
    {
      var ctx = new Mod.Context();
      var handler = new Mod.CommandHandler(ctx, new TextOutputFormatter());
      var result = handler.Execute("");

      Assert.That(result.Status, Is.EqualTo(CommandStatus.Success));
      Assert.That(result.Message, Is.Empty);
    }
Beispiel #2
0
    public void CommandSingleNumberedParameter()
    {
      var ctx = new Mod.Context();
      ctx.CurrentItem = _testContent;
      var handler = new Mod.CommandHandler(ctx, new TextOutputFormatter());
      var result = handler.Execute("cd luna");

      Assert.That(result.Status, Is.EqualTo(CommandStatus.Success));
      Assert.That(ctx.CurrentItem.ID, Is.EqualTo(_testContent.Axes.GetChild("Luna").ID));
    }
Beispiel #3
0
    /// <summary>
    /// Evaluates an expression which may contain joining conditions (and, or)
    /// </summary>
    /// <param name="context">The current Revolver context</param>
    /// <param name="exp">The expression to evaluate</param>
    /// <returns>The outcome of th expression</returns>
    public static bool EvaluateExpression(Context context, string exp)
    {
      // Break the expression around the joining condition keywords			
      bool res = false;
      string[] expElms = exp.Trim().Replace("  ", " ").Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
      int startInd = 0;
      string op = string.Empty;

      for (int i = 0; i < expElms.Length; i++)
      {
        if (expElms[i] == "and" || expElms[i] == "or" || i == expElms.Length - 1)
        {
          string[] currentPart;

          if (i == expElms.Length - 1)
          {
            currentPart = new string[(i + 1) - startInd];
            Array.Copy(expElms, startInd, currentPart, 0, (i + 1) - startInd);
          }
          else
          {
            currentPart = new string[i - startInd];
            Array.Copy(expElms, startInd, currentPart, 0, i - startInd);
          }

          bool currentRes = EvaluateSingleExpression(context, string.Join(" ", currentPart));
          if (op.Length > 0)
          {
            switch (op)
            {
              case "and":
                res &= currentRes;
                break;

              case "or":
                res |= currentRes;
                break;

              default:
                throw new ExpressionException("Invalid operator: " + op);
            }
          }
          else
            res = currentRes;

          if (expElms.Length > i + 1)
            op = expElms[i];

          if (expElms.Length > i + 2)
            startInd = i + 1;
        }
      }

      return res;
    }
Beispiel #4
0
 /// <summary>
 /// Create a new instance of the ContextSwitcher
 /// </summary>
 /// <param name="context">The context to switch. ContextSwitcher stores the initial context.</param>
 /// <param name="path">The path to switc to</param>
 public ContextSwitcher(Context context, string path)
 {
   if (!string.IsNullOrEmpty(path))
   {
     _active = true;
     StoreContext(context);
     _result = context.SetContext(path);
   }
   else
     _result = new CommandResult(CommandStatus.Success, "ContextSwitcher not active");
 }
Beispiel #5
0
    public void CommandMultipleNumberedParameters()
    {
      var ctx = new Mod.Context();
      ctx.CurrentItem = _testContent;
      var handler = new Mod.CommandHandler(ctx, new TextOutputFormatter());
      var result = handler.Execute("find pwd luna");

      Assert.That(result.Status, Is.EqualTo(CommandStatus.Success));
      Assert.That(result.Message, Contains.Substring("Carme"));
      Assert.That(result.Message, Contains.Substring("Ganymede"));
      Assert.That(result.Message, Contains.Substring("Metis"));
    }
Beispiel #6
0
    public void SetContext_Relative()
    {
      var context = new Revolver.Core.Context();
      context.CurrentItem = _testTreeRoot;

      var result = context.SetContext("Sycorax");

      Assert.That(result.Status, Is.EqualTo(CommandStatus.Success));
      Assert.That(context.CurrentDatabase.Name, Is.EqualTo("web"));
      Assert.That(context.CurrentItem.ID, Is.EqualTo(_testTreeRoot.Axes.GetChild("Sycorax").ID));
      Assert.That(context.CurrentLanguage.Name, Is.EqualTo("en"));
    }
Beispiel #7
0
    public void CommandSingleNamedParameter()
    {
      var ctx = new Mod.Context();
      ctx.CurrentItem = _testContent;
      var handler = new Mod.CommandHandler(ctx, new TextOutputFormatter());
      var result = handler.Execute("ls -r os");

      Assert.That(result.Status, Is.EqualTo(CommandStatus.Success));
      Assert.That(result.Message, Is.Not.Contains("Luna"));
      Assert.That(result.Message, Contains.Substring("Deimos"));
      Assert.That(result.Message, Contains.Substring("phobos"));
      Assert.That(result.Message, Contains.Substring("Adrastea Phobos"));
    }
Beispiel #8
0
    /// <summary>
    /// Evaluates the tokens in a prompt string
    /// </summary>
    /// <param name="context">The context to use during evaluation</param>
    /// <param name="prompt">The prompt to evaluate</param>
    /// <returns>The prompt</returns>
    public static string EvaluatePrompt(Context context, string prompt)
    {
      string toRet = prompt;

      if (context.CurrentItem != null)
      {
        // Path / DB tokens
        toRet = toRet.Replace("%path%", context.CurrentItem.Paths.FullPath);
        toRet = toRet.Replace("%itemname%", context.CurrentItem.Name);
        toRet = toRet.Replace("%ver%", context.CurrentItem.Version.Number.ToString());
      }
      else
      {
        toRet = toRet.Replace("%path%", "<undefined>");
        toRet = toRet.Replace("%itemname%", "<undefined>");
        toRet = toRet.Replace("%ver%", "<undefined>");
      }

      if (context.CurrentDatabase != null)
        toRet = toRet.Replace("%db%", context.CurrentDatabase.Name);
      else
        toRet = toRet.Replace("%db%", "<undefined>");

      if (context.CurrentLanguage != null)
      {
        toRet = toRet.Replace("%lang%", context.CurrentLanguage.Title);
        toRet = toRet.Replace("%langcode%", context.CurrentLanguage.Name);
      }
      else
      {
        toRet = toRet.Replace("%lang%", "<undefined>");
        toRet = toRet.Replace("%langcode%", "<undefined>");
      }

      // DateTime tokens
      DateTime dt = DateTime.Now;
      toRet = toRet.Replace("%date%", dt.ToShortDateString());
      toRet = toRet.Replace("%time%", dt.ToShortTimeString());

      // Environment variables
      toRet = Parser.PerformSubstitution(context, toRet);

      return toRet;
    }
Beispiel #9
0
    /// <summary>
    /// Evaulate the path string in relation to the current item
    /// </summary>
    /// <param name="context">The Revolver context to evaluate the path against</param>
    /// <param name="path">The path to evaulate. Can either be absolute or relative</param>
    /// <returns>The full sitecore path to the target item</returns>
    public static string EvaluatePath(Context context, string path)
    {
      if (ID.IsID(path))
        return path;

      string workingPath = string.Empty;
      if (!path.StartsWith("/"))
        workingPath = context.CurrentItem.Paths.FullPath + "/" + path;
      else
        workingPath = path;

      // Strip any language and version tags
      if (workingPath.IndexOf(':') >= 0)
        workingPath = workingPath.Substring(0, workingPath.IndexOf(':'));

      // Make relative paths absolute
      string[] parts = workingPath.Split('/');
      StringCollection targetParts = new StringCollection();
      targetParts.AddRange(parts);

      while (targetParts.Contains(".."))
      {
        int ind = targetParts.IndexOf("..");
        targetParts.RemoveAt(ind);
        if (ind > 0)
        {
          targetParts.RemoveAt(ind - 1);
        }
      }

      if (targetParts[targetParts.Count - 1] == ".")
        targetParts.RemoveAt(targetParts.Count - 1);

      // Remove empty elements
      while (targetParts.Contains(""))
      {
        targetParts.RemoveAt(targetParts.IndexOf(""));
      }

      string[] toRet = new string[targetParts.Count];
      targetParts.CopyTo(toRet, 0);
      return "/" + string.Join("/", toRet);
    }
Beispiel #10
0
    public void MultipleSubCommands()
    {
      var ctx = new Mod.Context();
      ctx.CurrentItem = _testContent;
      var handler = new Mod.CommandHandler(ctx, new TextOutputFormatter());
      var result = handler.Execute("replace < (ga -a name) B < (echo c) -c");

      Assert.That(result.Status, Is.EqualTo(CommandStatus.Success));
      Assert.That(result.Message, Is.EqualTo("cebhionn"));
    }
Beispiel #11
0
    public void CommandChaining()
    {
      var ctx = new Mod.Context();
      ctx.CurrentItem = _testContent;
      var handler = new Mod.CommandHandler(ctx, new TextOutputFormatter());
      var result = handler.Execute("ga -a name > replace $~$ B c -c");

      Assert.That(result.Status, Is.EqualTo(CommandStatus.Success), result.Message);
      Assert.That(result.Message, Is.EqualTo("cebhionn"));
    }
Beispiel #12
0
    /// <summary>
    /// Evaluate a single expression
    /// </summary>
    /// <param name="item">The current item</param>
    /// <param name="exp">The expression to evaluate</param>
    /// <returns>The outcome of the expression</returns>
    public static bool EvaluateSingleExpression(Context context, string exp)
    {
      // Clean the expression
      exp = exp.Trim();

      // substitute tokens
      exp = Parser.PerformSubstitution(context, exp);

      // Parse elements
      string[] elms = Parser.ParseFirstLevelGroups(exp, Constants.SubcommandEnter, Constants.SubcommandExit);

      // Validate the expression
      if (elms.Length != 1 && elms.Length != 2 && elms.Length != 3 && elms.Length != 5 && elms.Length != 7)
        throw new ExpressionException("Malformed expression");

      // a single element in the expression should be parsable true or false
      if (elms.Length == 1)
      {
        var value = false;
        if (Parser.TryParseBoolean(elms[0], out value))
          return value;
        else
          throw new ExpressionException("Could not parse boolean value '" + elms[0] + "'");
      }

      // 2 elements means a function
      if (elms.Length == 2)
      {
        switch (elms[0])
        {
          case "isempty":
            return string.IsNullOrEmpty(elms[1]);

          case "not":
            return !EvaluateExpression(context, elms[1]);

          case "isbound":
            return context.CommandHandler.CoreCommands.ContainsKey(elms[1]) || context.CommandHandler.CustomCommands.ContainsKey(elms[1]);

          default:
            throw new ExpressionException("Unknown function " + elms[0]);
        }
      }

      string op = elms[1];
      if ((op != "<") && (op != ">") && (op != "=") && (op != "!=") && (op != "<=") && (op != ">=") && (op != "[") && (op != "]") && (op != "?") && (op != "!?"))
        throw new ExpressionException("Invalid operator " + op);

      // substitute fields and attributes and pull out casting operator and flags
      string type = "string";
      bool ignoreCase = false;
      bool ignoreDecimal = false;
      bool round = false;
      bool ceil = false;
      bool floor = false;

      for (int i = 0; i < elms.Length; i++)
      {
        if (elms[i].StartsWith("@@"))
        {
          var inspector = new ItemInspector(context.CurrentItem);
          var attr = inspector.GetItemAttribute(elms[i]);
          if (attr == null)
            throw new ExpressionException("Unknown attribute " + elms[i]);

          elms[i] = attr;
        }
        else if (elms[i].StartsWith("@"))
        {
          elms[i] = context.CurrentItem[elms[i].Substring(1)];
        }
        else
        {
          if (elms[i] == "as")
          {
            if (elms.Length >= i + 2)
              type = elms[i + 1];
            else
              throw new ExpressionException("Missing the cast type");
          }
          else if (elms[i] == "with")
          {
            if (elms.Length < i + 2)
              throw new ExpressionException("Missing flags");

            switch (elms[i + 1])
            {
              case "ignorecase": ignoreCase = true; break;
              case "ignoredecimal": ignoreDecimal = true; break;
              case "round": round = true; break;
              case "ceiling": ceil = true; break;
              case "floor": floor = true; break;
              default:
                throw new ExpressionException("Unknown flag " + elms[i + 1]);
            }
          }
        }
      }

      string val1 = elms[0];
      string val2 = elms[2];

      // Do we need to convert the strings?
      switch (type)
      {
        case "string":
          if (ignoreCase)
          {
            val1 = val1.ToLower();
            val2 = val2.ToLower();
          }

          // Now do the comparison
          switch (op)
          {
            case "=":
              return val1 == val2;

            case "<":
              return string.Compare(val1, val2) < 0;

            case ">":
              return string.Compare(val1, val2) > 0;

            case "!=":
              return val1 != val2;

            case "<=":
              return string.Compare(val1, val2) <= 0;

            case ">=":
              return string.Compare(val1, val2) >= 0;

            case "[":
              return val1.StartsWith(val2);

            case "]":
              return val1.EndsWith(val2);

            case "?":
              return val1.Contains(val2);

            case "!?":
              return !val1.Contains(val2);
          }
          break;

        case "number":
          if (val1.Length == 0 || val2.Length == 0)
            return false;

          double a = 0;
          double b = 0;
          if (!double.TryParse(val1, out a))
            throw new ExpressionException(string.Format("{0} is not a number", val1));
          if (!double.TryParse(val2, out b))
            throw new ExpressionException(string.Format("{0} is not a number", val2));

          if (ignoreDecimal)
          {
            a = Math.Truncate(a);
            b = Math.Truncate(b);
          }

          if (ceil)
          {
            a = Math.Ceiling(a);
            b = Math.Ceiling(b);
          }

          if (floor)
          {
            a = Math.Floor(a);
            b = Math.Floor(b);
          }

          if (round)
          {
            a = Math.Round(a);
            b = Math.Round(b);
          }

          // Now do the comparison
          switch (op)
          {
            case "=":
              return a == b;

            case "<":
              return a < b;

            case ">":
              return a > b;

            case "!=":
              return a != b;

            case "<=":
              return a <= b;

            case ">=":
              return a >= b;

            case "[":
              return a.ToString().StartsWith(b.ToString());

            case "]":
              return a.ToString().EndsWith(b.ToString());

            case "?":
              return a.ToString().Contains(b.ToString());

            case "!?":
              return !a.ToString().Contains(b.ToString());
          }
          break;

        case "date":
          if (val1.Length == 0 || val2.Length == 0)
            return false;

          DateTime aa;
          DateTime bb;
          DateTime defaultPassthrough = DateTime.MinValue.AddSeconds(7);

          var culture = Sitecore.Context.Culture;
          if (culture.IsNeutralCulture)
            culture = Thread.CurrentThread.CurrentCulture;

          aa = Sitecore.DateUtil.ParseDateTime(val1, defaultPassthrough, culture);
          if (aa == defaultPassthrough)
            throw new ExpressionException(string.Format("{0} is not a date", val1));

          bb = Sitecore.DateUtil.ParseDateTime(val2, defaultPassthrough, culture);
          if (bb == defaultPassthrough)
            throw new ExpressionException(string.Format("{0} is not a date", val2));

          // Now do the comparison
          switch (op)
          {
            case "=":
              return aa == bb;

            case "<":
              return aa < bb;

            case ">":
              return aa > bb;

            case "!=":
              return aa != bb;

            case "<=":
              return aa <= bb;

            case ">=":
              return aa >= bb;
          }
          break;
      }

      // Something went wrong if we get to here
      return false;
    }
Beispiel #13
0
    public void MultipleCommandChaining()
    {
      var ctx = new Mod.Context();
      ctx.CurrentItem = _testContent;
      var handler = new Mod.CommandHandler(ctx, new TextOutputFormatter());
      var result = handler.Execute("ga -a name > replace $~$ B c -c > split -s h $~$ (echo $current$)");

      Assert.That(result.Status, Is.EqualTo(CommandStatus.Success), result.Message);
      Assert.That(result.Message, Contains.Substring("ceb"));
      Assert.That(result.Message, Contains.Substring("ionn"));
    }
Beispiel #14
0
    public void SetContext_NumberedChild()
    {
      var startItem = _testTreeRoot.Axes.SelectSingleItem("Umbriel");

      var context = new Revolver.Core.Context();
      context.CurrentItem = startItem;

      var expectedItem = _testTreeRoot.Axes.SelectSingleItem("Umbriel/*[@title='Skoll 1']");

      var result = context.SetContext("skoll[1]");

      Assert.That(result.Status, Is.EqualTo(CommandStatus.Success));
      Assert.That(context.CurrentDatabase.Name, Is.EqualTo("web"));
      Assert.That(context.CurrentItem.ID, Is.EqualTo(expectedItem.ID));
      Assert.That(context.CurrentLanguage.Name, Is.EqualTo("en"));
    }
Beispiel #15
0
    public void AddAliasWithParameters()
    {
      var ctx = new Mod.Context();
      ctx.CurrentItem = _testContent;
      var handler = new Mod.CommandHandler(ctx, new TextOutputFormatter());

      var result = handler.AddCommandAlias("aa", "ls", "-a", "-d");
      Assert.That(result.Status, Is.EqualTo(CommandStatus.Success));

      // Verify the alias was added
      var exResult = handler.Execute("aa");
      Assert.That(exResult.Status, Is.EqualTo(CommandStatus.Success));
      Assert.That(exResult.Message, Contains.Substring("  phobos\r\n+ Luna\r\n  Deimos\r\n  Adrastea Phobos"));
    }
Beispiel #16
0
    public void SetContext_BadVersionNumber()
    {
      var context = new Revolver.Core.Context();
      context.CurrentItem = _testTreeRoot;

      var item = _testTreeRoot.Axes.GetChild("Sycorax");

      var result = context.SetContext(item.Paths.FullPath + "::&", null);

      Assert.That(result.Status, Is.EqualTo(CommandStatus.Failure));
      Assert.That(context.CurrentDatabase.Name, Is.EqualTo("web"));
      Assert.That(context.CurrentItem.ID, Is.EqualTo(_testTreeRoot.ID));
      Assert.That(context.CurrentLanguage.Name, Is.EqualTo("en"));
    }
Beispiel #17
0
 public static string EvaluatePrompt(Context context, string prompt)
 {
   return Prompt.EvaluatePrompt(context, prompt);
 }
Beispiel #18
0
 public static string PerformSubstitution(Context context, string input, bool autowrap)
 {
   return Parser.PerformSubstitution(context, input);
 }
Beispiel #19
0
    public void CommandFlagParameter()
    {
      var ctx = new Mod.Context();
      ctx.CurrentItem = _testContent;
      var handler = new Mod.CommandHandler(ctx, new TextOutputFormatter());
      var result = handler.Execute("ls -a -d");

      Assert.That(result.Status, Is.EqualTo(CommandStatus.Success));
      Assert.That(result.Message, Is.EqualTo("  phobos\r\n+ Luna\r\n  Deimos\r\n  Adrastea Phobos"));
    }
Beispiel #20
0
 public static bool EvaluateSingleExpression(Context context, string exp)
 {
   return ExpressionParser.EvaluateSingleExpression(context, exp);
 }
Beispiel #21
0
    /// <summary>
    /// Substitute tokens in the input string such as environment variables
    /// </summary>
    /// <param name="context">The context to use during substitution</param>
    /// <param name="input">The input to perform substitution on</param>
    /// <returns>A string with tokens replaced</returns>
    public static string PerformSubstitution(Context context, string input)
    {
      // Substitute environment variables
      foreach (string key in context.EnvironmentVariables.Keys)
      {
        if (input.Contains(Constants.TokenIndicator + key + Constants.TokenIndicator))
          input = input.Replace(Constants.TokenIndicator + key + Constants.TokenIndicator, context.EnvironmentVariables[key]);
      }

      // Replace escaped tokens
      input = input.Replace(Constants.EscapeCharacter + Constants.TokenIndicator, Constants.TokenIndicator);

      return input;
    }
Beispiel #22
0
    public void CommandMixedParameterTypes()
    {
      var deimosId = _testContent.Axes.GetChild("Deimos").ID.ToString();
      var phobosId = _testContent.Axes.GetChild("phobos").ID.ToString();

      var ctx = new Mod.Context();
      ctx.CurrentItem = _testContent;
      var handler = new Mod.CommandHandler(ctx, new TextOutputFormatter());
      var result = handler.Execute(string.Format("find -i {0}|{1} -a name phobos -ns (ga -a id)", deimosId, phobosId));

      Assert.That(result.Status, Is.EqualTo(CommandStatus.Success));
      Assert.That(result.Message, Is.EqualTo(phobosId));
    }
Beispiel #23
0
    public void EscapedParameterDelimiter()
    {
      var ctx = new Mod.Context();
      ctx.CurrentItem = _testContent;
      var handler = new Mod.CommandHandler(ctx, new TextOutputFormatter());
      var result = handler.Execute("echo lorem \\(ipsum dolor\\)");

      Assert.That(result.Status, Is.EqualTo(CommandStatus.Success));
      Assert.That(result.Message, Is.EqualTo("lorem (ipsum dolor)"));
    }
Beispiel #24
0
 /// <summary>
 /// Stores the given context internally
 /// </summary>
 /// <param name="context">The context to store</param>
 private void StoreContext(Context context)
 {
   _context = context;
   _prevItem = context.CurrentItem;
   _prevLanguage = _context.CurrentLanguage;
 }
Beispiel #25
0
    public void SetContext_NumberedChildTooHigh()
    {
      var startItem = _testTreeRoot.Axes.SelectSingleItem("Umbriel");

      var context = new Revolver.Core.Context();
      context.CurrentItem = startItem;

      var result = context.SetContext("skoll[5]");

      Assert.That(result.Status, Is.EqualTo(CommandStatus.Failure));
      Assert.That(context.CurrentDatabase.Name, Is.EqualTo("web"));
      Assert.That(context.CurrentItem.ID, Is.EqualTo(startItem.ID));
      Assert.That(context.CurrentLanguage.Name, Is.EqualTo("en"));
    }
Beispiel #26
0
 public static string EvaluatePath(Context context, string path)
 {
   return PathParser.EvaluatePath(context, path);
 }
Beispiel #27
0
    public void AddAliasSameAsAlias()
    {
      var ctx = new Mod.Context();
      ctx.CurrentItem = _testContent;
      var handler = new Mod.CommandHandler(ctx, new TextOutputFormatter());

      handler.AddCommandAlias("aa", "ls");

      var result = handler.AddCommandAlias("aa", "ga");
      Assert.That(result.Status, Is.EqualTo(CommandStatus.Failure));
    }
Beispiel #28
0
 public static CommandResult SetContext(Context context, string path, string dbName = null, Language language = null, int? versionNumber = null)
 {
   return context.SetContext(path, dbName, language, versionNumber);
 }
Beispiel #29
0
 /// <summary>
 /// Create a new instance of this class
 /// </summary>
 /// <param name="context">The Revolver vontext to operate on</param>
 /// <param name="formatter">The formatter to use</param>
 public CommandHandler(Context context, ICommandFormatter formatter)
 {
   _commands = new Dictionary<string, Type>();
   _custcommands = new Dictionary<string, Type>();
   _commandAliases = new Dictionary<string, CommandArgs>();
   Context = context;
   _formatter = formatter;
   ScriptLocator = new ScriptLocator.ScriptLocator();
   
   CommandInspector.FindAllCommands(_commands);
 }