<commit_before>var test = require('tape')
var isFn = require('is-fn')

test('simple', function (assert) {
  var asset = require('./').context()

  assert.plan(1)

  assert.deepEqual(asset('folder'), { key: 0, type: 'folder', link: { type_1: true }, permissions: { read: { allow: ['7'] } } })
})

test('error if type is undefined', function (assert) {
  var asset = require('./').context()

  assert.plan(1)

  try {
    asset()
  } catch (error) {
    assert.ok(error, 'got an error')
  }
})

test('set asset properties', function (assert) {
  assert.plan(3)

  var expected = { key: 0, type: 'folder', name: 'Sites', link: { type_2: true }, permissions: { read: { allow: ['7'] } } }
  var tests = {
    'pass opts object': { name: 'Sites', link: 'type_2' },
    'cannot override asset type with opts.type': { type: 'nope', name: 'Sites', link: 'type_2' },
    'cannot override asset key with opts.key': { key: 10, name: 'Sites', link: 'type_2' }
  }
  var asset

  for (var test in tests) {
    asset = require('./').context()
    assert.deepEqual(asset('folder', tests[test]), expected, test)
  }
})

test('set asset permissions', function (assert) {
  var tests = {
    'default case': {
      test: function (asset) {
        return asset('folder', { name: 'Test' })
      },
      expected: { key: 0, type: 'folder', name: 'Test', link: { type_1: true }, permissions: { read: { allow: ['7'] } } }
    },
    'allow short-hand, single value': {
      test: function (asset) {
        return asset('folder', { name: 'Test', permissions: { read: '7' } })
      },
      expected: { key: 0, type: 'folder', name: 'Test', link: { type_1: true }, permissions: { read: { allow: ['7'] } } }
    },
    'allow short-hand, Array value': {
      test: function (asset) {
        return asset('folder', { name: 'Test', permissions: { read: ['7', '8'] } })
      },
      expected: { key: 0, type: 'folder', name: 'Test', link: { type_1: true }, permissions: { read: { allow: ['7', '8'] } } }
    }
  }
  var asset

  assert.plan(3)

  for (var test in tests) {
    asset = require('./').context()
    assert.deepEqual(tests[test].test(asset), tests[test].expected, test)
  }
})

test('set asset link(s)', function (assert) {
  var tests = {
    'default case': {
      test: function (asset) {
        return asset('folder', { name: 'Sites' })
      },
      expected: { key: 0, type: 'folder', name: 'Sites', link: { type_1: true }, permissions: { read: { allow: ['7'] } } }
    },
    'string case': {
      test: function (asset) {
        return asset('folder', { name: 'Sites', link: 'type_2' })
      },
      expected: { key: 0, type: 'folder', name: 'Sites', link: { type_2: true }, permissions: { read: { allow: ['7'] } } }
    },
    'array case with string': {
      test: function (asset) {
        return asset('folder', { name: 'Sites', link: [ 'type_2' ] })
      },
      expected: { key: 0, type: 'folder', name: 'Sites', link: { type_2: true }, permissions: { read: { allow: ['7'] } } }
    },
    'array case with object': {
      test: function (asset) {
        return asset('folder', { name: 'sites', link: [ { type_2: true } ] })
      },
      expected: { key: 0, type: 'folder', name: 'sites', link: { type_2: true }, permissions: { read: { allow: ['7'] } } }
    },
    'array case mixed': {
      test: function (asset) {
        return asset('folder', { name: 'sites', link: [ 'type_2', { index: 'site' } ] })
      },
      expected: { key: 0, type: 'folder', name: 'sites', link: { type_2: true, index: 'site' }, permissions: { read: { allow: ['7'] } } }
    },
    'object case': {
      test: function (asset) {
        return asset('folder', { name: 'sites', link: { type_2: true, index: 'site' } })
      },
      expected: { key: 0, type: 'folder', name: 'sites', link: { type_2: true, index: 'site' }, permissions: { read: { allow: ['7'] } } }
    }
  }
  var asset

  assert.plan(6)

  for (var test in tests) {
    asset = require('./').context()
    assert.deepEqual(tests[test].test(asset), tests[test].expected, test)
  }
})

test('create children assets', function (assert) {
  assert.plan(3)

  var assets = {
    'folder': { name: 'Sites', link: 'type_2' },
    'site': { name: 'My Site' }
  }

  var tests = {
    'processed children': {
      test: function (asset) {
        return asset('folder', assets['folder'], asset('site', assets['site']))
      },
      expected: {
        key: 1,
        type: 'folder',
        name: 'Sites',
        link: {
          type_2: true
        },
        children: [
          {
            key: 0,
            type: 'site',
            name: 'My Site',
            link: {
              type_1: true
            }, permissions: { read: { allow: ['7'] } }
          }
        ], permissions: { read: { allow: ['7'] } }
      }
    },
    'processed children as multiple arguments': {
      test: function (asset) {
        return asset('folder', assets['folder'], asset('site', assets['site']), asset('site', assets['site']))
      },
      expected: {
        key: 2,
        type: 'folder',
        name: 'Sites',
        link: {
          type_2: true
        },
        children: [
          {
            key: 0,
            type: 'site',
            name: 'My Site',
            link: {
              type_1: true
            }, permissions: { read: { allow: ['7'] } }
          },
          {
            key: 1,
            type: 'site',
            name: 'My Site',
            link: {
              type_1: true
            }, permissions: { read: { allow: ['7'] } }
          }
        ], permissions: { read: { allow: ['7'] } }
      }
    },
    'processed children as array': {
      test: function (asset) {
        return asset('folder', assets['folder'], [
          asset('site', assets['site'])
        ])
      },
      expected: {
        key: 1,
        type: 'folder',
        name: 'Sites',
        link: {
          type_2: true
        },
        children: [
          {
            key: 0,
            type: 'site',
            name: 'My Site',
            link: {
              type_1: true
            }, permissions: { read: { allow: ['7'] } }
          }
        ], permissions: { read: { allow: ['7'] } }
      }
    }
  }
  var asset

  for (var test in tests) {
    asset = require('./').context()
    assert.deepEqual(tests[test].test(asset), tests[test].expected, test)
  }
})

test('getAssetById returns selected asset', function (assert) {
  var asset = require('./').context()
  var getAssetById = asset.getAssetById

  assert.plan(12)

  var assets = {
    'folder': { name: 'Sites', link: 'type_2' },
    'site': { id: 'site', name: 'My Site' },
    'page_standard': { name: 'Home' }
  }
  var expected = {
    key: 1,
    id: 'site',
    type: 'site',
    name: 'My Site',
    link: {
      type_1: true
    }, permissions: { read: { allow: ['7'] } }
  }

  var testCallbackId = getAssetById('site')
  var testCallbackKey = getAssetById(1)

  assert.ok(isFn(testCallbackId), 'returns function if object not found via id')
  assert.notOk(testCallbackId(), 'undefined if object not found via id')

  assert.ok(isFn(testCallbackKey), 'returns function if object not found via key')
  assert.notOk(testCallbackKey(), 'undefined if object not found via key')

  asset('folder', assets['folder'], [
    asset('site', assets['site'], [
      asset('page_standard', assets['page_standard'])
    ])
  ])

  var testId = getAssetById('site')
  var testKey = getAssetById(1)

  assert.deepEqual(testCallbackId(), expected, 'callable returns correct object via id')
  assert.notOk(testCallbackId().children, 'children should be undefined')

  assert.deepEqual(testCallbackKey(), expected, 'callable returns correct object via key')
  assert.notOk(testCallbackKey().children, 'children should be undefined')

  assert.deepEqual(testId, expected, 'returns correct object via id')
  assert.notOk(testId.children, 'children should be undefined')

  assert.deepEqual(testKey, expected, 'returns correct object via key')
  assert.notOk(testKey.children, 'children should be undefined')
})

test('getAssetById inline asset definition', function (assert) {
  var asset = require('./').context()
  var getAssetById = asset.getAssetById

  assert.plan(1)

  var assets = {
    'folder': { name: 'Sites', link: 'type_2' },
    'site': { id: 'site', name: 'My Site' },
    'page_standard': { name: 'Home', link: { index: getAssetById('site') } }
  }
  var expected = {
    key: 2,
    type: 'folder',
    name: 'Sites',
    link: {
      type_2: true
    },
    children: [
      {
        key: 1,
        id: 'site',
        type: 'site',
        name: 'My Site',
        link: {
          type_1: true
        },
        children: [
          {
            key: 0,
            type: 'page_standard',
            name: 'Home',
            link: {
              type_1: true,
              index: {
                id: 'site',
                name: 'My Site',
                type: 'site',
                key: 1
              }
            },
            permissions: {
              read: {
                allow: ['7']
              }
            }
          }
        ],
        permissions: {
          read: {
            allow: ['7']
          }
        }
      }
    ],
    permissions: {
      read: {
        allow: ['7']
      }
    }
  }
  var test = asset('folder', assets['folder'], [
    asset('site', assets['site'], [
      asset('page_standard', assets['page_standard'])
    ])
  ])

  assert.deepEqual(test, expected, 'processed children')
})

test('multiple getAssetById inline definitions', function (assert) {
  var asset = require('./').context()
  var getAssetById = asset.getAssetById

  assert.plan(1)

  var assets = {
    'folder': { name: 'Sites', link: 'type_2' },
    'site': { id: 'site', name: 'My Site', link: { 'some-reverse-link': getAssetById('home') } },
    'page_standard': { id: 'home', name: 'Home', link: { index: getAssetById('site') } }
  }
  var expected = {
    key: 2,
    type: 'folder',
    name: 'Sites',
    link: {
      type_2: true
    },
    children: [
      {
        key: 1,
        id: 'site',
        type: 'site',
        name: 'My Site',
        link: {
          type_1: true,
          'some-reverse-link': {
            id: 'home',
            name: 'Home',
            type: 'page_standard',
            key: 0
          }
        },
        children: [
          {
            key: 0,
            id: 'home',
            type: 'page_standard',
            name: 'Home',
            link: {
              type_1: true,
              index: {
                id: 'site',
                name: 'My Site',
                type: 'site',
                key: 1
              }
            }, permissions: { read: { allow: ['7'] } }
          }
        ],
        permissions: {
          read: {
            allow: ['7']
          }
        }
      }
    ], permissions: {
      read: {
        allow: ['7']
      }
    }
  }
  var test = asset('folder', assets['folder'], [
    asset('site', assets['site'], [
      asset('page_standard', assets['page_standard'])
    ])
  ])

  assert.deepEqual(test, expected, 'processed children')
})

test('issue #1, getAssetById inline on asset with children', function (assert) {
  var asset = require('./').context()
  var getAssetById = asset.getAssetById

  assert.plan(1)

  var assets = {
    'folder': { name: 'Sites', link: 'type_2' },
    'site': { id: 'site', name: 'My Site' },
    'page_standard': { id: 'home', name: 'Home', link: { index: getAssetById('site') } },
    'bodycopy': { link: 'type_2', dependant: '1', exclusive: '1' },
    'bodycopy_div': { link: 'type_2', dependant: '1' },
    'content_type_wysiwyg': { id: 'test', dependant: '1', exclusive: '1' }
  }
  var expected = {
    type_1: true,
    index: {
      id: 'site',
      name: 'My Site',
      type: 'site',
      key: 4
    }
  }
  var test = asset('folder', assets['folder'], [
    asset('site', assets['site'], [
      asset('page_standard', assets['page_standard'], [
        asset('bodycopy', assets['bodycopy'], [
          asset('bodycopy_div', assets['bodycopy_div'], [
            asset('content_type_wysiwyg', assets['content_type_wysiwyg'])
          ])
        ])
      ])
    ])
  ])

  assert.deepEqual(test.children[0].children[0].link, expected, 'correct link value')
})
<commit_msg>Add additional permission tests<commit_after>var test = require('tape')
var isFn = require('is-fn')

