add-ed 0.6.0

Embeddable pure rust editor based on ED
Documentation
// Tests of the trickier cases
#[cfg(test)]
mod tests {
  use super::*;
  use super::super::Buffer;

  fn create_data() -> Vec<String> {
    vec![
      "1\n".to_string(),
      "2\n".to_string(),
      "3\n".to_string(),
      "4\n".to_string(),
      "5\n".to_string(),
      "6\n".to_string()
    ]
  }

  fn create_buffer() -> VecBuffer {
    let mut buf = VecBuffer::new();
    buf.insert(&mut create_data(), 0).unwrap();
    buf
  }

  #[test]
  fn verify_index() {
    let buffer = create_buffer();
    assert_eq!(Ok(()), buffer.verify_index(buffer.len()));
    assert_eq!(Ok(()), buffer.verify_index(0));
    assert_eq!(Err(INDEX_TOO_BIG), buffer.verify_index(buffer.len() + 1));
  }

  #[test]
  fn verify_selection() {
    let buffer = create_buffer();
    assert_eq!(Ok(()), buffer.verify_selection((0, buffer.len())));
    assert_eq!(Err(INDEX_TOO_BIG), buffer.verify_selection((0, buffer.len() + 1)));
    assert_eq!(Err(SELECTION_EMPTY), buffer.verify_selection((1, 0)));
  }

  #[test]
  fn saved() {
    let mut buffer = VecBuffer::new();
    assert!(buffer.saved());
    buffer.insert(&mut vec!["0".to_string()], 0).unwrap();
    assert!(!buffer.saved());
    buffer.set_saved();
    assert!(buffer.saved());
  }

  #[test]
  fn get_selection() {
    let data = create_data();
    let mut buffer = VecBuffer::new();
    buffer.insert(&mut data.clone(), 0).unwrap();
    assert_eq!(
      buffer.get_selection((0, 2)),
      Ok(&data[0 .. 2])
    );
  }

  #[test]
  fn insert() {
    // Todo, verify position of insert specifically.
    let data = create_data();
    let mut compare = data.clone();
    let mut buffer = VecBuffer::new();
    buffer.insert(&mut data.clone(), 0).unwrap();
    // Check that it inserts as expected
    let mut tmp = compare.split_off(3);
    compare.append(&mut data.clone());
    compare.append(&mut tmp);
    buffer.insert(&mut data.clone(), 3).unwrap();
    assert_eq!(Ok(&compare[..]), buffer.get_selection((0, buffer.len())));
  }

  #[test]
  fn delete() {
    let mut buffer = VecBuffer::new();
    let mut data = create_data();
    buffer.insert(&mut data.clone(), 0).unwrap();
    buffer.delete((0,3)).unwrap();
    let mut tail = data.split_off(3);
    let _deleted = data.split_off(0);
    data.append(&mut tail);
    assert_eq!(
      Ok(&data[..]),
      buffer.get_selection((0, buffer.len()))
    );
  }

  #[test]
  fn change() {
    let mut buffer1 = create_buffer();
    let mut buffer2 = create_buffer();
    let data = create_data();

    // Change should be the same as delete and insert
    // It exists only to allow optimisations
    buffer1.change(&mut data.clone(), (2,4)).unwrap();
    buffer2.delete((2,4)).unwrap();
    buffer2.insert(&mut data.clone(), 2).unwrap();
    assert_eq!(
      buffer1.get_selection((0, buffer1.len())).unwrap(),
      buffer2.get_selection((0, buffer2.len())).unwrap()
    );
  }

