(array, pred, why = 'Expected exactly one match')
| 32 | } |
| 33 | |
| 34 | function findOne (array, pred, why = 'Expected exactly one match') { |
| 35 | const matches = array.filter(pred) |
| 36 | if (matches.length === 1) { |
| 37 | return matches[0] |
| 38 | } |
| 39 | if (matches.length > 1) { |
| 40 | const nonSnippets = matches.filter(x => x[0].setupInfo?.type !== 'snippet') |
| 41 | if (nonSnippets.length === 1) { |
| 42 | // There's one main match and then some duplicative snippets, it's ok |
| 43 | return nonSnippets[0] |
| 44 | } |
| 45 | if (nonSnippets.length === 0) { |
| 46 | // There are multiple matching snippets; it's ok to just pick one |
| 47 | return matches[0] |
| 48 | } |
| 49 | if (matches.length === 2 && matches[0][0]?.type === 'junior_int' && matches[1][0]?.type === 'math_number') { |
| 50 | // We would rather pick junior_int over math_number, so it remains a dropdown |
| 51 | // But, for some reason, that just gives 0 as the value, when we need it to remain the actual value. |
| 52 | // So, let's pick the other one. TODO: figure out a way to get the dropdown to respect the number and switch this. |
| 53 | return matches[1] |
| 54 | } |
| 55 | // There are multiple matching non-snippets; maybe this is bad and we should error out? |
| 56 | console.log('Multiple block matches:', matches, '\nfrom possibilities:', array) |
| 57 | throw new Error(why + ', found ' + matches.length) |
| 58 | } |
| 59 | if (matches.length === 0) { |
| 60 | // There are no matches |
| 61 | console.log('No block matches from possibilities:', array) |
| 62 | throw new Error(why + ', found ' + matches.length) |
| 63 | } |
| 64 | } |
| 65 | class Converters { |
| 66 | static ConvertProgram (n, ctx) { |
| 67 | return { |
no test coverage detected