test('simple', function (assert) {
  var asset = require('./').context()

  assert.plan(1)

  assert.deepEqual(asset('folder'), { key: 0, type: 'folder', link: { type_1: true }, permissions: { read: { allow: ['7'] } } })
})

test('error if type is undefined', function (assert) {
  var asset = require('./').context()

  assert.plan(1)

  try {
    asset()
  } catch (error) {
    assert.ok(error, 'got an error')
  }
})

test('set asset properties', function (assert) {
  assert.plan(3)

  var expected = { key: 0, type: 'folder', name: 'Sites', link: { type_2: true }, permissions: { read: { allow: ['7'] } } }
  var tests = {
    'pass opts object': { name: 'Sites', link: 'type_2' },
    'cannot override asset type with opts.type': { type: 'nope', name: 'Sites', link: 'type_2' },
    'cannot override asset key with opts.key': { key: 10, name: 'Sites', link: 'type_2' }
  }
  var asset

  for (var test in tests) {
    asset = require('./').context()
    assert.deepEqual(asset('folder', tests[test]), expected, test)
  }
})

test('set asset permissions', function (assert) {
  var tests = {
    'default case': {
      test: function (asset) {
        return asset('folder', { name: 'Test' })
      },
      expected: { key: 0, type: 'folder', name: 'Test', link: { type_1: true }, permissions: { read: { allow: ['7'] } } }
    },
    'allow short-hand, single value': {
      test: function (asset) {
        return asset('folder', { name: 'Test', permissions: { read: '7' } })
      },
      expected: { key: 0, type: 'folder', name: 'Test', link: { type_1: true }, permissions: { read: { allow: ['7'] } } }
    },
    'allow short-hand, Array value': {
      test: function (asset) {
        return asset('folder', { name: 'Test', permissions: { read: ['7', '8'] } })
      },
      expected: { key: 0, type: 'folder', name: 'Test', link: { type_1: true }, permissions: { read: { allow: ['7', '8'] } } }
    },
    'explicit allow/deny as Object': {
      test: function (asset) {
        return asset('folder', { name: 'Test', permissions: { read: { allow: ['7', '8'], deny: '9' } } })
      },
      expected: { key: 0, type: 'folder', name: 'Test', link: { type_1: true }, permissions: { read: { allow: ['7', '8'], deny: ['9'] } } }
    },
    'cannot set allow and deny on the same value': {
      test: function (asset) {
        return asset('folder', { name: 'Test', permissions: { read: { allow: '7', deny: '7' } } })
      },
      expected: { key: 0, type: 'folder', name: 'Test', link: { type_1: true }, permissions: { read: { allow: ['7'] } } }
    }
  }
  var asset

  assert.plan(4)

  for (var test in tests) {
    asset = require('./').context()
    assert.deepEqual(tests[test].test(asset), tests[test].expected, test)
  }
})

test('set asset link(s)', function (assert) {
  var tests = {
    'default case': {
      test: function (asset) {
        return asset('folder', { name: 'Sites' })
      },
      expected: { key: 0, type: 'folder', name: 'Sites', link: { type_1: true }, permissions: { read: { allow: ['7'] } } }
    },
    'string case': {
      test: function (asset) {
        return asset('folder', { name: 'Sites', link: 'type_2' })
      },
      expected: { key: 0, type: 'folder', name: 'Sites', link: { type_2: true }, permissions: { read: { allow: ['7'] } } }
    },
    'array case with string': {
      test: function (asset) {
        return asset('folder', { name: 'Sites', link: [ 'type_2' ] })
      },
      expected: { key: 0, type: 'folder', name: 'Sites', link: { type_2: true }, permissions: { read: { allow: ['7'] } } }
    },
    'array case with object': {
      test: function (asset) {
        return asset('folder', { name: 'sites', link: [ { type_2: true } ] })
      },
      expected: { key: 0, type: 'folder', name: 'sites', link: { type_2: true }, permissions: { read: { allow: ['7'] } } }
    },
    'array case mixed': {
      test: function (asset) {
        return asset('folder', { name: 'sites', link: [ 'type_2', { index: 'site' } ] })
      },
      expected: { key: 0, type: 'folder', name: 'sites', link: { type_2: true, index: 'site' }, permissions: { read: { allow: ['7'] } } }
    },
    'object case': {
      test: function (asset) {
        return asset('folder', { name: 'sites', link: { type_2: true, index: 'site' } })
      },
      expected: { key: 0, type: 'folder', name: 'sites', link: { type_2: true, index: 'site' }, permissions: { read: { allow: ['7'] } } }
    }
  }
  var asset

  assert.plan(6)

  for (var test in tests) {
    asset = require('./').context()
    assert.deepEqual(tests[test].test(asset), tests[test].expected, test)
  }
})

test('create children assets', function (assert) {
  assert.plan(3)

  var assets = {
    'folder': { name: 'Sites', link: 'type_2' },
    'site': { name: 'My Site' }
  }

  var tests = {
    'processed children': {
      test: function (asset) {
        return asset('folder', assets['folder'], asset('site', assets['site']))
      },
      expected: {
        key: 1,
        type: 'folder',
        name: 'Sites',
        link: {
          type_2: true
        },
        children: [
          {
            key: 0,
            type: 'site',
            name: 'My Site',
            link: {
              type_1: true
            }, permissions: { read: { allow: ['7'] } }
          }
        ], permissions: { read: { allow: ['7'] } }
      }
    },
    'processed children as multiple arguments': {
      test: function (asset) {
        return asset('folder', assets['folder'], asset('site', assets['site']), asset('site', assets['site']))
      },
      expected: {
        key: 2,
        type: 'folder',
        name: 'Sites',
        link: {
          type_2: true
        },
        children: [
          {
            key: 0,
            type: 'site',
            name: 'My Site',
            link: {
              type_1: true
            }, permissions: { read: { allow: ['7'] } }
          },
          {
            key: 1,
            type: 'site',
            name: 'My Site',
            link: {
              type_1: true
            }, permissions: { read: { allow: ['7'] } }
          }
        ], permissions: { read: { allow: ['7'] } }
      }
    },
    'processed children as array': {
      test: function (asset) {
        return asset('folder', assets['folder'], [
          asset('site', assets['site'])
        ])
      },
      expected: {
        key: 1,
        type: 'folder',
        name: 'Sites',
        link: {
          type_2: true
        },
        children: [
          {
            key: 0,
            type: 'site',
            name: 'My Site',
            link: {
              type_1: true
            }, permissions: { read: { allow: ['7'] } }
          }
        ], permissions: { read: { allow: ['7'] } }
      }
    }
  }
  var asset

  for (var test in tests) {
    asset = require('./').context()
    assert.deepEqual(tests[test].test(asset), tests[test].expected, test)
  }
})

test('getAssetById returns selected asset', function (assert) {
  var asset = require('./').context()
  var getAssetById = asset.getAssetById

  assert.plan(12)

  var assets = {
    'folder': { name: 'Sites', link: 'type_2' },
    'site': { id: 'site', name: 'My Site' },
    'page_standard': { name: 'Home' }
  }
  var expected = {
    key: 1,
    id: 'site',
    type: 'site',
    name: 'My Site',
    link: {
      type_1: true
    }, permissions: { read: { allow: ['7'] } }
  }

  var testCallbackId = getAssetById('site')
  var testCallbackKey = getAssetById(1)

  assert.ok(isFn(testCallbackId), 'returns function if object not found via id')
  assert.notOk(testCallbackId(), 'undefined if object not found via id')

  assert.ok(isFn(testCallbackKey), 'returns function if object not found via key')
  assert.notOk(testCallbackKey(), 'undefined if object not found via key')

  asset('folder', assets['folder'], [
    asset('site', assets['site'], [
      asset('page_standard', assets['page_standard'])
    ])
  ])

  var testId = getAssetById('site')
  var testKey = getAssetById(1)

  assert.deepEqual(testCallbackId(), expected, 'callable returns correct object via id')
  assert.notOk(testCallbackId().children, 'children should be undefined')

  assert.deepEqual(testCallbackKey(), expected, 'callable returns correct object via key')
  assert.notOk(testCallbackKey().children, 'children should be undefined')

  assert.deepEqual(testId, expected, 'returns correct object via id')
  assert.notOk(testId.children, 'children should be undefined')

  assert.deepEqual(testKey, expected, 'returns correct object via key')
  assert.notOk(testKey.children, 'children should be undefined')
})

test('getAssetById inline asset definition', function (assert) {
  var asset = require('./').context()
  var getAssetById = asset.getAssetById

  assert.plan(1)

  var assets = {
    'folder': { name: 'Sites', link: 'type_2' },
    'site': { id: 'site', name: 'My Site' },
    'page_standard': { name: 'Home', link: { index: getAssetById('site') } }
  }
  var expected = {
    key: 2,
    type: 'folder',
    name: 'Sites',
    link: {
      type_2: true
    },
    children: [
      {
        key: 1,
        id: 'site',
        type: 'site',
        name: 'My Site',
        link: {
          type_1: true
        },
        children: [
          {
            key: 0,
            type: 'page_standard',
            name: 'Home',
            link: {
              type_1: true,
              index: {
                id: 'site',
                name: 'My Site',
                type: 'site',
                key: 1
              }
            },
            permissions: {
              read: {
                allow: ['7']
              }
            }
          }
        ],
        permissions: {
          read: {
            allow: ['7']
          }
        }
      }
    ],
    permissions: {
      read: {
        allow: ['7']
      }
    }
  }
  var test = asset('folder', assets['folder'], [
    asset('site', assets['site'], [
      asset('page_standard', assets['page_standard'])
    ])
  ])

  assert.deepEqual(test, expected, 'processed children')
})

test('multiple getAssetById inline definitions', function (assert) {
  var asset = require('./').context()
  var getAssetById = asset.getAssetById

  assert.plan(1)

  var assets = {
    'folder': { name: 'Sites', link: 'type_2' },
    'site': { id: 'site', name: 'My Site', link: { 'some-reverse-link': getAssetById('home') } },
    'page_standard': { id: 'home', name: 'Home', link: { index: getAssetById('site') } }
  }
  var expected = {
    key: 2,
    type: 'folder',
    name: 'Sites',
    link: {
      type_2: true
    },
    children: [
      {
        key: 1,
        id: 'site',
        type: 'site',
        name: 'My Site',
        link: {
          type_1: true,
          'some-reverse-link': {
            id: 'home',
            name: 'Home',
            type: 'page_standard',
            key: 0
          }
        },
        children: [
          {
            key: 0,
            id: 'home',
            type: 'page_standard',
            name: 'Home',
            link: {
              type_1: true,
              index: {
                id: 'site',
                name: 'My Site',
                type: 'site',
                key: 1
              }
            }, permissions: { read: { allow: ['7'] } }
          }
        ],
        permissions: {
          read: {
            allow: ['7']
          }
        }
      }
    ], permissions: {
      read: {
        allow: ['7']
      }
    }
  }
  var test = asset('folder', assets['folder'], [
    asset('site', assets['site'], [
      asset('page_standard', assets['page_standard'])
    ])
  ])

  assert.deepEqual(test, expected, 'processed children')
})

