Skip to content

Instantly share code, notes, and snippets.

@antony
Last active August 31, 2016 08:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save antony/4fdfc0398f46f73887de21f490185097 to your computer and use it in GitHub Desktop.
Save antony/4fdfc0398f46f73887de21f490185097 to your computer and use it in GitHub Desktop.
ChanceJS from Groovy / Java
package vendigo.support.extensions
import groovy.json.JsonOutput
import javax.script.ScriptEngine
import javax.script.ScriptEngineManager
class Chance {
private static ScriptEngine engine
static {
ScriptEngineManager factory = new ScriptEngineManager()
engine = factory.getEngineByName("nashorn")
engine.eval("""
var window = { document: {} }
var JavaMath = Java.type('java.lang.Math')
load('./node_modules/chance/dist/chance.min.js')
window.chance.random = JavaMath.random
""")
}
def methodMissing(String name, args) {
String options = args ? JsonOutput.toJson(args[0]) : ''
return engine.eval("window.chance.${name}(${options})")
}
}
@antony
Copy link
Author

antony commented Aug 29, 2016

You can now get the full feature set of ChanceJS in Groovy thanks to the joys of Metaprogramming!

For Java you will have to adapt this to define the methods you want to use.

To use:

Chance chance = new Chance()
println chance.word() // prints 'woswoswos' or similar
println chance.phone( country: 'uk', formatted: false ) // prints '01614329918' or similar

@victorquinn
Copy link

This is awesome!

Just curious, how does it deal with the dynamically-typed/statically-typed barrier from JavaScript to Groovy? Does it do type inference based on what is returned from Chance or does it just assume all responses are strings and leave it to an exercise to the user to cast them as the appropriate type or something else? (sorry I know nothing about Groovy)

@antony
Copy link
Author

antony commented Aug 29, 2016

@victorquinn I'm not 100% sure as I'm very new to the Nashorn engine, but it seems to do the same coercion as the JsonSlurper / JSONObject classes do, so it returns the equivalent groovy/java objects, which works for every case other than large numbers (which end up as things like 6.99999999999E11. What I've done in the case of numbers is taken the Groovy approach of wrapping them with BigDecimal which makes the representation sane again.

Everything else (so far) appears to be "Automagic"

@antony
Copy link
Author

antony commented Aug 31, 2016

So I found that there was no randomness at all, for some reason chance.random() doesn't generate random numbers at all.

So I've overriden chance's random number generator to use Java's builtin random number generator.

I've gone deep now, way too meta, but it works flawlessly 👯

engine.eval("""
  var window = { document: {} }
      var JavaMath = Java.type('java.lang.Math')
      ${chanceJs}
      window.chance.random = JMath.random
""")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment