Skip to content

Commit

Permalink
Merge pull request #73 from reknih/master
Browse files Browse the repository at this point in the history
Add `lipsum_from_seed` and tweak capitalization.
  • Loading branch information
mgeisler authored Mar 17, 2022
2 parents 443c2de + 3f1a362 commit fbcf857
Showing 1 changed file with 58 additions and 6 deletions.
64 changes: 58 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,16 +343,27 @@ fn join_words<'a, I: Iterator<Item = &'a str>>(mut words: I) -> String {
match words.next() {
None => String::new(),
Some(word) => {
// Closure to determine whether a character ends a sentence.
let is_sentence_end = |c: char| c == '.' || c == '!' || c == '?';

let mut sentence = capitalize(word);
let mut needs_cap = sentence.ends_with(is_sentence_end);

// Add remaining words.
for word in words {
sentence.push(' ');
sentence.push_str(word);

if needs_cap {
sentence.push_str(&capitalize(word));
} else {
sentence.push_str(word);
}

needs_cap = word.ends_with(is_sentence_end);
}

// Ensure the sentence ends with either one of ".!?".
if !sentence.ends_with(|c: char| c == '.' || c == '!' || c == '?') {
if !sentence.ends_with(is_sentence_end) {
// Trim all trailing punctuation characters to avoid
// adding '.' after a ',' or similar.
let idx = sentence.trim_end_matches(is_ascii_punctuation).len();
Expand Down Expand Up @@ -417,6 +428,29 @@ pub fn lipsum(n: usize) -> String {
LOREM_IPSUM_CHAIN.with(|chain| chain.generate_from(n, ("Lorem", "ipsum")))
}

/// Generate `n` words of lorem ipsum text. The output will always start with
/// "Lorem ipsum". The seed makes the sequence deterministic.
///
/// Deterministic sequences are useful for unit tests where you need random but
/// consistent inputs or when users expect an infinitely extendable blind text
/// string that does not change.
///
/// # Examples
///
/// ```
/// use lipsum::lipsum_from_seed;
///
/// assert_eq!(lipsum_from_seed(23, 16),
/// "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim.");
/// ```
///
/// [`LOREM_IPSUM`]: constant.LOREM_IPSUM.html
/// [`lipsum`]: fn.lipsum.html
pub fn lipsum_from_seed(n: usize, seed: u64) -> String {
let rng = ChaCha20Rng::seed_from_u64(seed);
LOREM_IPSUM_CHAIN.with(|chain| chain.generate_with_rng_from(rng, n, ("Lorem", "ipsum")))
}

/// Generate `n` random words of lorem ipsum text.
///
/// The text starts with a random word from [`LOREM_IPSUM`]. Multiple
Expand All @@ -437,17 +471,20 @@ pub fn lipsum_words(n: usize) -> String {
LOREM_IPSUM_CHAIN.with(|chain| chain.generate(n))
}

/// Generate `n` random words of lorem ipsum text. The seed is used to
/// make the sequence deterministic. This is useful in unit tests
/// where you need random but consistent inputs.
/// Generate `n` random words of lorem ipsum text. The seed makes the sequence
/// deterministic.
///
/// Deterministic sequences are useful for unit tests where you need random but
/// consistent inputs or when users expect an infinitely extendable blind text
/// string that does not change.
///
/// # Examples
///
/// ```
/// use lipsum::lipsum_words_from_seed;
///
/// assert_eq!(lipsum_words_from_seed(7, 1234),
/// "Anteponant iis, quae recordamur. stulti autem malorum.");
/// "Anteponant iis, quae recordamur. Stulti autem malorum.");
/// ```
///
/// [`LOREM_IPSUM`]: constant.LOREM_IPSUM.html
Expand Down Expand Up @@ -563,6 +600,19 @@ mod tests {
}
}

#[test]
fn capitalize_after_punctiation() {
// The Markov Chain will yield a "habitut." as the second word. However,
// the following "voluptatem" is not capitalized, which does not make
// much sense, given that it appears after a full stop. The `join_words`
// must ensure that every word appearing after sentence-ending
// punctuation is capitalized.
assert_eq!(
lipsum_words_from_seed(9, 5),
"Nullam habuit. Voluptatem cum summum bonum in voluptate est."
);
}

#[test]
fn empty_chain() {
let chain = MarkovChain::new();
Expand Down Expand Up @@ -630,9 +680,11 @@ mod tests {
lipsum_words_from_seed(10, 100_000),
lipsum_words_from_seed(10, 100_000)
);
assert_eq!(lipsum_from_seed(30, 100_000), lipsum_from_seed(30, 100_000));
assert_ne!(
lipsum_words_from_seed(10, 100_000),
lipsum_words_from_seed(10, 100_001)
);
assert_ne!(lipsum_from_seed(30, 100_000), lipsum_from_seed(30, 100_001));
}
}

0 comments on commit fbcf857

Please sign in to comment.