test('issue #1, getAssetById inline on asset with children', function (assert) {
  var asset = require('./').context()
  var getAssetById = asset.getAssetById

  assert.plan(1)

  var assets = {
    'folder': { name: 'Sites', link: 'type_2' },
    'site': { id: 'site', name: 'My Site' },
    'page_standard': { id: 'home', name: 'Home', link: { index: getAssetById('site') } },
    'bodycopy': { link: 'type_2', dependant: '1', exclusive: '1' },
    'bodycopy_div': { link: 'type_2', dependant: '1' },
    'content_type_wysiwyg': { id: 'test', dependant: '1', exclusive: '1' }
  }
  var expected = {
    type_1: true,
    index: {
      id: 'site',
      name: 'My Site',
      type: 'site',
      key: 4
    }
  }
  var test = asset('folder', assets['folder'], [
    asset('site', assets['site'], [
      asset('page_standard', assets['page_standard'], [
        asset('bodycopy', assets['bodycopy'], [
          asset('bodycopy_div', assets['bodycopy_div'], [
            asset('content_type_wysiwyg', assets['content_type_wysiwyg'])
          ])
        ])
      ])
    ])
  ])

  assert.deepEqual(test.children[0].children[0].link, expected, 'correct link value')
})
<|endoftext|>


<commit_before>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length > 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<commit_msg>🤖(break): 2017-7-24 00:43:21<commit_after>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length < 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<|endoftext|>


<commit_before>var expect = require("chai").expect,
    ChiasmDataset = require("./index"),
    strings = ChiasmDataset.strings,
    errorMessage = ChiasmDataset.errorMessage;

function reject(options, done, printErr){
  ChiasmDataset.validate(options.dataset)
    .then(function (){}, function (err) {

      if(printErr){
        console.log(err.message);
        console.log(err.stack);
      }

      expect(err.message)
        .to
        .equal(errorMessage(options.errorId, options.errorParams));
      done();
    });
}

describe("chiasm-dataset", function () {

  it("`data` property exists.", function(done) {
    ChiasmDataset.validate({}).then(function (){}, function (err) {

      // Here's how you can see a stack trace for debugging.
      //console.log(err.stack);

      expect(err).to.exist;
      expect(err.message).to.equal(strings.data_missing);
      done();
    });
  });

  it("`data` property is an array of objects (reject string).", function(done) {
    ChiasmDataset.validate({
      data: "foo"
    }).then(function (){}, function (err) {
      expect(err).to.exist;
      expect(err.message).to.equal(errorMessage("data_not_array", {
        type: "string"
      }));
      done();
    });
  });

  it("`data` property is an array of objects (reject string) using reject function.", function(done) {
    reject({
      dataset: { data: "foo" },
      errorId: "data_not_array",
      errorParams: { "type": "string" }
    }, done);
  });

  it("`data` property is an array of objects (reject number).", function(done) {
    reject({
      dataset: { data: 5 },
      errorId: "data_not_array",
      errorParams: { "type": "number" }
    }, done);
  });

  it("`data` property is an array of objects (reject string array).", function(done) {
    reject({
      dataset: { data: ["foo", "bar"] },
      errorId: "data_not_array_of_objects",
      errorParams: { type: "string" }
    }, done);
  });

  it("`data` property is an array of objects (reject number array).", function(done) {
    reject({
      dataset: { data: [1, 2, 3] },
      errorId: "data_not_array_of_objects",
      errorParams: { type: "number" }
    }, done);
  });

  it("`data` property is an array of objects (inspect all elements).", function(done) {
    reject({
      dataset: { data: [{ x: 5 }, { x: 6 }, 3] },
      errorId: "data_not_array_of_objects",
      errorParams: { type: "number" }
    }, done);
  });

  it("`metadata` property exists.", function(done) {
    reject({
      dataset: { data: [
        { name: "Joe" },
        { name: "Jane" }
      ] },
      errorId: "metadata_missing"
    }, done);
  });

  it("`metadata` property is an object (reject string).", function(done) {
    reject({
      dataset: {
        data: [
          { name: "Joe" },
          { name: "Jane" }
        ],
        metadata: "yo mama"
      },
      errorId: "metadata_not_object",
      errorParams: { type: "string" }
    }, done);
  });

  it("`metadata` property is an object (reject number).", function(done) {
    reject({
      dataset: {
        data: [
          { name: "Joe" },
          { name: "Jane" }
        ],
        metadata: 5000
      },
      errorId: "metadata_not_object",
      errorParams: { type: "number" }
    }, done);
  });

  it("`metadata.columns` property exists.", function(done) {
    reject({
      dataset: {
        data: [
          { name: "Joe" },
          { name: "Jane" }
        ],
        metadata: {}
      },
      errorId: "metadata_missing_columns"
    }, done);
  });

  it("`metadata.columns` must be an array (reject string).", function(done) {
    reject({
      dataset: {
        data: [
          { name: "Joe" },
          { name: "Jane" }
        ],
        metadata: {
          columns: "foo"
        }
      },
      errorId: "metadata_columns_not_array",
      errorParams: {
        type: "string"
      }
    }, done);
  });

  it("`metadata.columns` must be an array (reject number).", function(done) {
    reject({
      dataset: {
        data: [
          { name: "Joe" },
          { name: "Jane" }
        ],
        metadata: {
          columns: 5
        }
      },
      errorId: "metadata_columns_not_array",
      errorParams: {
        type: "number"
      }
    }, done);
  });

  it("`metadata.columns` must be an array of objects (reject number).", function(done) {
    reject({
      dataset: {
        data: [
          { name: "Joe" },
          { name: "Jane" }
        ],
        metadata: {
          columns: [5]
        }
      },
      errorId: "metadata_columns_not_array_of_objects",
      errorParams: {
        type: "number"
      }
    }, done);
  });

  it("`metadata.columns` must be an array of objects (reject string).", function(done) {
    reject({
      dataset: {
        data: [
          { name: "Joe" },
          { name: "Jane" }
        ],
        metadata: {
          columns: ["foo"]
        }
      },
      errorId: "metadata_columns_not_array_of_objects",
      errorParams: {
        type: "string"
      }
    }, done);
  });

  it("`metadata.columns` must be an array of objects (inspect all entries).", function(done) {
    reject({
      dataset: {
        data: [
          { name: "Joe" },
          { name: "Jane" }
        ],
        metadata: {
          columns: [{}, {}, 5]
        }
      },
      errorId: "metadata_columns_not_array_of_objects",
      errorParams: {
        type: "number"
      }
    }, done);
  });

  it("`metadata.columns` entries must have a 'name' property.", function(done) {
    reject({
      dataset: {
        data: [{},{}],
        metadata: {
          columns: [{}]
        }
      },
      errorId: "metadata_columns_name_missing"
    }, done);
  });
  it("`metadata.columns` entries must have a 'name' property that is a string (reject number).", function(done) {
    reject({
      dataset: {
        data: [{},{}],
        metadata: {
          columns: [{ name: 22 }]
        }
      },
      errorId: "metadata_columns_name_not_string"
    }, done);
  });
  it("`metadata.columns` entries must have a 'name' property that is a string (reject object).", function(done) {
    reject({
      dataset: {
        data: [{},{}],
        metadata: {
          columns: [{ name: { total: "crap" } }]
        }
      },
      errorId: "metadata_columns_name_not_string"
    }, done);
  });

  it("`metadata.columns` entries must have a 'type' property.", function(done) {
    reject({
      dataset: {
        data: [{ x: 5 }, { x: 10}],
        metadata: {
          columns: [{
            name: "x"
          }]
        }
      },
      errorId: "metadata_columns_type_missing",
      errorParams: {
        column: "x"
      }
    }, done);
  });

  it("`metadata.columns` entries must have a 'type' property (inspect all entries).", function(done) {
    reject({
      dataset: {
        data: [{ x: 5, y:10 }],
        metadata: {
          columns: [
            { name: "x", type: "number" },
            { name: "y" }
          ]
        }
      },
      errorId: "metadata_columns_type_missing",
      errorParams: {
        column: "y"
      }
    }, done);
  });

  it("`metadata.columns` entries must have a 'type' property that is a valid value.", function(done) {
    reject({
      dataset: {
        data: [{ x: 5, y:10 }],
        metadata: {
          columns: [
            { name: "x", type: "number" },
            { name: "y", type: "invalid foo" }
          ]
        }
      },
      errorId: "metadata_columns_type_not_valid",
      errorParams: { column: "y" }
    }, done);
  });

 //TODO
 //each column descriptor object has a "type" field
 //each column descriptor object has a "type" field whose value is "number", "string", or "date"

  it("All columns present in the data are also present in the metadata.", function(done) {
    reject({
      dataset: {
        data: [
          { name: "Joe" },
          { name: "Jane" }
        ],
        metadata: {
          columns: []
        }
      },
      errorId: "column_in_data_not_metadata",
      errorParams: { column: "name" }
    }, done);
  });

  it("All columns present in the metadata are also present in the data.", function(done) {
    reject({
      dataset: {
        data: [
          { name: "Joe" },
          { name: "Jane" }
        ],
        metadata: {
          columns: [
            { name: "name", type: "string" },
            { name: "foo", type: "string" }
          ]
        }
      },
      errorId: "column_in_metadata_not_data",
      errorParams: { column: "foo" }
    }, done);
  });

//  it("Types in data must match types in metadata (reject string in data != number in metadata).", function(done) {
//    reject({
//      dataset: {
//        data: [
//          { name: "Joe" },
//          { name: "Jane" }
//        ],
//        metadata: {
//          columns: [
//            { name: "name", type: "number" }
//          ]
//        }
//      }
//      errorId: "column_type_mismatch",
//      errorParams: {
//        column: "name",
//        value: "Joe",
//        typeInData: "string",
//        typeInMetadata: "number"
//      }
//    }, done);
//  });

//  it("Types in data must match types in metadata (reject number in data != string in metadata).", function(done) {
//    reject({
//      dataset: {
//        data: [
//          { name: 5 },
//          { name: 6 }
//        ],
//        metadata: {
//          columns: [
//            { name: "name", type: "string" }
//          ]
//        }
//      }
//      errorId: "column_type_mismatch",
//      errorParams: {
//        column: "name",
//        value: 5,
//        typeInData: "number",
//        typeInMetadata: "string"
//      }
//    }, done);
//  });

  it("should pass validation for a valid dataset.", function(done) {
    ChiasmDataset.validate({
      data: [
        { name: "Joe" },
        { name: "Jane" }
      ],
      metadata: {
        columns: [
          { name: "name", type: "string" }
        ]
      }
    }).then(done);
  });
});
<commit_msg>Clean up tests, make type check more thorough<commit_after>var expect = require("chai").expect,
    ChiasmDataset = require("./index"),
    strings = ChiasmDataset.strings,
    errorMessage = ChiasmDataset.errorMessage;

function reject(options, done, printErr){
  ChiasmDataset.validate(options.dataset)
    .then(function (){}, function (err) {

      if(printErr){
        console.log(err.message);
        console.log(err.stack);
      }

      expect(err.message)
        .to
        .equal(errorMessage(options.errorId, options.errorParams));
      done();
    });
}

