rusty_v8 0.32.1

Rust bindings to V8
Documentation
// Tests from the same file run in a single process. That's why this test
// is in its own file, because changing the entropy source affects the
// whole process.
use rusty_v8 as v8;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering;

static CALLS: AtomicUsize = AtomicUsize::new(0);

#[test]
fn set_entropy_source() {
  const N: usize = 3;

  v8::V8::set_entropy_source(|buf| {
    CALLS.fetch_add(1, Ordering::SeqCst);
    for c in buf {
      *c = 42;
    }
    true
  });

  v8::V8::initialize_platform(v8::new_default_platform(0, false).make_shared());
  v8::V8::initialize();

  // Assumes that every isolate creates a PRNG from scratch, which is currently true.
  let mut results = vec![];
  for _ in 0..N {
    let isolate = &mut v8::Isolate::new(Default::default());
    let scope = &mut v8::HandleScope::new(isolate);
    let context = v8::Context::new(scope);
    let scope = &mut v8::ContextScope::new(scope, context);
    let source = v8::String::new(scope, "Math.random()").unwrap();
    let script = v8::Script::compile(scope, source, None).unwrap();
    let result = script.run(scope).unwrap();
    let result = result.to_string(scope).unwrap();
    let result = result.to_rust_string_lossy(scope);
    results.push(result);
  }

  unsafe {
    v8::V8::dispose();
  }
  v8::V8::shutdown_platform();

  // All runs should have produced the same value.
  assert_eq!(results.len(), N);
  results.dedup();
  assert_eq!(results.len(), 1);

  // Doesn't have to be exactly N because V8 also calls
  // the EntropySource for things like hash seeds and ASLR.
  assert!(CALLS.load(Ordering::SeqCst) >= N);
}