public void CloneTest() { Record target = new Record(); Record expected = target; Record actual; actual = target.Clone(); Assert.AreNotEqual(expected, actual); target.Leader = "Take me to your leader!"; string expectedString = string.Empty.PadRight(FileMARC.LEADER_LEN); string actualString; actualString = actual.Leader; Assert.AreEqual(expectedString, actualString); target.Warnings.Add("Testing!"); int expectedCount = 0; int actualCount; actualCount = actual.Warnings.Count; Assert.AreEqual(expectedCount, actualCount); target.Fields.Add(new ControlField("001", "Test Data")); expectedCount = 0; actualCount = actual.Fields.Count; Assert.AreEqual(expectedCount, actualCount); }
/// <summary> /// Decodes the raw MARC record into a <see cref="MARC.Record"/> at the specified index./// /// </summary> /// <param name="index">The index of the record to retrieve.</param> /// <returns></returns> private Record Decode(int index) { XElement record = _rawSource[index]; Record marcXml = new Record(); //First we get the leader marcXml.Leader = record.Elements().First(e => e.Name.LocalName == "leader").Value; //Now we get the control fields foreach (XElement controlField in record.Elements().Where(e => e.Name.LocalName == "controlfield")) { ControlField newField = new ControlField(controlField.Attribute("tag").Value, controlField.Value); marcXml.Fields.Add(newField); } //Now we get the data fields foreach (XElement dataField in record.Elements().Where(e => e.Name.LocalName == "datafield")) { DataField newField = new DataField(dataField.Attribute("tag").Value, new List<Subfield>(), dataField.Attribute("ind1").Value[0], dataField.Attribute("ind2").Value[0]); foreach (XElement subfield in dataField.Elements().Where(e => e.Name.LocalName == "subfield")) { Subfield newSubfield = new Subfield(subfield.Attribute("code").Value[0], subfield.Value); newField.Subfields.Add(newSubfield); } marcXml.Fields.Add(newField); } return marcXml; }
public void WarningsTest() { Record target = new Record(); string expected = "IT'S ALL BROKEN! SOUND THE ALARM!"; target.AddWarnings("IT'S ALL BROKEN! SOUND THE ALARM!"); List<string> actual; actual = target.Warnings; Assert.AreEqual(expected, actual[0]); }
public void ToRawTest() { Record target = new Record(); target.Fields.Add(new ControlField("001", "I am data! (But not Data from Star Trek TNG)")); //This will be empty, and thus not written target.Fields.Add(new DataField("245")); //I broke each bit of the record out into their own strings and concatenated because it's easier to follow. //Leader -> Tag -> Length (+1 for EoF) -> Starts At -> EoF -> Data -> EoF -> EoR string expected = "00083 2200037 4500" + "001" + "0045" + "00000" + FileMARC.END_OF_FIELD + "I am data! (But not Data from Star Trek TNG)" + FileMARC.END_OF_FIELD + FileMARC.END_OF_RECORD; string actual; actual = target.ToRaw(); Assert.AreEqual(expected, actual); }
public void ToStringTest() { Record target = new Record(); target.Fields.Add(new ControlField("001", "I am data! (But not Data from Star Trek TNG)")); //This will be empty, and thus not written target.Fields.Add(new DataField("245")); string expected = "LDR 00083 2200037 4500" + Environment.NewLine + "001" + " " + "I am data! (But not Data from Star Trek TNG)" + Environment.NewLine; string actual; actual = target.ToString(); Assert.AreEqual(expected, actual); }
public void LeaderTest() { Record target = new Record(); string expected = "Take me to your leader!"; string actual; target.Leader = expected; actual = target.Leader; Assert.AreEqual(expected, actual); }
public void RecordConstructorTest() { Record target = new Record(); { int expected = 0; int actual = target.Fields.Count; Assert.AreEqual(expected, actual); actual = target.Warnings.Count; Assert.AreEqual(expected, actual); } { string expected = " "; //24 spaces! Yes I counted! :awesome: string actual = target.Leader; Assert.AreEqual(expected, actual); } }
public void InsertFieldTest() { Record target = new Record(); string tag = "245"; target.Fields.Add(new ControlField("001", "I am data! (But not Data from Star Trek TNG)")); target.Fields.Add(new DataField(tag)); target.Fields.Add(new DataField("521", new List<Subfield>(), ' ', '1')); Field newField = new DataField("300", new List<Subfield>(), '0', '1'); target.InsertField(newField); Assert.AreSame(newField, target.Fields[2]); }
public void ItemTest() { Record target = new Record(); string tag = "245"; ControlField controlField = new ControlField("001", "I am data! (But not Data from Star Trek TNG)"); DataField dataField = new DataField(tag); DataField dataField2 = new DataField(tag, new List<Subfield>(), ' ', '1'); target.Fields.Add(controlField); target.Fields.Add(dataField); target.Fields.Add(dataField2); Field expected = dataField; Field actual; actual = target[tag]; }
public void GetFieldsTest() { Record target = new Record(); string tag = "245"; target.Fields.Add(new ControlField("001", "I am data! (But not Data from Star Trek TNG)")); target.Fields.Add(new DataField(tag)); target.Fields.Add(new DataField("521", new List<Subfield>(), ' ', '1')); List<Field> expected = new List<Field>(); expected.Add(new DataField(tag)); List<Field> actual; actual = target.GetFields(tag); Assert.AreEqual(expected.Count, actual.Count); Assert.AreEqual(expected[0].ToRaw(), actual[0].ToRaw()); }
public void FieldsTest() { Record target = new Record(); ControlField controlField = new ControlField("001", "I am data! (But not Data from Star Trek TNG)"); DataField dataField = new DataField("245"); DataField dataField2 = new DataField("521", new List<Subfield>(), ' ', '1'); target.Fields.Add(controlField); target.Fields.Add(dataField); target.Fields.Add(dataField2); { int expected = 3; int actual; actual = target.Fields.Count; Assert.AreEqual(expected, actual); } { Field expected = controlField; Field actual; actual = target.Fields[0]; Assert.AreSame(expected, actual); expected = dataField; actual = target.Fields[1]; Assert.AreSame(expected, actual); expected = dataField2; actual = target.Fields[2]; Assert.AreSame(expected, actual); } { List<Field> expected = new List<Field>(); expected.Add(controlField); expected.Add(dataField); expected.Add(dataField2); target.Fields = expected; List<Field> actual; actual = target.Fields; Assert.AreSame(expected, actual); } }
/// <summary> /// Decodes the raw MARC record into a <see cref="MARC.Record"/> at the specified index./// /// </summary> /// <param name="index">The index of the record to retrieve.</param> /// <returns></returns> private Record Decode(int index) { string raw = _rawSource[index]; Record marc = new Record(); Match match = Regex.Match(raw, "^(\\d{5})"); int recordLength = 0; // Store record length if (match.Captures.Count == 0) marc.AddWarnings("MARC record length is not numeric."); else recordLength = Convert.ToInt32(match.Captures[0].Value); if (recordLength != raw.Length) { marc.AddWarnings("MARC record length does not match actual length."); recordLength = raw.Length; } if (!raw.EndsWith(END_OF_RECORD.ToString())) throw new InvalidDataException("MARC record ends with an invalid terminator"); //Store leader marc.Leader = raw.Substring(0, LEADER_LEN); //Bytes 12-16 of leader give offset to the body of the record int dataStart = Convert.ToInt32(raw.Substring(12, 5)); //Immediately after the leader comes the directory (no separator) string directory = raw.Substring(LEADER_LEN, dataStart - LEADER_LEN - 1); //Character after the directory should be END_OF_FIELD if (raw.Substring(dataStart - 1, 1) != END_OF_FIELD.ToString()) marc.AddWarnings("No directory found."); //All directory entries must be DIRECTORY_ENTRY_LEN long, so length % DIRECTORY_ENTRY_LEN should be 0 if (directory.Length % DIRECTORY_ENTRY_LEN != 0) marc.AddWarnings("Invalid directory length."); //Go through all the fields int fieldCount = directory.Length / DIRECTORY_ENTRY_LEN; for (int i = 0; i < fieldCount; i++) { string tag = directory.Substring(i * DIRECTORY_ENTRY_LEN, DIRECTORY_ENTRY_LEN).Substring(0, 3); int fieldLength = 0; int fieldOffset = 0; try { fieldLength = Convert.ToInt32(directory.Substring(i * DIRECTORY_ENTRY_LEN, DIRECTORY_ENTRY_LEN).Substring(3, 4)); } catch (FormatException) { marc.AddWarnings("Invalid Directory Tag Length for tag " + tag + "."); } try { fieldOffset = Convert.ToInt32(directory.Substring(i * DIRECTORY_ENTRY_LEN, DIRECTORY_ENTRY_LEN).Substring(7, 5)); } catch (FormatException) { marc.AddWarnings("Invalid Directory Offset for tag " + tag + "."); } //Check Directory validity //If a tag isn't valid, default it to ZZZ. This should at least make the record valid enough to be readable and not throw exceptions if (!Field.ValidateTag(tag)) { marc.AddWarnings("Invalid tag " + tag + " in directory."); tag = "ZZZ"; } if (fieldOffset + fieldLength > recordLength) marc.AddWarnings("Directory entry for tag " + tag + " runs past the end of the record."); int fieldStart = dataStart + fieldOffset; if (fieldStart > recordLength) { marc.AddWarnings("Directory entry for tag " + tag + " starts past the end of the record. Skipping tag and all proceeding tags."); break; } else if (fieldStart + fieldLength > recordLength) { marc.AddWarnings("Directory entry for tag " + tag + " runs past the end of the record."); fieldLength = recordLength - fieldStart; } string tagData = raw.Substring(fieldStart, fieldLength); if (tagData.Substring(tagData.Length - 1, 1) == END_OF_FIELD.ToString()) { //Get rid of the end of tag character tagData = tagData.Remove(tagData.Length - 1); fieldLength--; } else marc.AddWarnings("Field for tag " + tag + " does not end with an end of field character."); match = Regex.Match(tag, "^\\d+$"); if (match.Captures.Count > 0 && Convert.ToInt32(tag) < 10) marc.Fields.Add(new ControlField(tag, tagData)); else { List<string> rawSubfields = new List<string>(tagData.Split(SUBFIELD_INDICATOR)); string indicators = rawSubfields[0]; rawSubfields.RemoveAt(0); char ind1; char ind2; if (indicators.Length != 2) { marc.AddWarnings("Invalid indicator length. Forced indicators to blanks for tag " + tag + "."); ind1 = ind2 = ' '; } else { ind1 = char.ToLower(indicators[0]); if (!DataField.ValidateIndicator(ind1)) { ind1 = ' '; marc.AddWarnings("Invalid first indicator. Forced first indicator to blank for tag " + tag + "."); } ind2 = char.ToLower(indicators[1]); if (!DataField.ValidateIndicator(ind2)) { ind2 = ' '; marc.AddWarnings("Invalid second indicator. Forced second indicator to blank for tag " + tag + "."); } } //Split the subfield data into subfield name and data pairs List<Subfield> subfieldData = new List<Subfield>(); foreach (string subfield in rawSubfields) { if (subfield.Length > 0) subfieldData.Add(new Subfield(subfield[0], subfield.Substring(1))); else marc.AddWarnings("No subfield data found in tag " + tag + "."); } if (subfieldData.Count == 0) marc.AddWarnings("No subfield data found in tag " + tag + "."); marc.Fields.Add(new DataField(tag, subfieldData, ind1, ind2)); } } return marc; }
/// <summary> /// Writes the specified record. /// </summary> /// <param name="record">The record.</param> public void Write(Record record) { XDocument xml = record.ToXMLDocument(); xml.Save(writer); }
/// <summary> /// Makes a deep clone of this instance. /// </summary> /// <returns></returns> public Record Clone() { Record clone = new Record(); clone.Leader = this.Leader; foreach (string needsCloned in Warnings) clone.AddWarnings(needsCloned); foreach (Field needsCloned in this.Fields) clone.Fields.Add(needsCloned.Clone()); return clone; }