describe("chiasm-dataset", function () {

  it("`data` property exists.", function(done) {
    ChiasmDataset.validate({}).then(function (){}, function (err) {

      // Here's how you can see a stack trace for debugging.
      //console.log(err.stack);

      expect(err).to.exist;
      expect(err.message).to.equal(strings.data_missing);
      done();
    });
  });

  it("`data` property is an array of objects (reject string).", function(done) {
    ChiasmDataset.validate({
      data: "foo"
    }).then(function (){}, function (err) {
      expect(err).to.exist;
      expect(err.message).to.equal(errorMessage("data_not_array", {
        type: "string"
      }));
      done();
    });
  });

  it("`data` property is an array of objects (reject string) using reject function.", function(done) {
    reject({
      dataset: { data: "foo" },
      errorId: "data_not_array",
      errorParams: { "type": "string" }
    }, done);
  });

  it("`data` property is an array of objects (reject number).", function(done) {
    reject({
      dataset: { data: 5 },
      errorId: "data_not_array",
      errorParams: { "type": "number" }
    }, done);
  });

  it("`data` property is an array of objects (reject string array).", function(done) {
    reject({
      dataset: { data: ["foo", "bar"] },
      errorId: "data_not_array_of_objects",
      errorParams: { type: "string" }
    }, done);
  });

  it("`data` property is an array of objects (reject number array).", function(done) {
    reject({
      dataset: { data: [1, 2, 3] },
      errorId: "data_not_array_of_objects",
      errorParams: { type: "number" }
    }, done);
  });

  it("`data` property is an array of objects (inspect all elements).", function(done) {
    reject({
      dataset: { data: [{ x: 5 }, { x: 6 }, 3] },
      errorId: "data_not_array_of_objects",
      errorParams: { type: "number" }
    }, done);
  });

  it("`metadata` property exists.", function(done) {
    reject({
      dataset: { data: [
        { name: "Joe" },
        { name: "Jane" }
      ] },
      errorId: "metadata_missing"
    }, done);
  });

  it("`metadata` property is an object (reject string).", function(done) {
    reject({
      dataset: {
        data: [
          { name: "Joe" },
          { name: "Jane" }
        ],
        metadata: "yo mama"
      },
      errorId: "metadata_not_object",
      errorParams: { type: "string" }
    }, done);
  });

  it("`metadata` property is an object (reject number).", function(done) {
    reject({
      dataset: {
        data: [
          { name: "Joe" },
          { name: "Jane" }
        ],
        metadata: 5000
      },
      errorId: "metadata_not_object",
      errorParams: { type: "number" }
    }, done);
  });

  it("`metadata.columns` property exists.", function(done) {
    reject({
      dataset: {
        data: [
          { name: "Joe" },
          { name: "Jane" }
        ],
        metadata: {}
      },
      errorId: "metadata_missing_columns"
    }, done);
  });

  it("`metadata.columns` must be an array (reject string).", function(done) {
    reject({
      dataset: {
        data: [
          { name: "Joe" },
          { name: "Jane" }
        ],
        metadata: {
          columns: "foo"
        }
      },
      errorId: "metadata_columns_not_array",
      errorParams: {
        type: "string"
      }
    }, done);
  });

  it("`metadata.columns` must be an array (reject number).", function(done) {
    reject({
      dataset: {
        data: [
          { name: "Joe" },
          { name: "Jane" }
        ],
        metadata: {
          columns: 5
        }
      },
      errorId: "metadata_columns_not_array",
      errorParams: {
        type: "number"
      }
    }, done);
  });

  it("`metadata.columns` must be an array of objects (reject number).", function(done) {
    reject({
      dataset: {
        data: [
          { name: "Joe" },
          { name: "Jane" }
        ],
        metadata: {
          columns: [5]
        }
      },
      errorId: "metadata_columns_not_array_of_objects",
      errorParams: {
        type: "number"
      }
    }, done);
  });

  it("`metadata.columns` must be an array of objects (reject string).", function(done) {
    reject({
      dataset: {
        data: [
          { name: "Joe" },
          { name: "Jane" }
        ],
        metadata: {
          columns: ["foo"]
        }
      },
      errorId: "metadata_columns_not_array_of_objects",
      errorParams: {
        type: "string"
      }
    }, done);
  });

  it("`metadata.columns` must be an array of objects (inspect all entries).", function(done) {
    reject({
      dataset: {
        data: [
          { name: "Joe" },
          { name: "Jane" }
        ],
        metadata: {
          columns: [{}, {}, 5]
        }
      },
      errorId: "metadata_columns_not_array_of_objects",
      errorParams: {
        type: "number"
      }
    }, done);
  });

  it("`metadata.columns` entries must have a 'name' property.", function(done) {
    reject({
      dataset: {
        data: [{},{}],
        metadata: {
          columns: [{}]
        }
      },
      errorId: "metadata_columns_name_missing"
    }, done);
  });
  it("`metadata.columns` entries must have a 'name' property that is a string (reject number).", function(done) {
    reject({
      dataset: {
        data: [{},{}],
        metadata: {
          columns: [{ name: 22 }]
        }
      },
      errorId: "metadata_columns_name_not_string"
    }, done);
  });
  it("`metadata.columns` entries must have a 'name' property that is a string (reject object).", function(done) {
    reject({
      dataset: {
        data: [{},{}],
        metadata: {
          columns: [{ name: { total: "crap" } }]
        }
      },
      errorId: "metadata_columns_name_not_string"
    }, done);
  });

  it("`metadata.columns` entries must have a 'type' property.", function(done) {
    reject({
      dataset: {
        data: [{ x: 5 }, { x: 10}],
        metadata: {
          columns: [{
            name: "x"
          }]
        }
      },
      errorId: "metadata_columns_type_missing",
      errorParams: {
        column: "x"
      }
    }, done);
  });

  it("`metadata.columns` entries must have a 'type' property (inspect all entries).", function(done) {
    reject({
      dataset: {
        data: [{ x: 5, y:10 }],
        metadata: {
          columns: [
            { name: "x", type: "number" },
            { name: "y" }
          ]
        }
      },
      errorId: "metadata_columns_type_missing",
      errorParams: {
        column: "y"
      }
    }, done);
  });

  it("`metadata.columns` entries must have a 'type' property that is a valid value.", function(done) {
    reject({
      dataset: {
        data: [{ x: 5, y:"str", z: new Date(), foo: { not: "allowed"} }],
        metadata: {
          columns: [
            { name: "x", type: "number" },
            { name: "y", type: "string" },
            { name: "z", type: "date" },
            { name: "foo", type: "invalid" }
          ]
        }
      },
      errorId: "metadata_columns_type_not_valid",
      errorParams: { column: "foo" }
    }, done);
  });

  it("All columns present in the data are also present in the metadata.", function(done) {
    reject({
      dataset: {
        data: [
          { name: "Joe" },
          { name: "Jane" }
        ],
        metadata: {
          columns: []
        }
      },
      errorId: "column_in_data_not_metadata",
      errorParams: { column: "name" }
    }, done);
  });

  it("All columns present in the metadata are also present in the data.", function(done) {
    reject({
      dataset: {
        data: [
          { name: "Joe" },
          { name: "Jane" }
        ],
        metadata: {
          columns: [
            { name: "name", type: "string" },
            { name: "foo", type: "string" }
          ]
        }
      },
      errorId: "column_in_metadata_not_data",
      errorParams: { column: "foo" }
    }, done);
  });

//  it("Types in data must match types in metadata (reject string in data != number in metadata).", function(done) {
//    reject({
//      dataset: {
//        data: [
//          { name: "Joe" },
//          { name: "Jane" }
//        ],
//        metadata: {
//          columns: [
//            { name: "name", type: "number" }
//          ]
//        }
//      }
//      errorId: "column_type_mismatch",
//      errorParams: {
//        column: "name",
//        value: "Joe",
//        typeInData: "string",
//        typeInMetadata: "number"
//      }
//    }, done);
//  });

//  it("Types in data must match types in metadata (reject number in data != string in metadata).", function(done) {
//    reject({
//      dataset: {
//        data: [
//          { name: 5 },
//          { name: 6 }
//        ],
//        metadata: {
//          columns: [
//            { name: "name", type: "string" }
//          ]
//        }
//      }
//      errorId: "column_type_mismatch",
//      errorParams: {
//        column: "name",
//        value: 5,
//        typeInData: "number",
//        typeInMetadata: "string"
//      }
//    }, done);
//  });

  it("should pass validation for a valid dataset.", function(done) {
    ChiasmDataset.validate({
      data: [
        { name: "Joe" },
        { name: "Jane" }
      ],
      metadata: {
        columns: [
          { name: "name", type: "string" }
        ]
      }
    }).then(done);
  });
});
<|endoftext|>


<commit_before>const test = require('tape');
const strip = require('strip-ansi');
const flamongo = require('./lib/tester');

test('flamongo', function (t) {
  t.plan(1);

  const schema = {
    name: {
      first: 'first',
      last: 'last',
    },
    vegan: 'bool',
    happy: {
      _type: 'bool',
      args: { likelihood: 10 },
    },
    birthday: 'date',
    jobTitle: {
      _type: 'enum',
      options: ['software developer', 'football player'],
    },
    friends: [{
      name: {
        first: 'first',
        last: 'last',
      },
    }],
  };

  const indexKeys = [{ 'name.first': 1 }, { birthday: 1 }];
  const queries = [{'name.first': 'Richard'}, { 'name.first': 'John', vegan: false, 'name.last': { $nin: ['Smith'] } }];

  flamongo(indexKeys, queries, schema, { verbose: false, preserveData: false })
    .then((queryResults) => {
      const indexUseRegex = /.*Examined [\d]+ keys on index name.first_1 in a forward direction.*/;
      t.ok(indexUseRegex.test(strip(queryResults[1].output)));
      t.end();
    });
});
<commit_msg>spacing<commit_after>const test = require('tape');
const strip = require('strip-ansi');
const flamongo = require('./lib/tester');

test('flamongo', function (t) {
  t.plan(1);

  const schema = {
    name: {
      first: 'first',
      last: 'last',
    },
    vegan: 'bool',
    happy: {
      _type: 'bool',
      args: { likelihood: 10 },
    },
    birthday: 'date',
    jobTitle: {
      _type: 'enum',
      options: ['software developer', 'football player'],
    },
    friends: [{
      name: {
        first: 'first',
        last: 'last',
      },
    }],
  };

  const indexKeys = [
    { 'name.first': 1 },
    { birthday: 1 }
  ];

  const queries = [
    {'name.first': 'Richard'},
    { 'name.first': 'John', vegan: false, 'name.last': { $nin: ['Smith'] } }
  ];

  flamongo(indexKeys, queries, schema, { verbose: false, preserveData: false })
    .then((queryResults) => {
      const indexUseRegex = /.*Examined [\d]+ keys on index name.first_1 in a forward direction.*/;
      t.ok(indexUseRegex.test(strip(queryResults[1].output)));
      t.end();
    });
});
<|endoftext|>


<commit_before>import { filter, find, includes, findIndex, reduce, isNil } from 'lodash';
import { computed, observable, action } from 'mobx';
import {
  BaseModel, identifiedBy, belongsTo, hasMany, session, identifier, field,
} from 'shared/model';
import { TimeStore } from '../../../flux/time';

