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)); }
/// <summary> /// Given a group of votes (grouped by task), create and return /// a list of VoteNodes that collapse together votes that are /// sub-votes of each other. /// </summary> /// <param name="taskGroup">A set of votes with the same task value.</param> /// <returns>Returns a list of VoteNodes that collapse similar votes.</returns> public static IEnumerable<VoteNode> GetVoteNodes(IGrouping<string, KeyValuePair<string, HashSet<string>>> taskGroup) { var groupByFirstLine = taskGroup.GroupBy(v => v.Key.GetFirstLine(), Agnostic.StringComparer); List<VoteNode> nodeList = new List<VoteNode>(); VoteNode parent; foreach (var voteGroup in groupByFirstLine) { parent = null; if (voteGroup.Count() == 1) { string planname = VoteString.GetPlanName(voteGroup.Key); if (planname != null && VoteCounter.Instance.HasPlan(planname)) { var vote = voteGroup.First(); parent = new VoteNode(vote.Key, vote.Value); nodeList.Add(parent); continue; } } foreach (var vote in voteGroup) { var lines = vote.Key.GetStringLines(); if (parent == null) { var voters = lines.Count == 1 ? vote.Value : null; parent = new VoteNode(lines[0], voters); } if (lines.Count == 1) { parent.AddVoters(vote.Value); } else if (lines.Count == 2 && !string.IsNullOrEmpty(VoteString.GetVotePrefix(lines[1]))) { parent.AddChild(lines[1], vote.Value); } else { parent.AddChild(vote.Key, vote.Value); } } if (parent != null) { nodeList.Add(parent); } } return nodeList.OrderByDescending(v => v.VoterCount); }
/// <summary> /// Takes the full vote string list of the vote and breaks it /// into base plans, regular vote lines, and ranked vote lines. /// Store in the local object properties. /// </summary> /// <param name="voteStrings">The list of all the lines in the vote post.</param> private void SeparateVoteStrings(List <string> voteStrings) { BasePlans = new List <IGrouping <string, string> >(); List <string> consolidatedLines = new List <string>(); // Group blocks based on parent vote lines (no prefix). // Key for each block is the parent vote line. var voteBlocks = voteStrings.GroupAdjacentToPreviousKey( (s) => string.IsNullOrEmpty(VoteString.GetVotePrefix(s)), (s) => s, (s) => s); bool addBasePlans = true; foreach (var block in voteBlocks) { if (addBasePlans) { if (block.Count() > 1) { string planName = VoteString.GetPlanName(block.Key, basePlan: true); if (planName != null && !VoteCounter.Instance.ReferenceVoters.Contains(planName, Agnostic.StringComparer)) { BasePlans.Add(block); continue; } } } addBasePlans = false; consolidatedLines.AddRange(block.ToList()); } RankLines = new List <string>(); VoteLines = new List <string>(); foreach (var line in consolidatedLines) { if (VoteString.IsRankedVote(line)) { RankLines.Add(line); } else { VoteLines.Add(line); } } // If we have ranked vote options, make sure we don't have duplicate entries, // or the same option voted on different ranks. if (RankLines.Count > 0) { var groupRankLinesMulti = RankLines.GroupBy(line => VoteString.GetVoteContent(line), Agnostic.StringComparer) .Where(group => group.Count() > 1); // If there are any, remove all but the top ranked option. foreach (var lineGroup in groupRankLinesMulti) { var topOption = lineGroup.MinObject(a => VoteString.GetVoteMarker(a)); var otherOptions = lineGroup.Where(a => a != topOption).ToList(); foreach (string otherOption in otherOptions) { RankLines.Remove(otherOption); } } } }