private static TokenTextPart GetTokenTextPart(int lineCount) { TokenTextPart part = new TokenTextPart { ItemId = Guid.NewGuid().ToString(), CreatorId = "zeus", UserId = "zeus" }; char c = 'a'; StringBuilder sb = new StringBuilder(); for (int y = 0; y < lineCount; y++) { sb.Clear(); for (int x = 0; x < 3; x++) { if (x > 0) { sb.Append(' '); } sb.Append(c).Append(x + 1); if (++c > 'z') { c = 'a'; } } part.Lines.Add(new TextLine { Y = y + 1, Text = sb.ToString() }); } return(part); }
/// <summary> /// Pick (if possible) the specified count of random locations in the /// base text part, each with its corresponding piece of text. /// </summary> /// <param name="part">The part.</param> /// <param name="count">The count.</param> /// <returns>A list of tuples where 1=location, 2=base text.</returns> private IList <Tuple <string, string> > PickLocAndTexts( TokenTextPart part, int count) { HashSet <Tuple <int, int> > usedCoords = new HashSet <Tuple <int, int> >(); Dictionary <int, string[]> tokens = new Dictionary <int, string[]>(); List <Tuple <string, string> > results = new List <Tuple <string, string> >(); while (count > 0) { for (int attempt = 0; attempt < 10; attempt++) { // pick a line int y = Randomizer.Seed.Next(1, part.Lines.Count + 1); // pick a token in that line if (!tokens.ContainsKey(y)) { tokens[y] = part.Lines[y - 1].GetTokens(); } int x = Randomizer.Seed.Next(1, tokens[y].Length + 1); // select if not already used Tuple <int, int> yx = Tuple.Create(y, x); if (!usedCoords.Contains(yx)) { usedCoords.Add(yx); results.Add(Tuple.Create($"{y}.{x}", tokens[y][x - 1])); break; } } count--; } return(results); }
public void GetDataPins_NoCitation_Empty() { TokenTextPart part = GetPart(); part.Citation = null; Assert.Empty(part.GetDataPins()); }
public void GetTextAt_3LinesRange_Ok(string location, string expectedText) { TokenTextPart textPart = GetTokenTextPart(3); TokenTextLayerPart <CommentLayerFragment> layerPart = GetPart(); string text = layerPart.GetTextAt(textPart, location); Assert.Equal(expectedText, text); }
public void GetTextAt_InvalidLocation_Null() { TokenTextPart textPart = GetTokenTextPart(3); TokenTextLayerPart <CommentLayerFragment> layerPart = GetPart(); string text = layerPart.GetTextAt(textPart, "12.3"); Assert.Null(text); }
public void GetDataPins_WithItem_2() { Item item = new Item { CreatorId = "zeus", UserId = "zeus", Title = "Mock", Description = "A mock item", FacetId = "default", SortKey = "mock" }; TokenTextPart textPart = new TokenTextPart { ItemId = item.Id, CreatorId = item.CreatorId, UserId = item.UserId, }; textPart.Lines.Add(new TextLine { Text = "quae bixit annis X", Y = 1 }); item.Parts.Add(textPart); TokenTextLayerPart <OrthographyLayerFragment> layerPart = new TokenTextLayerPart <OrthographyLayerFragment>(); OrthographyLayerFragment fr; layerPart.AddFragment(fr = new OrthographyLayerFragment { Location = "1.2", Standard = "vixit", }); item.Parts.Add(layerPart); List <DataPin> pins = fr.GetDataPins(item).ToList(); Assert.Equal(2, pins.Count); DataPin pin = pins.Find(p => p.Name == "fr.orthography-txt"); Assert.NotNull(pin); Assert.Equal("bixit", pin.Value); pin = pins.Find(p => p.Name == "fr.orthography-std"); Assert.NotNull(pin); Assert.Equal("vixit", pin.Value); }
public void GetDataPins_Citation_1() { TokenTextPart part = GetPart(); List <DataPin> pins = part.GetDataPins().ToList(); Assert.Single(pins); DataPin pin = pins[0]; Assert.Equal(part.ItemId, pin.ItemId); Assert.Equal(part.Id, pin.PartId); Assert.Equal(part.RoleId, pin.RoleId); Assert.Equal("citation", pin.Name); Assert.Equal("some-citation", pin.Value); }
private static TokenTextPart GetPart() { TokenTextPart part = new TokenTextPart { ItemId = Guid.NewGuid().ToString(), RoleId = "some-role", CreatorId = "zeus", UserId = "another", Citation = "some-citation" }; for (int y = 1; y <= 3; y++) { part.Lines.Add(new TextLine { Y = y, Text = $"Line {y}." }); } return(part); }
public void Seed_Options_Tag() { TokenTextPartSeeder seeder = new TokenTextPartSeeder(); seeder.SetSeedOptions(_seedOptions); IPart part = seeder.GetPart(_item, null, _factory); Assert.NotNull(part); TokenTextPart tp = part as TokenTextPart; Assert.NotNull(tp); TestHelper.AssertPartMetadata(tp); Assert.NotNull(tp.Citation); Assert.NotEmpty(tp.Lines); for (int y = 1; y <= tp.Lines.Count; y++) { Assert.Equal(y, tp.Lines[y - 1].Y); } }
/// <summary> /// Creates and seeds a new part. /// </summary> /// <param name="item">The item this part should belong to.</param> /// <param name="roleId">The optional part role ID.</param> /// <param name="factory">The part seeder factory. This is used /// for layer parts, which need to seed a set of fragments.</param> /// <returns>A new part.</returns> /// <exception cref="ArgumentNullException">item or factory</exception> public override IPart GetPart(IItem item, string roleId, PartSeederFactory factory) { if (item == null) { throw new ArgumentNullException(nameof(item)); } if (factory == null) { throw new ArgumentNullException(nameof(factory)); } TokenTextPart part = new TokenTextPart(); SetPartMetadata(part, roleId, item); // citation part.Citation = Randomizer.Seed.Next(1, 100) .ToString(CultureInfo.InvariantCulture); // from 2 to 10 lines string text = new Faker().Lorem.Sentences( Randomizer.Seed.Next(2, 11)); int y = 1; foreach (string line in text.Split('\n')) { part.Lines.Add(new TextLine { Y = y++, Text = line.Trim() }); } return(part); }
public void Part_Is_Serializable() { TokenTextPart part = GetPart(); string json = TestHelper.SerializePart(part); TokenTextPart part2 = TestHelper.DeserializePart <TokenTextPart>(json); Assert.Equal(part.Id, part2.Id); Assert.Equal(part.TypeId, part2.TypeId); Assert.Equal(part.ItemId, part2.ItemId); Assert.Equal(part.RoleId, part2.RoleId); Assert.Equal(part.CreatorId, part2.CreatorId); Assert.Equal(part.UserId, part2.UserId); Assert.Equal(part.Citation, part2.Citation); Assert.Equal(part.Lines.Count, part2.Lines.Count); int i = 0; foreach (TextLine expected in part.Lines) { TextLine actual = part2.Lines[i++]; Assert.Equal(expected.Y, actual.Y); Assert.Equal(expected.Text, actual.Text); } }
/// <summary> /// Creates and seeds a new part with its fragments. The fragment /// type comes from the part's role ID. /// </summary> /// <param name="item">The item this part should belong to.</param> /// <param name="roleId">The optional part role ID.</param> /// <param name="factory">The part seeder factory. This is used /// for layer parts, which need to seed a set of fragments.</param> /// <returns>A new part.</returns> /// <exception cref="ArgumentNullException">item or factory</exception> public override IPart GetPart(IItem item, string roleId, PartSeederFactory factory) { if (item == null) { throw new ArgumentNullException(nameof(item)); } if (factory == null) { throw new ArgumentNullException(nameof(factory)); } if (_options == null || _options.MaxFragmentCount < 1) { return(null); } // get the base text part; nothing to do if none TokenTextPart textPart = item.Parts .OfType <TokenTextPart>() .FirstOrDefault(); if (textPart == null) { return(null); } // get the seeder; nothing to do if none string frTypeId = StripColonSuffix(roleId); IFragmentSeeder seeder = factory.GetFragmentSeeder("seed." + frTypeId); if (seeder == null) { return(null); } // get the layer part for the specified fragment type Type constructedType = typeof(TokenTextLayerPart <>) .MakeGenericType(seeder.GetFragmentType()); IPart part = (IPart)Activator.CreateInstance(constructedType); // seed metadata SetPartMetadata(part, frTypeId, item); // seed by adding fragments int count = Randomizer.Seed.Next(1, _options.MaxFragmentCount); IList <Tuple <string, string> > locAndTexts = PickLocAndTexts(textPart, count); // must invoke AddFragment via reflection, as the closed type // is known only at runtime foreach (var lt in locAndTexts) { ITextLayerFragment fr = seeder.GetFragment( item, lt.Item1, lt.Item2); if (fr != null) { constructedType.InvokeMember("AddFragment", BindingFlags.InvokeMethod, null, part, new[] { fr }); } } return(part); }