@identifiedBy('course/scores/task-result')
export default class TaskResult extends BaseModel {
  @identifier id;
  @field type;
  @field status;
  @field score;
  @field step_count;
  @field completed_step_count;
  @field completed_accepted_late_exercise_count;
  @field completed_accepted_late_step_count;
  @field completed_exercise_count;
  @field completed_on_time_exercise_count;
  @field completed_on_time_step_count;
  @field completed_step_count;
  @field correct_accepted_late_exercise_count
  @field correct_exercise_count
  @field correct_on_time_exercise_count
  @field({ type: 'date' }) due_at;
  @field exercise_count;
  @field is_included_in_averages;
  @field is_late_work_accepted;
  @field recovered_exercise_count;

  @belongsTo({ model: 'course/scores/student' }) student;

  @computed get columnIndex() {
    return findIndex(this.student.data, s => s === this);
  }

  @computed get lateStepCount() {
    if (this.type === 'homework') {
      return this.completed_exercise_count -
             this.completed_on_time_exercise_count -
             this.completed_accepted_late_exercise_count;
    }
    return this.completed_step_count -
           this.completed_on_time_step_count -
           this.completed_accepted_late_step_count;
  }

  @computed get hasLateWork() {
    return this.lateStepCount > 0;
  }

  @computed get isLate() {
    return this.completed_on_time_step_count < this.completed_step_count;
  }

  @computed get isStarted() {
    return Boolean(this.completed_step_count || this.completed_exercise_count);
  }

  @computed get reportHeading() {
    return this.student.period.data_headings[this.columnIndex];
  }

  // called by API
  acceptLate() {}
  rejectLate() {}

  onLateWorkRejected() {
    const prevLateSteps = this.completed_accepted_late_step_count;
    const prevCorrect = this.correct_accepted_late_exercise_count;

    this.is_late_work_accepted = false;
    this.completed_accepted_late_exercise_count = 0;
    this.correct_accepted_late_exercise_count = 0;
    this.completed_accepted_late_step_count = 0;
    this.accepted_late_at = null;

    if (this.is_included_in_averages) {
      this.adjustAverages(
        prevLateSteps + this.completed_on_time_step_count,
        prevCorrect + this.correct_on_time_exercise_count,
      );
    }
  }

  onLateWorkAccepted() {
    // nothing to do if it's not actually late
    if (!this.hasLateWork) { return; }

    const prevLateSteps = this.completed_accepted_late_step_count;
    const prevCorrect = this.correct_accepted_late_exercise_count;

    this.is_late_work_accepted = true;
    this.completed_accepted_late_exercise_count =
      this.completed_exercise_count - this.completed_on_time_exercise_count;
    this.correct_accepted_late_exercise_count =
      this.correct_exercise_count - this.correct_on_time_exercise_count;
    this.completed_accepted_late_step_count =
      this.completed_step_count - this.completed_on_time_step_count;
    this.accepted_late_at = TimeStore.getNow().toISOString();

    if (this.is_included_in_averages) {
      this.adjustAverages(
        prevLateSteps + this.completed_on_time_step_count,
        prevCorrect + this.correct_on_time_exercise_count,
      );
    }
  }

  @computed get completedStepCount() {
    return this.completed_accepted_late_step_count + this.completed_on_time_step_count;
  }

  @computed get scoredStepCount() {
    return this.completed_on_time_exercise_count + this.completed_accepted_late_exercise_count;
  }

  @computed get scoredCorrectCount() {
    return this.correct_on_time_exercise_count + this.correct_accepted_late_exercise_count;
  }

  adjustAverages(prevCompletedStepCount, prevCorrect) {
    const oldScore = this.score;
    const period = this.student.period;
    const { course } = period.coursePeriod;
    const { type } = this;
    let student = this.student;

    // Update score for the task without rounding so the calculations below will use it's full precision
    this.score = (
      this.correct_on_time_exercise_count + this.correct_accepted_late_exercise_count
    ) / this.exercise_count;

    //----------------------------------------------------------------+
    // scores                                                         |
    //----------------------------------------------------------------+

    // student
    student[`${type}_score`] += (
      this.scoredCorrectCount / student.scoredStepCount[type]
    ) - ( prevCorrect / student.scoredStepCount[type] );
    // assignment
    this.reportHeading.average_score += (
      this.scoredCorrectCount / this.reportHeading.scoredStepCount
    ) - ( prevCorrect / this.reportHeading.scoredStepCount );
    // period
    period[`overall_${type}_score`] += course[`${type}_score_weight`] * (
      ( this.scoredCorrectCount / period.scoredStepCount[type] ) -
        ( prevCorrect / period.scoredStepCount[type] )
    );

    //----------------------------------------------------------------+
    // progress                                                       |
    //----------------------------------------------------------------+

    // student
    student[`${type}_progress`] += (
      this.completedStepCount / student.scoredStepCount[type]
    ) - ( prevCompletedStepCount / student.scoredStepCount[type] );
    // assignment
    this.reportHeading.average_progress += (
      this.completedStepCount / this.reportHeading.scoredStepCount
    ) - ( prevCompletedStepCount / this.reportHeading.scoredStepCount );
    // period
    period[`overall_${type}_progress`] += course[`${type}_progress_weight`] * (
      ( this.completedStepCount / period.scoredStepCount[type] ) -
        ( prevCompletedStepCount / period.scoredStepCount[type] )
    );

    // Now round the score
    return this.score = Math.round(this.score * 100 ) / 100;
  }

}
<commit_msg>add missingstep count fields<commit_after>import { filter, find, includes, findIndex, reduce, isNil } from 'lodash';
import { computed, observable, action } from 'mobx';
import {
  BaseModel, identifiedBy, belongsTo, hasMany, session, identifier, field,
} from 'shared/model';
import { TimeStore } from '../../../flux/time';

@identifiedBy('course/scores/task-result')
export default class TaskResult extends BaseModel {
  @identifier id;
  @field type;
  @field status;
  @field score;
  @field step_count;
  @field completed_step_count;
  @field completed_accepted_late_exercise_count;
  @field completed_accepted_late_step_count;
  @field completed_exercise_count;
  @field completed_on_time_exercise_count;
  @field completed_on_time_step_count;
  @field completed_step_count;
  @field correct_accepted_late_exercise_count;
  @field correct_exercise_count;
  @field correct_on_time_exercise_count;
  @field correct_on_time_step_count;
  @field correct_accepted_late_step_count;
  @field({ type: 'date' }) due_at;
  @field exercise_count;
  @field is_included_in_averages;
  @field is_late_work_accepted;
  @field recovered_exercise_count;

  @belongsTo({ model: 'course/scores/student' }) student;

  @computed get columnIndex() {
    return findIndex(this.student.data, s => s === this);
  }

  @computed get lateStepCount() {
    if (this.type === 'homework') {
      return this.completed_exercise_count -
             this.completed_on_time_exercise_count -
             this.completed_accepted_late_exercise_count;
    }
    return this.completed_step_count -
           this.completed_on_time_step_count -
           this.completed_accepted_late_step_count;
  }

  @computed get hasLateWork() {
    return this.lateStepCount > 0;
  }

  @computed get isLate() {
    return this.completed_on_time_step_count < this.completed_step_count;
  }

  @computed get isStarted() {
    return Boolean(this.completed_step_count || this.completed_exercise_count);
  }

  @computed get reportHeading() {
    return this.student.period.data_headings[this.columnIndex];
  }

  // called by API
  acceptLate() {}
  rejectLate() {}

  onLateWorkRejected() {
    const prevLateSteps = this.completed_accepted_late_step_count;
    const prevCorrect = this.correct_accepted_late_exercise_count;

    this.is_late_work_accepted = false;
    this.completed_accepted_late_exercise_count = 0;
    this.correct_accepted_late_exercise_count = 0;
    this.completed_accepted_late_step_count = 0;
    this.accepted_late_at = null;

    if (this.is_included_in_averages) {
      this.adjustAverages(
        prevLateSteps + this.completed_on_time_step_count,
        prevCorrect + this.correct_on_time_exercise_count,
      );
    }
  }

  onLateWorkAccepted() {
    // nothing to do if it's not actually late
    if (!this.hasLateWork) { return; }

    const prevLateSteps = this.completed_accepted_late_step_count;
    const prevCorrect = this.correct_accepted_late_exercise_count;

    this.is_late_work_accepted = true;
    this.completed_accepted_late_exercise_count =
      this.completed_exercise_count - this.completed_on_time_exercise_count;
    this.correct_accepted_late_exercise_count =
      this.correct_exercise_count - this.correct_on_time_exercise_count;
    this.completed_accepted_late_step_count =
      this.completed_step_count - this.completed_on_time_step_count;
    this.accepted_late_at = TimeStore.getNow().toISOString();

    if (this.is_included_in_averages) {
      this.adjustAverages(
        prevLateSteps + this.completed_on_time_step_count,
        prevCorrect + this.correct_on_time_exercise_count,
      );
    }
  }

  @computed get completedStepCount() {
    return this.completed_accepted_late_step_count + this.completed_on_time_step_count;
  }

  @computed get scoredStepCount() {
    return this.completed_on_time_exercise_count + this.completed_accepted_late_exercise_count;
  }

  @computed get scoredCorrectCount() {
    return this.correct_on_time_exercise_count + this.correct_accepted_late_exercise_count;
  }

  adjustAverages(prevCompletedStepCount, prevCorrect) {
    const oldScore = this.score;
    const period = this.student.period;
    const { course } = period.coursePeriod;
    const { type } = this;
    let student = this.student;

    // Update score for the task without rounding so the calculations below will use it's full precision
    this.score = (
      this.correct_on_time_exercise_count + this.correct_accepted_late_exercise_count
    ) / this.exercise_count;

    //----------------------------------------------------------------+
    // scores                                                         |
    //----------------------------------------------------------------+

    // student
    student[`${type}_score`] += (
      this.scoredCorrectCount / student.scoredStepCount[type]
    ) - ( prevCorrect / student.scoredStepCount[type] );
    // assignment
    this.reportHeading.average_score += (
      this.scoredCorrectCount / this.reportHeading.scoredStepCount
    ) - ( prevCorrect / this.reportHeading.scoredStepCount );
    // period
    period[`overall_${type}_score`] += course[`${type}_score_weight`] * (
      ( this.scoredCorrectCount / period.scoredStepCount[type] ) -
        ( prevCorrect / period.scoredStepCount[type] )
    );

    //----------------------------------------------------------------+
    // progress                                                       |
    //----------------------------------------------------------------+

    // student
    student[`${type}_progress`] += (
      this.completedStepCount / student.scoredStepCount[type]
    ) - ( prevCompletedStepCount / student.scoredStepCount[type] );
    // assignment
    this.reportHeading.average_progress += (
      this.completedStepCount / this.reportHeading.scoredStepCount
    ) - ( prevCompletedStepCount / this.reportHeading.scoredStepCount );
    // period
    period[`overall_${type}_progress`] += course[`${type}_progress_weight`] * (
      ( this.completedStepCount / period.scoredStepCount[type] ) -
        ( prevCompletedStepCount / period.scoredStepCount[type] )
    );

    // Now round the score
    return this.score = Math.round(this.score * 100 ) / 100;
  }

}
<|endoftext|>


