workshopper / org

Organizing the workshopper environment.
9 stars 4 forks source link

Tool wanted: Compare stream. #8

Open martinheidegger opened 8 years ago

martinheidegger commented 8 years ago

I came to have the opinion that the important code written for the workshoppers is obfuscated by workshopper-exercise and adventure in different ways but both hang on the same issue: They try to take the work of "comparing output of executed code for you". Now I think that it would be cleanest to get a tool that would do nothing else but compare two streams and end with an error or regular message.

I imagine the API for workshoppers like this:

var submissionStream = /* ... */
if (mode === "verify") {
   var solutionStream = /* ... */
   compareStream({actual: __('{compare.actual}'), expected: __('{compare.expected}')
   }, submissionStream, solutionStream, callback)
} else {
  callback(null, submissionStream)
}

And the API for the compare should tool like this:

var options =  {
  actual: String // The title to be shown for the actual section
  expected: String // The title to be shown for the expected section
}

function callback(err, compared) {
  if (err) {
     // true if 
  }
  compared // Markdown table with the differences highlighted as ``**`` bold ``**`` 
}

var stream = compareStream(options, streamA, streamB, callback); 

The output should be

| {compare.actual} | {compare.expected} |
|---|---|
| line1 | line1 |
| *L*ine2 | *l*ine2 |
| line3 | line3 |
| **line4** | __EOF__ |

Note: If one stream has less lines than the other it should write __EOF__ to indicate that the file ended.

This could replace the way we do comparison now. Anyone up for that?

a0viedo commented 8 years ago

maybe @maxogden or @mafintosh know some tool that could apply for the use case

martinheidegger commented 8 years ago

Thinking of it: an even more abstract API might be better, since markdown rendering might be problematic if the content contains other markdown syntax.

var stream = compareStreamByLine(streamA, streamB)
var error = false
stream.on('data', function (line) {
  line // Array with the parts that are same/different:
  // ["ab", ["cd", "ef"], "12"] for the inputs "abcd12" and "abef12"

  console.log(format(line)) // Here it is possible to format the line and immediately show the output

  // We can detect problems with this little trick
  if (line.length > 0 || Array.isArray(line[0]) {
    error = true
  }
})
stream.on('error', function (errorInfo) {
  // If an error occured while reading the stream
  errorInfo.stream; // 'a' or 'b' if an error occurred null if the error occurred somewhere else
  errorInfo.err // error that occured
  error = true
})
stream.on('end', function () {
  if (error) {
    console.log('error occurred')
  }
})
martinheidegger commented 8 years ago

@denysdovhan This looks a lot like https://github.com/denysdovhan/learnyoubash/blob/master/utils/diff.js