public void CleanVoteLine_ItalicsInContent() { string line = "[x] 『i』Vote『/i』 for stuff"; string cleanLine = "[x] 『i』Vote『/i』 for stuff"; Assert.AreEqual(cleanLine, VoteString.CleanVoteLineBBCode(line)); }
public void CleanVoteLine_NestedCodes() { string line = "[x] 『b』『i』Vote『/i』 for stuff『/b』"; string cleanLine = "[x] 『b』『i』Vote『/i』 for stuff『/b』"; Assert.AreEqual(cleanLine, VoteString.CleanVoteLineBBCode(line)); }
public void CleanVoteLine_FullLineBoldPreTask() { string line = "-[x]『b』[Who] Vote for stuff『/b』"; string cleanLine = "-[x][Who] Vote for stuff"; Assert.AreEqual(cleanLine, VoteString.CleanVoteLineBBCode(line)); }
public void RemoveBBCode_NoBBCode() { string line = "[x] Vote for stuff"; string cleanLine = "[x] Vote for stuff"; Assert.AreEqual(cleanLine, VoteString.RemoveBBCode(line)); }
public void CleanVoteLine_ColorMarkerPlus() { string line = "『color=blue』[x]『/color』[main] 『b』『b』Vote『/b』 for stuff"; string cleanLine = "[x][main] 『b』Vote『/b』 for stuff"; Assert.AreEqual(cleanLine, VoteString.CleanVoteLineBBCode(line)); }
public void RemoveBBCode_MultiCodes() { string line = "『color=blue』『b』[x] 『i』Vote『/i』 for stuff『/b』"; string cleanLine = "[x] Vote for stuff"; Assert.AreEqual(cleanLine, VoteString.RemoveBBCode(line)); }
public void DeUrl_AtUrl() { string content = "[url=https://forum.questionablequesting.com/members/2392/]@Xryuran[/url]"; string clean = "Xryuran"; Assert.AreEqual(clean, VoteString.DeUrlContent(content)); }
public void CleanVoteLine_InMarkerPlus() { string line = "-『b』[『b』x][Who『/b』] 『b』Vote『/b』 for stuff『/b』"; string cleanLine = "-[x][Who] 『b』Vote『/b』 for stuff"; Assert.AreEqual(cleanLine, VoteString.CleanVoteLineBBCode(line)); }
private void modifyTask_Click(object sender, RoutedEventArgs e) { if (sender is MenuItem mi) { if (mi.Parent is ContextMenu cm) { if (cm.PlacementTarget is ListBox box) { if (box.SelectedItem?.ToString() is string selectedVote) { string changedVote = ""; if (mi.Header.ToString() == "Clear Task") { changedVote = VoteString.ReplaceTask(selectedVote, "", CurrentVoteType); } else { changedVote = VoteString.ReplaceTask(selectedVote, mi.Header.ToString(), CurrentVoteType); } MergeVotes(selectedVote, changedVote); box.SelectedItem = changedVote; } } } } }
/// <summary> /// Process acceptance of the new task text. /// </summary> private void AcceptInput() { // YesButton Clicked! Let's hide our InputBox and handle the input text. InputBox.Visibility = Visibility.Collapsed; string newTask = InputTextBox.Text.RemoveUnsafeCharacters().Trim(); // Clear InputBox. InputTextBox.Text = String.Empty; // Do something with the Input AddTaskToContextMenu(newTask); // Update the selected item of the list box string selectedVote = newTaskBox?.SelectedItem?.ToString(); if (selectedVote != null) { string changedVote = VoteString.ReplaceTask(selectedVote, newTask, CurrentVoteType); MergeVotes(selectedVote, changedVote); newTaskBox.SelectedItem = changedVote; } newTaskBox = null; }
/// <summary> /// Add the list of all voters for a given winning option, along with /// the ranking they gave that option. /// </summary> /// <param name="taskName">The name of the task.</param> /// <param name="choice">The name of the choice selected.</param> private void AddRankedVoters(string taskName, string choice) { var votes = VoteCounter.Instance.GetVotesCollection(VoteType.Rank); var voters = VoteCounter.Instance.GetVotersCollection(VoteType.Rank); var whoVoted = from v in votes where Agnostic.StringComparer.Equals(VoteString.GetVoteTask(v.Key), taskName) && Agnostic.StringComparer.Equals(VoteString.GetVoteContent(v.Key), choice) select new { marker = VoteString.GetVoteMarker(v.Key), voters = v.Value }; var whoDidNotVote = from v in voters where whoVoted.Any(a => a.voters.Contains(v.Key)) == false select v.Key; using (new Spoiler(sb, "Voters", DisplayMode == DisplayMode.SpoilerVoters || DisplayMode == DisplayMode.SpoilerAll)) { foreach (var mark in whoVoted.OrderBy(a => a.marker)) { var sortedVoters = mark.voters.OrderBy(a => a); foreach (var voter in sortedVoters) { AddVoter(voter, VoteType.Rank, mark.marker); } } foreach (var nonVoter in whoDidNotVote.OrderBy(a => a)) { AddVoter(nonVoter, VoteType.Rank, "-"); } } sb.AppendLine(); }
/// <summary> /// Extract any vote lines from the message text, and save both the original and /// the cleaned (no BBCode) in a list. /// Do not record any vote lines if there's a tally marker (#####). /// Mark the vote as valid if it has any vote lines. /// </summary> /// <param name="message">The original, full message text.</param> private void ProcessMessageLines(string message) { var messageLines = message.GetStringLines(); foreach (var line in messageLines) { string cleanLine = VoteString.RemoveBBCode(line); if (tallyRegex.Match(cleanLine).Success) { // If this is a tally post, clear any found vote lines and end processing. VoteLines.Clear(); break; } Match m = voteLineRegex.Match(cleanLine); if (m.Success) { VoteLines.Add(new VoteLine(line)); } } VoteLines.IsReadonly = true; IsValid = VoteLines.Any(); }
public void GetPlanNameTest7() { string input = "[X] Kinematics"; string expect = "Kinematics".MakePlanName(); Assert.AreEqual(null, VoteString.GetMarkedPlanName(input)); }
public int Compare(object x, object y) { if (x == null) { throw new ArgumentNullException(nameof(x)); } if (y == null) { throw new ArgumentNullException(nameof(y)); } string xs = x as string; if (xs == null) { throw new ArgumentException("Parameter x is not a string."); } string ys = y as string; if (ys == null) { throw new ArgumentException("Parameter y is not a string."); } string marker = VoteString.GetVoteMarker(xs); VoteType voteType = string.IsNullOrEmpty(marker) ? VoteType.Rank : VoteType.Plan; string compX = VoteString.GetVoteTask(xs, voteType) + " " + VoteString.GetVoteContent(xs, voteType); string compY = VoteString.GetVoteTask(ys, voteType) + " " + VoteString.GetVoteContent(ys, voteType); int result = string.Compare(compX, compY, StringComparison.CurrentCultureIgnoreCase); return(result); }
public void DeUrl_Image() { string content = "[url=http://google.com/image/1.jpg]<Image>[/url]"; string clean = "<Image>"; Assert.AreEqual(clean, VoteString.DeUrlContent(content)); }
public void CleanVoteLine_NestedTaskMarkup() { string line = "-[x][『color=#15fae6』『b』Who『/b』『/color』] Vote for stuff"; string cleanLine = "-[x][Who] Vote for stuff"; Assert.AreEqual(cleanLine, VoteString.CleanVoteLineBBCode(line)); }
public void RemoveBBCode_Empty() { string line = ""; string cleanLine = ""; Assert.AreEqual(cleanLine, VoteString.RemoveBBCode(line)); }
public void RemoveBBCode_FullLineBold() { string line = "『b』[x] Vote for stuff『/b』"; string cleanLine = "[x] Vote for stuff"; Assert.AreEqual(cleanLine, VoteString.RemoveBBCode(line)); }
public void DeUrl_Link() { string content = "Vote for [url=http://google.com/myhome.html]me[/url]!"; string clean = "Vote for me!"; Assert.AreEqual(clean, VoteString.DeUrlContent(content)); }
public void CleanVoteLine_LongSamplePartialColors() { string line = "[X] - Brutalize them. You haven’t had a chance to properly fight in 『/color』『i』『color=#ebebeb』years『/color』『/i』『color=#ebebeb』, and spars can only do so much. How thoughtful of the Herans to volunteer!"; string cleanLine = "[X] - Brutalize them. You haven’t had a chance to properly fight in 『i』『color=#ebebeb』years『/color』『/i』, and spars can only do so much. How thoughtful of the Herans to volunteer!"; Assert.AreEqual(cleanLine, VoteString.CleanVoteLineBBCode(line)); }
public void CleanVoteLine_TaskMarkup() { string line = "-[x][『b』Who『/b』] Vote for stuff"; string cleanLine = "-[x][Who] Vote for stuff"; Assert.AreEqual(cleanLine, VoteString.CleanVoteLineBBCode(line)); }
/// <summary> /// Merges the specified from vote into the specified to vote, assuming the votes aren't the same. /// Moves the voters from the from vote into the to vote list, and removes the from vote's key. /// </summary> /// <param name="fromVote">Vote that is being merged.</param> /// <param name="toVote">Vote that is being merged into.</param> /// <returns>Returns true if there were any changes.</returns> private bool MergeRanks(string fromVote, string toVote) { var votes = GetVotesCollection(VoteType.Rank); Dictionary <KeyValuePair <string, HashSet <string> >, string> mergedVotes = new Dictionary <KeyValuePair <string, HashSet <string> >, string>(); foreach (var vote in votes) { if (VoteString.CondenseVote(vote.Key) == fromVote) { string toContent = VoteString.GetVoteContent(toVote, VoteType.Rank); string toTask = VoteString.GetVoteTask(toVote, VoteType.Rank); string revisedKey = VoteString.ModifyVoteLine(vote.Key, task: toTask, content: toContent); mergedVotes.Add(vote, revisedKey); } } if (mergedVotes.Count > 0) { var voters = GetVotersCollection(VoteType.Rank); UndoBuffer.Push(new UndoAction(UndoActionType.Merge, VoteType.Rank, voters, mergedVotes)); foreach (var merge in mergedVotes) { Rename(merge.Key, merge.Value, VoteType.Rank); } return(true); } return(false); }
/// <summary> /// Counts the provided rank votes. /// </summary> /// <param name="votes">The rank votes to count.</param> /// <returns>Returns an ordered list of ranked votes for each task in the provided votes.</returns> /// <exception cref="System.ArgumentNullException">Provided votes cannot be null.</exception> public RankResultsByTask CountVotes(Dictionary <string, HashSet <string> > votes) { if (votes == null) { throw new ArgumentNullException(nameof(votes)); } RankResultsByTask preferencesByTask = new RankResultsByTask(); if (votes.Any()) { // Handle each task separately var groupByTask = votes.GroupBy(vote => VoteString.GetVoteTask(vote.Key), Agnostic.StringComparer); foreach (GroupedVotesByTask task in groupByTask) { if (task.Any()) { preferencesByTask[task.Key] = RankTask(task); Debug.WriteLine($"Ranking task [{task.Key}] via [{this.GetType().Name}]:"); foreach (var res in preferencesByTask[task.Key]) { Debug.WriteLine($" - Option [{res.Option}] Debug [{res.Debug}]"); } } } } return(preferencesByTask); }
/// <summary> /// Attempt to find any existing vote that matches with the vote we have, /// and can be used as a key in the VotesWithSupporters table. /// </summary> /// <param name="vote">The vote to search for.</param> /// <returns>Returns the string that can be used as a key in the VotesWithSupporters table.</returns> private string GetVoteKey(string vote, VoteType voteType) { // Store a lookup of the cleaned version of the vote so we don't have to repeat the processing. if (!cleanedKeys.TryGetValue(vote, out string cleaned)) { cleaned = VoteString.RemoveBBCode(vote); cleaned = VoteString.DeUrlContent(cleaned); cleanedKeys[vote] = cleaned; } var votes = GetVotesCollection(voteType); // If the vote already matches an existing key, we don't need to search again. if (votes.ContainsKey(vote)) { return(vote); } // Find any vote that matches using an agnostic string comparison, that ignores // case, spacing, and most punctuation. string agVote = votes.Keys.FirstOrDefault(k => Agnostic.StringComparer.Equals(cleaned, cleanedKeys[k])); // If we found a match, return that; otherwise this is a new vote, so return it unchanged. return(agVote ?? vote); }
/// <summary> /// Adds an individual vote. /// </summary> /// <param name="vote">The vote that is being added to.</param> /// <param name="voter">The voter that is supporting the vote.</param> /// <param name="voteType">Type of the vote.</param> /// <exception cref="System.ArgumentNullException">vote and voter must not be null or empty.</exception> private void AddVote(string vote, string voter, VoteType voteType) { if (string.IsNullOrEmpty(vote)) { throw new ArgumentNullException(nameof(vote)); } if (string.IsNullOrEmpty(voter)) { throw new ArgumentNullException(nameof(voter)); } string voteKey = GetVoteKey(vote, voteType); var votes = GetVotesCollection(voteType); // Make sure there's a hashset for the voter list available for the vote key. if (votes.ContainsKey(voteKey) == false) { votes[voteKey] = new HashSet <string>(StringComparer.OrdinalIgnoreCase); OnPropertyChanged("Votes"); } string cleanVoter = VoteString.RemoveBBCode(voter); cleanVoter = VoteString.DeUrlContent(cleanVoter); // Update the supporters list if the voter isn't already in it. if (votes[voteKey].Contains(cleanVoter)) { return; } votes[voteKey].Add(cleanVoter); OnPropertyChanged("Voters"); }
public void DeUrl_NoneWithBBCode() { string content = "『i』Vote『/i』 for stuff"; string clean = "『i』Vote『/i』 for stuff"; Assert.AreEqual(clean, VoteString.DeUrlContent(content)); }
public void DeUrl_None() { string content = "Vote for stuff"; string clean = "Vote for stuff"; Assert.AreEqual(clean, VoteString.DeUrlContent(content)); }
public void GetPlanNameTest7() { string input = "[X] Kinematics"; string expect = StringUtility.PlanNameMarker + "Kinematics"; Assert.AreEqual(null, VoteString.GetMarkedPlanName(input)); }
public void DeUrl_Empty() { string content = ""; string clean = ""; Assert.AreEqual(clean, VoteString.DeUrlContent(content)); }
public void GetPlanNameTest5() { string input = "[X] Plan: Kinematics"; Assert.AreEqual("Kinematics", VoteString.GetPlanName(input)); Assert.AreEqual(null, VoteString.GetPlanName(input, true)); Assert.AreEqual("Kinematics", VoteString.GetPlanName(input, false)); }