<commit_before>var docpadConfig, moment, exec, json;
moment = require('moment');
moment.lang('es');
exec = require('child_process').exec;
json = require('./package.json');
docpadConfig = {
	templateData: {
		site: {
			url: "http://www.fizzvr.com",
			titulo: "FizzVR",
			descripcion: "Compilando el mundo con tecnologías de hoy y generando bits para la web de mañana",
			keywords: "vladimir, vladimir rodríguez, rodríguez, javascript, html5, jquery, css3, git, ajax, html, desarrolo web, diseño web, programación, v2b",
			autor: "fizzvr",
			email: "fizzvr@gmail.com",
			go_css: "/cvr/cssvr.css",
			go_js: "/jvr/vrweb.js"
		},
		obtenerDocpadv: function () {
			version = json.dependencies.docpad;
			return version;
		},
		formatoFecha: function (fecha, formato) {
			if (formato == null) {
				formato = 'LLLL';
			}
			return moment(fecha).format(formato);
		},
		obtenerTitulo: function() {
			if (this.document.titulo) {
				return "" + this.site.titulo + " , " + this.document.titulo;
			} else {
				return "" + this.site.titulo + " , Programador";
			}
		},
		obtenerDescripcion: function() {
			return this.document.descripcion || this.site.descripcion;
		},
		obtenerPalabrasClave: function() {
			return this.site.keywords.concat(this.document.keywords || []).join(", ");
		},
		obtenerAutor: function() {
			return this.document.autor || this.site.autor;
		},
		obtenerEstilos: function() {
			return this.document.css || this.site.go_css;
		},
		obtenerJavascript: function() {
			return this.document.js || this.site.go_js;
		}
	},
	collections: {
	    paginas: function(database) {
	    return database.findAllLive({
	        pageOrder: {
	          $exists: true
	        }
	      }, [
	        {
	          pageOrder: 1,
	          titulo: 1
	        }
	      ]);
	    },
	    proyectos: function(database) {
	      return database.findAllLive({
	        relativeOutDirPath: 'proyectos',
	        hex: {
	          $exists: true
	        }
	      }, [
	        {
	          hex: 1
	        }
	      ]);
	    }
	},
	events: {
		generateBefore: function(opts, next) {
			var proc;
			if (this.docpad.getConfig().frontendDebug) {
				return next();
			}
			proc = exec('grunt', {
				cwd: process.cwd()
			}, function(error, stdout, stderr) {
				console.log(stdout);
				if (error) {
					return process.exit();
				}
			});
			return proc.on('exit', next);
		}
	}
};
module.exports = docpadConfig;
<commit_msg>Se modifica la descripcion del sitio web<commit_after>var docpadConfig, moment, exec, json;
moment = require('moment');
moment.lang('es');
exec = require('child_process').exec;
json = require('./package.json');
docpadConfig = {
	templateData: {
		site: {
			url: "http://www.fizzvr.com",
			titulo: "FizzVR",
			descripcion: "Programador from Quito-Ecuador, alumno del Conocimiento Libre y desarrollador Web",
			keywords: "vladimir, vladimir rodríguez, rodríguez, quito, ecuador, javascript, html5, jquery, css3, git, ajax, html, desarrolo web, diseño web, programación, v2b",
			autor: "fizzvr",
			email: "fizzvr@gmail.com",
			go_css: "/cvr/cssvr.css",
			go_js: "/jvr/vrweb.js"
		},
		obtenerDocpadv: function () {
			version = json.dependencies.docpad;
			return version;
		},
		formatoFecha: function (fecha, formato) {
			if (formato == null) {
				formato = 'LLLL';
			}
			return moment(fecha).format(formato);
		},
		obtenerTitulo: function() {
			if (this.document.titulo) {
				return "" + this.site.titulo + " , " + this.document.titulo;
			} else {
				return "" + this.site.titulo + " , Programador";
			}
		},
		obtenerDescripcion: function() {
			return this.document.descripcion || this.site.descripcion;
		},
		obtenerPalabrasClave: function() {
			return this.site.keywords.concat(this.document.keywords || []).join(", ");
		},
		obtenerAutor: function() {
			return this.document.autor || this.site.autor;
		},
		obtenerEstilos: function() {
			return this.document.css || this.site.go_css;
		},
		obtenerJavascript: function() {
			return this.document.js || this.site.go_js;
		}
	},
	collections: {
	    paginas: function(database) {
	    return database.findAllLive({
	        pageOrder: {
	          $exists: true
	        }
	      }, [
	        {
	          pageOrder: 1,
	          titulo: 1
	        }
	      ]);
	    },
	    proyectos: function(database) {
	      return database.findAllLive({
	        relativeOutDirPath: 'proyectos',
	        hex: {
	          $exists: true
	        }
	      }, [
	        {
	          hex: 1
	        }
	      ]);
	    }
	},
	events: {
		generateBefore: function(opts, next) {
			var proc;
			if (this.docpad.getConfig().frontendDebug) {
				return next();
			}
			proc = exec('grunt', {
				cwd: process.cwd()
			}, function(error, stdout, stderr) {
				console.log(stdout);
				if (error) {
					return process.exit();
				}
			});
			return proc.on('exit', next);
		}
	}
};
module.exports = docpadConfig;
<|endoftext|>


<commit_before>var gpio = require("pi-gpio");

var inPin = 7;

blink(1);

function blink(status) {
	console.log('GPIO set to: ' + status);
    gpio.open(inPin, "output", function(err) {
	    gpio.write(inPin, status, function() {
	        gpio.close(inPin);
	        setTimeout(function() {
	        	status = (status + 1) % 2;
    			blink(status);
			}, 2000);
	    });
	});
}