  #[test]
  fn mov() {
    // Create identical buffers and verify the move by
    // by comparing it to get_selection and insert
    let mut tmp = create_data();
    let mut buffer1 = VecBuffer::new();
    let mut buffer2 = VecBuffer::new();
    buffer1.insert(&mut tmp.clone(), 0).unwrap();
    buffer2.insert(&mut tmp, 0).unwrap();
    // forward
    buffer1.mov((0,3), 5).unwrap();
    let mut tmp = buffer2.get_selection((0,3)).unwrap().to_vec();
    buffer2.insert(&mut tmp, 5).unwrap();
    buffer2.delete((0,3)).unwrap();
    assert_eq!(
      buffer1.get_selection((0, buffer1.len())),
      buffer2.get_selection((0, buffer2.len()))
    );

    // Recreate buffers and test backward
    let mut tmp = create_data();
    let mut buffer1 = VecBuffer::new();
    let mut buffer2 = VecBuffer::new();
    buffer1.insert(&mut tmp.clone(), 0).unwrap();
    buffer2.insert(&mut tmp, 0).unwrap();
    // backward
    buffer1.mov((3,5), 2).unwrap();
    let mut tmp = buffer2.get_selection((3,5)).unwrap().to_vec();
    buffer2.delete((3,5)).unwrap();
    buffer2.insert(&mut tmp, 2 - 1).unwrap();
    assert_eq!(
      buffer1.get_selection((0, buffer1.len())),
      buffer2.get_selection((0, buffer2.len()))
    );

    // Verify the edges of moving into self
    let mut buffer = create_buffer();
    assert_eq!(
      Err(MOVE_INTO_SELF),
      buffer.mov((1,4), 2)
    );
    assert_eq!(
      Err(MOVE_INTO_SELF),
      buffer.mov((1,4), 3)
    );
    assert_eq!(
      Ok(()),
      buffer.mov((1,4), 4)
    );
    assert_eq!(
      Ok(()),
      buffer.mov((1,4), 1)
    );
  }

  #[test]
  fn copy() {
    // Compare with get_selection and insert
    let data = create_data();
    let mut buffer1 = VecBuffer::new();
    let mut buffer2 = VecBuffer::new();
    buffer1.insert(&mut data.clone(), 0).unwrap();
    buffer2.insert(&mut data.clone(), 0).unwrap();
    // copy forward
    buffer1.copy((1,3), 4).unwrap();
    let mut tmp = buffer2.get_selection((1,3)).unwrap().to_vec();
    buffer2.insert(&mut tmp, 4).unwrap();
    assert_eq!(
      buffer1.get_selection((0, buffer1.len())),
      buffer2.get_selection((0, buffer2.len()))
    );
  }

  #[test]
  fn join() {
    let mut data = create_data();
    let mut buffer = VecBuffer::new();
    buffer.insert(&mut data.clone(), 0).unwrap();
    // First join two lines together, 1 and 2
    buffer.join((1,3)).unwrap();
    let tmp = data.remove(2);
    data[1].pop(); // Get rid of the newline
    data[1].push_str(&tmp);
    assert_eq!(
      &data[..],
      buffer.get_selection((0,buffer.len())).unwrap()
    );
    // Then join the whole buffer
    buffer.join((0,buffer.len())).unwrap();
    let mut tmp = String::new();
    for line in data {
      tmp.push_str(&line[0 .. line.len() - 1]);
    }
    tmp.push('\n');
    assert_eq!(
      &tmp,
      &buffer.get_selection((0,1)).unwrap()[0]
    );
  }

  #[test]
  fn search_replace() {
    let mut data = vec!["test line\n".to_string(), "also a test line\n".to_string()];
    let mut buffer = VecBuffer::new();
    buffer.insert(&mut data.clone(), 0).unwrap();
    // Verify non-global against replacen
    buffer.search_replace(("test", "best"), (0, buffer.len()), false).unwrap();
    let line = data[0].replacen("test", "best", 1);
    data[0] = line;
    assert_eq!(
      &data[..],
      buffer.get_selection((0,buffer.len())).unwrap()
    );
    // And verify global using replace
    buffer.search_replace(("line", "string"), (0, buffer.len()), true).unwrap();
    data = data.iter().map(|line| line.replace("line", "string")).collect();
    assert_eq!(
      &data[..],
      buffer.get_selection((0,buffer.len())).unwrap()
    );
  }

  #[test]
  fn find_matching() {
    let mut data = vec![
      "test line\n".to_string(),
      "hard to write random works\n".to_string(),
      "to test over\n".to_string(),
      "None the less, it is needed\n".to_string(),
      "in this case\n".to_string()
    ];
    let mut buffer = VecBuffer::new();
    buffer.insert(&mut data, 0).unwrap();
    // Verify the return using known indices
    assert_eq!(
      vec![0,2],
      buffer.find_matching("test", (0, buffer.len())).unwrap()
    );

  }
}