process.on('SIGINT', function() {
    console.log('Caught interrupt signal, turning LED off!');
    gpio.write(inPin, 0, function() {
	    gpio.close(inPin);
	    process.exit();
	}
});<commit_msg>Adding blink<commit_after>var gpio = require("pi-gpio");

var inPin = 7;

blink(1);

function blink(status) {
	console.log('GPIO set to: ' + status);
    gpio.open(inPin, "output", function(err) {
	    gpio.write(inPin, status, function() {
	        gpio.close(inPin);
	        setTimeout(function() {
	        	status = (status + 1) % 2;
    			blink(status);
			}, 2000);
	    });
	});
}

process.on('SIGINT', function() {
    console.log('Caught interrupt signal, turning LED off!');
    gpio.write(inPin, 0, function() {
	    gpio.close(inPin);
	    process.exit();
	});
});<|endoftext|>


<commit_before>// DO THIS FIRST; REPLACE LATER
window.onerror = function(msg, url, line) {
  alert("JavaScript error on line " + line + " of " + url + "\n\n" + msg);
}

// Globals
var _files = {};
var _current_filename_id;
var _whoami = {};
var _dirty = false;
var _save_timeout;
var _editor;
var _output_window;
var _popout = false;

// Keep track of z-index to allow layering of multiple glass messages
var _glassMessageZIndex = 2147483647 - 100;

var source_container = document.getElementById('source-container');
var source_filename = document.getElementById('source-filename');
var source_code = document.getElementById('source-code');
var source_image = document.getElementById('source-image');

function set_status(status) {
  document.getElementById('status').innerHTML = status || ' ';
}

function lightbox(summary, details) {
  outer = document.createElement('div');
  _glassMessageZIndex += 2;
  // borrowed from GWT's hosted.html and adapted for bliss
  outer.innerHTML =
    '
' +
    '
' +
    '<button onclick="window.location.reload()" style="background-color:#fff;color:#000;">reload page</button>' +
    '<button onclick="outer=this.parentNode.parentNode.parentNode;outer.parentNode.removeChild(outer)" style="background-color:#fff;color:#000;">close</button>' +
    '
' +
    '
' + summary + '
' +
    '
' + details + '
' +
    '
' +
    '

'
  ;
  document.body.appendChild(outer);
  document.body.scrollTop = 0;

  return function() {
    document.body.removeChild(outer);
  }
}

window.onerror = function(msg, url, line) {
  box = lightbox("JavaScript error on line " + line + " of " + url, msg);
}

// XHR
function xhr(method, url, callback, data) {
  set_status(' ' + method + ' ' + url);
  setTimeout(function() { _xhr(method, url, callback, data); }, 0);
}

function safer(html) {
  return html.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
}

function _xhr(method, url, callback, data) {
  var xhr = new XMLHttpRequest();
  xhr.open(method, url, true);
  xhr.onreadystatechange = function() {
    if (xhr.readyState != 4) {
      return;
    }
    if (xhr.status != 200) {
      set_status('\nHTTP Status: ' + xhr.status + '\nURL: ' + url);
      // '.' does not match newlines, so use '[\s\S]' instead
      content = xhr.responseText.replace(/[\s\S]*([\s\S]*)<\/body>[\s\S]*/, '$1');
      box = lightbox('HTTP Status: ' + xhr.status + '\nURL: ' + url, content);
    } else {
      set_status(); // XHR success
      callback(xhr);
    }
  }
  xhr.send(data);
}

// GET
function get(url, callback, data) {
  xhr('get', url, function(xhr) {
    callback(xhr);
  }, data);
}

// POST
function post(url, callback, data) {
  xhr('post', url, function(xhr) {
    callback(xhr);
  }, data);
}

// PUT
function put(url, callback, data) {
  xhr('put', url, function(xhr) {
    callback(xhr);
  }, data);
}

// JSON XHR
function json(url, callback, data) {
  get(url, function(xhr) {
    var content_type = xhr.getResponseHeader('Content-Type');
    if (content_type != 'application/json') {
      throw url + '\nReturned non-JSON Content-Type: ' + content_type;
    }
    try {
      eval('r = ' + xhr.responseText);
    } catch(e) {
      throw url + '\nFailed to eval JSON:\n' + xhr.responseText;
    }
    callback(xhr, r);
  }, data);
}

// CodeMirror helper
function getSelectedRange() {
  return { from: _editor.getCursor(true), to: _editor.getCursor(false) };
}

function insertAfter(newNode, existingNode) {
  var parentNode = existingNode.parentNode;
  if (existingNode.nextSibling) {
    return parentNode.insertBefore(newNode, existingNode.nextSibling);
  } else {
    return parentNode.appendChild(newNode);
  }
}

function file_context_menu(evt, id) {
  evt.stopPropagation();
  var menuDiv = document.getElementById('file-context-menu');
  menuDiv.style.display = 'block';
  console.log(menuDiv.style);
  menuDiv.style.left = evt.pageX + 'px';
  menuDiv.style.top = evt.pageY + 'px';
  var elem = document.getElementById(id);
  insertAfter(menuDiv, elem);
}

// activate a new file in the left nav
function selectFile(id) {
  if (_current_filename_id) {
    if (id == _current_filename_id) {
      return;
    }

    // CSS deselect previous file
    var elem = document.getElementById(_current_filename_id);
    elem.setAttribute('class', elem.getAttribute('class').replace(' selected', ' unselected'));

    // save file content
    save();

    // hide current file
    source_container.setAttribute('class', 'unknown');
  }

  // CSS select current file
  var elem = document.getElementById(id);
  if (elem) {
    elem.setAttribute('class', elem.getAttribute('class').replace(' unselected', ' selected'));
  }

  // remember current file
  _current_filename_id = id;

  // fetch file content
  var filename = _files[id];
  source_filename.innerHTML = filename;
  var uri = '/bliss/p/' + encodeURI(_whoami.project_name) + '/getfile/' + encodeURI(filename);
  get(uri, function(xhr) {
    // e.g. 'text/html; charset=UTF-8'
    var mime_type = xhr.getResponseHeader('Content-Type');
    // strip '; charset=...'
    mime_type = mime_type.replace(/ ?;.*/, '');
    if (/^image\//.test(mime_type)) {
      source_image.setAttribute('src', uri);
      source_container.setAttribute('class', 'image');
    } else {
      while(source_code.hasChildNodes()) {
        source_code.removeChild(source_code.childNodes[0]);
      }
      _editor = createEditor(mime_type);
      source_container.setAttribute('class', 'code');
      _editor.setValue(xhr.responseText);
      _editor.setOption('onChange', editorOnChange);
      _editor.focus();
    }
  });
}

function addfile(id, filename) {
  _files[id] = filename;
  var filelist = document.getElementById('filelist');
  var node = document.createElement('div');
  node.id = id;
  node.setAttribute('class', 'fileentry unselected');
  var url = 'http://' + _whoami.hostname + filename;
  node.innerHTML = '' + filename + '…';
  filelist.insertBefore(node, filelist.lastChild);
}

function prompt_file_delete() {
  var filename = _files[_current_filename_id];
  var answer = prompt("Are you sure you want to delete " + filename + "?\nType 'yes' to confirm.", "no");
  if (!answer || answer.toLowerCase()[0] != 'y') {
    return;
  }
  var uri = 'deletepath/' + encodeURI(filename);
  post(uri, function(xhr) {
    document.body.scrollTop = 0;
    window.location.reload();
  });
}

function prompt_file_rename() {
  var filename = _files[_current_filename_id];
  var new_filename = prompt('New filename?\n(You may specify a full path such as: foo/bar.txt)', filename);
  if (!new_filename) {
    return;
  }
  if (new_filename[0] == '/') {
    new_filename = new_filename.substr(1);
  }
  if (!new_filename || new_filename == filename) {
    return;
  }
  var uri = 'movefile/' + encodeURI(filename) +
            '?newpath=' + encodeURI(new_filename);
  post(uri, function(xhr) {
    document.body.scrollTop = 0;
    window.location.reload();
  });
}

function prompt_for_new_project(template_url) {
  var project_name = prompt("Please select a unique project name.\nUse only lowercase letters (a-z), digits (0-9) and dashes (-).", "");
  if (!project_name) {
    return;
  }
  // var project_description = prompt('Project description', project_name) || project_name;
  var project_description = project_name;
  var uri = '/bliss/p/' + encodeURI(project_name) + '/create' +
            '?template_url=' + encodeURI(template_url) +
            '&project_description=' + encodeURI(project_description);
  box = lightbox(escape(project_description), 'Creating project. Please wait.');
  post(uri, function(xhr) {
    box();
    document.body.scrollTop = 0;
    window.location.reload();
  });
}

function prompt_to_delete_project(project_name) {
  var answer = prompt("Are you sure you want to delete project " + project_name + "?\nType 'yes' to confirm.", "no");
  if (!answer || answer.toLowerCase()[0] != 'y') {
    return;
  }
  var uri = '/bliss/p/' + encodeURI(project_name) + '/delete';
  post(uri, function(xhr) {
    document.body.scrollTop = 0;
    window.location.reload();
  });
}

function prompt_for_new_file() {
  var filename = prompt('New filename?', '');
  if (!filename) {
    return;
  }
  if (filename[0] == '/') {
    filename = filenamei
  }
  for (id in _files) {
    if (filename == _files[id]) {
      selectFile(id);
      return;
    }
  }
  var id = 'file-' + Object.keys(_files).length;
  var uri = '/bliss/p/' + encodeURI(_whoami.project_name) + '/putfile/' + encodeURI(filename);
  put(uri, function(xhr) {
    addfile(id, filename);
    selectFile(id);
  });
}

function popout() {
  _popout = true;
  _output_window = undefined;
}

function run(url, project_name) {
  var container = document.getElementById('output-container');
  if (_output_window && _output_window.closed) {
    _popout = false;
  }
  if (_popout) {
    container.style.display = 'none';
    _output_window = window.open(url, project_name);
  } else {
    container.style.display = 'block';
    var container = document.getElementById('output-container');
    var where = document.getElementById('output-url');
    var iframe = document.getElementById('output-iframe');
    iframe.src = url;
    where.innerHTML = iframe.src;
  }
}

// populate left nav with list of filenames
function populateFilenames(filenames) {
  var filelist = document.getElementById('filelist');

  // allow the creation of new files
  var node =  document.createElement('div');
  node.setAttribute('class', 'newthing link');
  node.innerHTML = '+ new file';
  node.onclick = function(evt) {
    prompt_for_new_file();
  }
  filelist.appendChild(node);

  // add project files
  for (var i in filenames) {
    var id = 'file-' + i;
    var filename = filenames[i];
    addfile(id, filename);
  }
}

// initalize workspace
function initWorkspace() {
  json('whoami', function(xhr, r) {
    _whoami = r;
    initLeftNavClickHandler();
    initFileContextMenuClearHandler();
    json('listfiles/', function(xhr, files) {
      populateFilenames(files);
      if (files.length) {
        // select a file
        selectFile('file-0');
      }
    });
  });
}

// given an element in the left nav, determine the file id
function getFileIdFromElem(elem) {
  while (elem != null && elem.nodeName != 'BODY') {
    var clazz = elem.getAttribute('class');
    if (clazz && clazz.indexOf('fileentry') != -1) {
      return elem.id;
    }
    elem = elem.parentNode;
  }
  return null;
}

// setup file context menu clear handler
function initFileContextMenuClearHandler() {
  window.addEventListener('click', function(evt) {
    document.getElementById('file-context-menu').style.display = 'None';
  }, false);
}

// setup left nav click handler
function initLeftNavClickHandler() {
  nav.addEventListener('click', function(evt) {
    var id = getFileIdFromElem(evt.srcElement || evt.target);
    if (id) {
      selectFile(id);
    }
  }, true);
}

// called from setTimeout after editor is marked dirty
function save() {
  if (!_dirty) {
    return;
  }

  // TODO: fix me
  _dirty = false;

  // determine filename
  var filename = _files[_current_filename_id];

  set_status('Saving...');

  // TODO: catch exception and mark dirty
  var uri = '/bliss/p/' + encodeURI(_whoami.project_name) + '/putfile/' + encodeURI(filename);
  put(uri, function(xhr) {
    set_status(); // Saved
  }, _editor.getValue());
}

function markDirty() {
  if (_save_timeout) {
    return;
  }
  _dirty = true;
  _save_timeout = setTimeout(function() {
    _save_timeout = null;
    save();
  }, 1000);
}

// editor onChange
function editorOnChange(from, to, text, next) {
   markDirty();
}

function createEditor(mime_type) {
  return CodeMirror(source_code, {
    value: 'Initializing...',
    mode: mime_type,
    lineNumbers: true,
    matchBrackets: true,
    undoDepth: 440, // default = 40
  });
}
<commit_msg>http methods should be upper case<commit_after>// DO THIS FIRST; REPLACE LATER
window.onerror = function(msg, url, line) {
  alert("JavaScript error on line " + line + " of " + url + "\n\n" + msg);
}

// Globals
var _files = {};
var _current_filename_id;
var _whoami = {};
var _dirty = false;
var _save_timeout;
var _editor;
var _output_window;
var _popout = false;

// Keep track of z-index to allow layering of multiple glass messages
var _glassMessageZIndex = 2147483647 - 100;

var source_container = document.getElementById('source-container');
var source_filename = document.getElementById('source-filename');
var source_code = document.getElementById('source-code');
var source_image = document.getElementById('source-image');

function set_status(status) {
  document.getElementById('status').innerHTML = status || ' ';
}

function lightbox(summary, details) {
  outer = document.createElement('div');
  _glassMessageZIndex += 2;
  // borrowed from GWT's hosted.html and adapted for bliss
  outer.innerHTML =
    '
' +
    '
' +
    '<button onclick="window.location.reload()" style="background-color:#fff;color:#000;">reload page</button>' +
    '<button onclick="outer=this.parentNode.parentNode.parentNode;outer.parentNode.removeChild(outer)" style="background-color:#fff;color:#000;">close</button>' +
    '
' +
    '
' + summary + '
' +
    '
' + details + '
' +
    '
' +
    '

'
  ;
  document.body.appendChild(outer);
  document.body.scrollTop = 0;

  return function() {
    document.body.removeChild(outer);
  }
}

window.onerror = function(msg, url, line) {
  box = lightbox("JavaScript error on line " + line + " of " + url, msg);
}

// XHR
function xhr(method, url, callback, data) {
  set_status(' ' + method + ' ' + url);
  setTimeout(function() { _xhr(method, url, callback, data); }, 0);
}

function safer(html) {
  return html.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
}

function _xhr(method, url, callback, data) {
  var xhr = new XMLHttpRequest();
  xhr.open(method, url, true);
  xhr.onreadystatechange = function() {
    if (xhr.readyState != 4) {
      return;
    }
    if (xhr.status != 200) {
      set_status('\nHTTP Status: ' + xhr.status + '\nURL: ' + url);
      // '.' does not match newlines, so use '[\s\S]' instead
      content = xhr.responseText.replace(/[\s\S]*([\s\S]*)<\/body>[\s\S]*/, '$1');
      box = lightbox('HTTP Status: ' + xhr.status + '\nURL: ' + url, content);
    } else {
      set_status(); // XHR success
      callback(xhr);
    }
  }
  xhr.send(data);
}

// GET
function get(url, callback, data) {
  xhr('GET', url, function(xhr) {
    callback(xhr);
  }, data);
}

// POST
function post(url, callback, data) {
  xhr('POST', url, function(xhr) {
    callback(xhr);
  }, data);
}

// PUT
function put(url, callback, data) {
  xhr('PUT', url, function(xhr) {
    callback(xhr);
  }, data);
}

// JSON XHR
function json(url, callback, data) {
  get(url, function(xhr) {
    var content_type = xhr.getResponseHeader('Content-Type');
    if (content_type != 'application/json') {
      throw url + '\nReturned non-JSON Content-Type: ' + content_type;
    }
    try {
      eval('r = ' + xhr.responseText);
    } catch(e) {
      throw url + '\nFailed to eval JSON:\n' + xhr.responseText;
    }
    callback(xhr, r);
  }, data);
}

// CodeMirror helper
function getSelectedRange() {
  return { from: _editor.getCursor(true), to: _editor.getCursor(false) };
}

function insertAfter(newNode, existingNode) {
  var parentNode = existingNode.parentNode;
  if (existingNode.nextSibling) {
    return parentNode.insertBefore(newNode, existingNode.nextSibling);
  } else {
    return parentNode.appendChild(newNode);
  }
}

function file_context_menu(evt, id) {
  evt.stopPropagation();
  var menuDiv = document.getElementById('file-context-menu');
  menuDiv.style.display = 'block';
  console.log(menuDiv.style);
  menuDiv.style.left = evt.pageX + 'px';
  menuDiv.style.top = evt.pageY + 'px';
  var elem = document.getElementById(id);
  insertAfter(menuDiv, elem);
}

// activate a new file in the left nav
function selectFile(id) {
  if (_current_filename_id) {
    if (id == _current_filename_id) {
      return;
    }

    // CSS deselect previous file
    var elem = document.getElementById(_current_filename_id);
    elem.setAttribute('class', elem.getAttribute('class').replace(' selected', ' unselected'));

    // save file content
    save();

    // hide current file
    source_container.setAttribute('class', 'unknown');
  }

  // CSS select current file
  var elem = document.getElementById(id);
  if (elem) {
    elem.setAttribute('class', elem.getAttribute('class').replace(' unselected', ' selected'));
  }

  // remember current file
  _current_filename_id = id;

  // fetch file content
  var filename = _files[id];
  source_filename.innerHTML = filename;
  var uri = '/bliss/p/' + encodeURI(_whoami.project_name) + '/getfile/' + encodeURI(filename);
  get(uri, function(xhr) {
    // e.g. 'text/html; charset=UTF-8'
    var mime_type = xhr.getResponseHeader('Content-Type');
    // strip '; charset=...'
    mime_type = mime_type.replace(/ ?;.*/, '');
    if (/^image\//.test(mime_type)) {
      source_image.setAttribute('src', uri);
      source_container.setAttribute('class', 'image');
    } else {
      while(source_code.hasChildNodes()) {
        source_code.removeChild(source_code.childNodes[0]);
      }
      _editor = createEditor(mime_type);
      source_container.setAttribute('class', 'code');
      _editor.setValue(xhr.responseText);
      _editor.setOption('onChange', editorOnChange);
      _editor.focus();
    }
  });
}

function addfile(id, filename) {
  _files[id] = filename;
  var filelist = document.getElementById('filelist');
  var node = document.createElement('div');
  node.id = id;
  node.setAttribute('class', 'fileentry unselected');
  var url = 'http://' + _whoami.hostname + filename;
  node.innerHTML = '' + filename + '…';
  filelist.insertBefore(node, filelist.lastChild);
}

function prompt_file_delete() {
  var filename = _files[_current_filename_id];
  var answer = prompt("Are you sure you want to delete " + filename + "?\nType 'yes' to confirm.", "no");
  if (!answer || answer.toLowerCase()[0] != 'y') {
    return;
  }
  var uri = 'deletepath/' + encodeURI(filename);
  post(uri, function(xhr) {
    document.body.scrollTop = 0;
    window.location.reload();
  });
}

function prompt_file_rename() {
  var filename = _files[_current_filename_id];
  var new_filename = prompt('New filename?\n(You may specify a full path such as: foo/bar.txt)', filename);
  if (!new_filename) {
    return;
  }
  if (new_filename[0] == '/') {
    new_filename = new_filename.substr(1);
  }
  if (!new_filename || new_filename == filename) {
    return;
  }
  var uri = 'movefile/' + encodeURI(filename) +
            '?newpath=' + encodeURI(new_filename);
  post(uri, function(xhr) {
    document.body.scrollTop = 0;
    window.location.reload();
  });
}

function prompt_for_new_project(template_url) {
  var project_name = prompt("Please select a unique project name.\nUse only lowercase letters (a-z), digits (0-9) and dashes (-).", "");
  if (!project_name) {
    return;
  }
  // var project_description = prompt('Project description', project_name) || project_name;
  var project_description = project_name;
  var uri = '/bliss/p/' + encodeURI(project_name) + '/create' +
            '?template_url=' + encodeURI(template_url) +
            '&project_description=' + encodeURI(project_description);
  box = lightbox(escape(project_description), 'Creating project. Please wait.');
  post(uri, function(xhr) {
    box();
    document.body.scrollTop = 0;
    window.location.reload();
  });
}

function prompt_to_delete_project(project_name) {
  var answer = prompt("Are you sure you want to delete project " + project_name + "?\nType 'yes' to confirm.", "no");
  if (!answer || answer.toLowerCase()[0] != 'y') {
    return;
  }
  var uri = '/bliss/p/' + encodeURI(project_name) + '/delete';
  post(uri, function(xhr) {
    document.body.scrollTop = 0;
    window.location.reload();
  });
}

function prompt_for_new_file() {
  var filename = prompt('New filename?', '');
  if (!filename) {
    return;
  }
  if (filename[0] == '/') {
    filename = filenamei
  }
  for (id in _files) {
    if (filename == _files[id]) {
      selectFile(id);
      return;
    }
  }
  var id = 'file-' + Object.keys(_files).length;
  var uri = '/bliss/p/' + encodeURI(_whoami.project_name) + '/putfile/' + encodeURI(filename);
  put(uri, function(xhr) {
    addfile(id, filename);
    selectFile(id);
  });
}

function popout() {
  _popout = true;
  _output_window = undefined;
}

function run(url, project_name) {
  var container = document.getElementById('output-container');
  if (_output_window && _output_window.closed) {
    _popout = false;
  }
  if (_popout) {
    container.style.display = 'none';
    _output_window = window.open(url, project_name);
  } else {
    container.style.display = 'block';
    var container = document.getElementById('output-container');
    var where = document.getElementById('output-url');
    var iframe = document.getElementById('output-iframe');
    iframe.src = url;
    where.innerHTML = iframe.src;
  }
}

// populate left nav with list of filenames
function populateFilenames(filenames) {
  var filelist = document.getElementById('filelist');

  // allow the creation of new files
  var node =  document.createElement('div');
  node.setAttribute('class', 'newthing link');
  node.innerHTML = '+ new file';
  node.onclick = function(evt) {
    prompt_for_new_file();
  }
  filelist.appendChild(node);

  // add project files
  for (var i in filenames) {
    var id = 'file-' + i;
    var filename = filenames[i];
    addfile(id, filename);
  }
}

// initalize workspace
function initWorkspace() {
  json('whoami', function(xhr, r) {
    _whoami = r;
    initLeftNavClickHandler();
    initFileContextMenuClearHandler();
    json('listfiles/', function(xhr, files) {
      populateFilenames(files);
      if (files.length) {
        // select a file
        selectFile('file-0');
      }
    });
  });
}

// given an element in the left nav, determine the file id
function getFileIdFromElem(elem) {
  while (elem != null && elem.nodeName != 'BODY') {
    var clazz = elem.getAttribute('class');
    if (clazz && clazz.indexOf('fileentry') != -1) {
      return elem.id;
    }
    elem = elem.parentNode;
  }
  return null;
}

// setup file context menu clear handler
function initFileContextMenuClearHandler() {
  window.addEventListener('click', function(evt) {
    document.getElementById('file-context-menu').style.display = 'None';
  }, false);
}

// setup left nav click handler
function initLeftNavClickHandler() {
  nav.addEventListener('click', function(evt) {
    var id = getFileIdFromElem(evt.srcElement || evt.target);
    if (id) {
      selectFile(id);
    }
  }, true);
}

// called from setTimeout after editor is marked dirty
function save() {
  if (!_dirty) {
    return;
  }

  // TODO: fix me
  _dirty = false;

  // determine filename
  var filename = _files[_current_filename_id];

  set_status('Saving...');

  // TODO: catch exception and mark dirty
  var uri = '/bliss/p/' + encodeURI(_whoami.project_name) + '/putfile/' + encodeURI(filename);
  put(uri, function(xhr) {
    set_status(); // Saved
  }, _editor.getValue());
}

function markDirty() {
  if (_save_timeout) {
    return;
  }
  _dirty = true;
  _save_timeout = setTimeout(function() {
    _save_timeout = null;
    save();
  }, 1000);
}

// editor onChange
function editorOnChange(from, to, text, next) {
   markDirty();
}

function createEditor(mime_type) {
  return CodeMirror(source_code, {
    value: 'Initializing...',
    mode: mime_type,
    lineNumbers: true,
    matchBrackets: true,
    undoDepth: 440, // default = 40
  });
}
<|endoftext|>


<commit_before>var t = require('../index'),
  should = require('should'),
  fs = require('fs')

describe('grid', function(){
  it('should create a 100x100 grid as a Point FeatureCollection', function(done){
    var syncGrid = t.grid([0,0,10,10], 10, function(err, grid){
      if(err) throw err
      grid.should.be.ok
      grid.type.should.equal('FeatureCollection')
      grid.features[0].geometry.type.should.equal('Point')
      //fs.writeFileSync('./testOut/grid.geojson',JSON.stringify(grid))
    })

    if (typeof syncGrid === 'Error') {
      throw syncGrid;
    }

    syncGrid.should.be.ok;
    syncGrid.type.should.equal('FeatureCollection');
    syncGrid.features[0].geometry.type.should.equal('Point');
    done();
  })
  it('should work properly with a negative start value', function(done){
    var syncGrid = t.grid([-20,-20,20,20], 10, function(err, grid){
      if(err) throw err
      grid.should.be.ok
      grid.type.should.equal('FeatureCollection')
      grid.features[0].geometry.type.should.equal('Point')
      grid.features[0].geometry.coordinates[0].should.equal(-20)
      grid.features[0].geometry.coordinates[0].should.equal(-20)
      //fs.writeFileSync('./testOut/grid.geojson',JSON.stringify(grid))
    })

    if (typeof syncGrid === 'Error') {
      throw syncGrid;
    }

    syncGrid.should.be.ok;
    syncGrid.type.should.equal('FeatureCollection');
    syncGrid.features[0].geometry.type.should.equal('Point');
    syncGrid.features[0].geometry.coordinates[0].should.equal(-20);
    syncGrid.features[0].geometry.coordinates[0].should.equal(-20);

    done();
  })
}) <commit_msg>refactored test with tape and sync interface<commit_after>var test = require('tape')
var fs = require('fs')
var grid = require('./')

test('grid', function(t){
  var gridded = grid([0,0,10,10], 10)

  t.ok(gridded, 'should create a 100x100 grid as a Point FeatureCollection')
  t.equal(gridded.type, 'FeatureCollection')
  t.equal(gridded.features[0].geometry.type, 'Point')

  fs.writeFileSync(__dirname+'/geojson/grid1.geojson', JSON.stringify(tinned))

  var gridded = grid([0,0,10,10], 10)

  t.ok(gridded, 'should work properly with a negative start value')
  t.equal(gridded.type, 'FeatureCollection')
  t.equal(gridded.features[0].geometry.type, 'Point')

  fs.writeFileSync(__dirname+'/geojson/grid2.geojson', JSON.stringify(tinned))

  t.end()
});<|endoftext|>


<commit_before>/******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId])
/******/ 			return installedModules[moduleId].exports;
/******/
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;
/******/
/******/ 	// identity function for calling harmony imports with the correct context
/******/ 	__webpack_require__.i = function(value) { return value; };
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
/******/ 		if(!__webpack_require__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, {
/******/ 				configurable: false,
/******/ 				enumerable: true,
/******/ 				get: getter
/******/ 			});
/******/ 		}
/******/ 	};
/******/
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__webpack_require__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__webpack_require__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};
/******/
/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

exports.__esModule = true;
/**
 * Adds div with texts to document body.
 * @param text
 * @returns {boolean}
 */
function addSomethingToDOM(text) {
    var div = document.createElement('div');
    div.innerHTML = text;
    document.querySelector('body').appendChild(div);
    return true;
}
exports.addSomethingToDOM = addSomethingToDOM;

/***/ })
/******/ ]);
//# sourceMappingURL=jsworks.js.map<commit_msg>Delete jsworks.js<commit_after><|endoftext|>