<commit_before>import React, { useEffect, useState } from 'react'
import Aux from 'react-aux'
import { useParams } from 'react-router-dom'
import { compose } from 'recompose'
import Button from '@material-ui/core/Button'
import Card from '@material-ui/core/Card'
import CardActions from '@material-ui/core/CardActions'
import CardContent from '@material-ui/core/CardContent'
import CardHeader from '@material-ui/core/CardHeader'
import Grid from '@material-ui/core/Grid'
import Typography from '@material-ui/core/Typography'

import * as ROUTES from '../../constants/routes'
import ConfirmDialog from '../ConfirmDialog'
import TaskEdit from '../TaskEdit'
import { withAuthorization, withEmailVerification } from '../Session'

const TaskDetailsPage = props => {
  // Deconstruct properties
  const { firebase, history } = props
  // Load url params
  const { gameId, qwestId, id } = useParams()
  // Load state
  const [task, setTask] = useState(null)
  const [isConfirmDialogOpen, setIsConfirmDialogOpen] = useState(false)
  const [isEditMode, setIsEditMode] = useState(false)
  // Define methods
  const viewPosts = () => {
    // history.push(`${ROUTES.QWESTS}/${id}/posts`)
  }

  const editTask = () => {
    setIsEditMode(true)
  }

  const handleTaskEditClose = () => {
    setIsEditMode(false)
  }

  const confirmTaskDelete = () => {
    // Open confirm dialog
    setIsConfirmDialogOpen(true)
  }

  const handleTaskDelete = confirm => {
    if (confirm) {
      // Delete task
      firebase.deleteQwestTask(qwestId, task.id)
      if (gameId) {
        // Push to the game qwest details page
        history.push(`${ROUTES.GAMES}/${gameId}${ROUTES.QWESTS}/${qwestId}`)
      } else {
        // Push to the qwest details page
        history.push(`${ROUTES.QWESTS}/${qwestId}`)
      }
    }
    // Close confirm dialog
    setIsConfirmDialogOpen(false)
  }
  // Define effects handlers
  useEffect(() => {
    // Setup listener to the task collection object
    const unsubscribe = firebase.task(id).onSnapshot(snapshot => {
      setTask(snapshot)
    })
    // Unsubscribe from listener when component is destroyed
    return () => {
      unsubscribe()
    }
  }, [qwestId, id, firebase])
  // Return component
  return (
    <Aux>
      {task && (
        <Aux>
          <Grid container spacing={3}>
            {!isEditMode ? (
              <Aux>
                <Grid item xs={12}>
                  <Card>
                    <CardHeader title="Details" />
                    <CardContent>
                      <Typography variant="body1">
                        <b>Name: </b> {task.data().name}
                      </Typography>
                    </CardContent>
                    <CardActions>
                      <Button
                        variant="contained"
                        color="primary"
                        aria-label="view"
                        onClick={viewPosts}
                      >
                        Posts
                      </Button>
                      <Button
                        variant="contained"
                        color="default"
                        aria-label="view"
                        onClick={editTask}
                      >
                        Edit
                      </Button>
                      <Button
                        variant="contained"
                        color="secondary"
                        aria-label="delete"
                        onClick={confirmTaskDelete}
                      >
                        Delete
                      </Button>
                    </CardActions>
                  </Card>
                </Grid>
              </Aux>
            ) : (
              <Grid item xs={12}>
                <TaskEdit
                  firebase={firebase}
                  task={task}
                  close={handleTaskEditClose}
                ></TaskEdit>
              </Grid>
            )}
          </Grid>
          <ConfirmDialog
            isOpen={isConfirmDialogOpen}
            handleClose={handleTaskDelete}
            title="Delete Task"
            message="Are you sure you want to delete this task?  This cannot be undone."
          />
        </Aux>
      )}
    </Aux>
  )
}

const condition = authUser => !!authUser

export { TaskDetailsPage }

export default compose(
  withEmailVerification,
  withAuthorization(condition),
)(TaskDetailsPage)
<commit_msg>Updated handleTaskDelete method in TaskDetails component<commit_after>import React, { useEffect, useState } from 'react'
import Aux from 'react-aux'
import { useParams } from 'react-router-dom'
import { compose } from 'recompose'
import Button from '@material-ui/core/Button'
import Card from '@material-ui/core/Card'
import CardActions from '@material-ui/core/CardActions'
import CardContent from '@material-ui/core/CardContent'
import CardHeader from '@material-ui/core/CardHeader'
import Grid from '@material-ui/core/Grid'
import Typography from '@material-ui/core/Typography'

import * as ROUTES from '../../constants/routes'
import ConfirmDialog from '../ConfirmDialog'
import TaskEdit from '../TaskEdit'
import { withAuthorization, withEmailVerification } from '../Session'

const TaskDetailsPage = props => {
  // Deconstruct properties
  const { firebase, history } = props
  // Load url params
  const { gameId, qwestId, id } = useParams()
  // Load state
  const [task, setTask] = useState(null)
  const [isConfirmDialogOpen, setIsConfirmDialogOpen] = useState(false)
  const [isEditMode, setIsEditMode] = useState(false)
  // Define methods
  const viewPosts = () => {
    // history.push(`${ROUTES.QWESTS}/${id}/posts`)
  }

  const editTask = () => {
    setIsEditMode(true)
  }

  const handleTaskEditClose = () => {
    setIsEditMode(false)
  }

  const confirmTaskDelete = () => {
    // Open confirm dialog
    setIsConfirmDialogOpen(true)
  }

  const handleTaskDelete = confirm => {
    if (confirm) {
      // Delete task
      firebase.deleteTask(task.id)
      if (gameId) {
        // Push to the game qwest details page
        history.push(`${ROUTES.GAMES}/${gameId}${ROUTES.QWESTS}/${qwestId}`)
      } else {
        // Push to the qwest details page
        history.push(`${ROUTES.QWESTS}/${qwestId}`)
      }
    }
    // Close confirm dialog
    setIsConfirmDialogOpen(false)
  }
  // Define effects handlers
  useEffect(() => {
    // Setup listener to the task collection object
    const unsubscribe = firebase.task(id).onSnapshot(snapshot => {
      setTask(snapshot)
    })
    // Unsubscribe from listener when component is destroyed
    return () => {
      unsubscribe()
    }
  }, [qwestId, id, firebase])
  // Return component
  return (
    <Aux>
      {task && (
        <Aux>
          <Grid container spacing={3}>
            {!isEditMode ? (
              <Aux>
                <Grid item xs={12}>
                  <Card>
                    <CardHeader title="Details" />
                    <CardContent>
                      <Typography variant="body1">
                        <b>Name: </b> {task.data().name}
                      </Typography>
                    </CardContent>
                    <CardActions>
                      <Button
                        variant="contained"
                        color="primary"
                        aria-label="view"
                        onClick={viewPosts}
                      >
                        Posts
                      </Button>
                      <Button
                        variant="contained"
                        color="default"
                        aria-label="view"
                        onClick={editTask}
                      >
                        Edit
                      </Button>
                      <Button
                        variant="contained"
                        color="secondary"
                        aria-label="delete"
                        onClick={confirmTaskDelete}
                      >
                        Delete
                      </Button>
                    </CardActions>
                  </Card>
                </Grid>
              </Aux>
            ) : (
              <Grid item xs={12}>
                <TaskEdit
                  firebase={firebase}
                  task={task}
                  close={handleTaskEditClose}
                ></TaskEdit>
              </Grid>
            )}
          </Grid>
          <ConfirmDialog
            isOpen={isConfirmDialogOpen}
            handleClose={handleTaskDelete}
            title="Delete Task"
            message="Are you sure you want to delete this task?  This cannot be undone."
          />
        </Aux>
      )}
    </Aux>
  )
}

const condition = authUser => !!authUser

export { TaskDetailsPage }

export default compose(
  withEmailVerification,
  withAuthorization(condition),
)(TaskDetailsPage)
<|endoftext|>


<commit_before>import 'should'
import $ from 'teaspoon'
import Selection from '../src/Selection.jsx'
import Selectable from '../src/Selectable.jsx'
import React, { Component, PropTypes } from 'react'

describe("Selection", () => {
  const Blah = class A extends Component {
    static displayName = 'A'
    static propTypes = {
      name: PropTypes.string,
      children: PropTypes.any
    }
    render() {
      return (

hi {this.props.name}

          {this.props.children}

      )
    }
  }
  const Child = class B extends Component {
    static displayName='B'
    static propTypes = {
      value: PropTypes.string,
      id: PropTypes.number
    }
    render() {
      return
{this.props.value}

    }
  }
  const options = {
    value: (props) => props.value,
    key: (props) => props.id,
    cacheBounds: true
  }
  const SelectableChild = Selectable(Child, options)
  describe("higher-order container creation", () => {
    it("should make a component", () => {
      const Thing = Selection(Blah)
      Thing.displayName.should.be.eql('Selection(A)')

      const stuff = $(<Thing>
hi
</Thing>).render()

      stuff.find('.foo').text().should.eql('hi')

      const nextstuff = $(<Thing name="Greg" />).render()

      nextstuff.find('p').text().should.eql('hi Greg')
    })

    it("should error if a non-component is passed in", () => {
      expect(() => {
        Selection(false)
      }).to.throw('Component is not a class, must be a stateful React Component class')
    })

    it("should force a container div for ", () => {
      const Thing = Selection(() => null, { containerDiv: false })

      const stuff = $(<Thing />).render()
      expect(stuff[0].containerDiv).to.be.true
    })

    it("should pull displayname from displayName", () => {
      const Thing = Selection( class {
        static displayName = 'Hi'
        render() {}
      })
      Thing.displayName.should.equal('Selection(Hi)')
    })

    it("should pull displayname from name if displayName is not present", () => {
      const Thing = Selection( class Hi {
        render() {}
      })
      Thing.displayName.should.match(/^Selection\((Hi|Component)\)$/) // IE 10/11
    })
  })

  describe("updateState", () => {
    const Thing = Selection(Blah, {
      sorter: (a, b) => a > b ? 1 : (a  {
      stuff = $(<Thing />).render()
      component = stuff[0]
    })
    afterEach(() => {
      stuff.unmount()
    })

    it("should keep state the same if passed null", () => {
      component.setState({
        selecting: false,
        selectedNodes: { 1: 1, 2: 2, 3: 3 },
        selectedValues: { 4: 4, 5: 5, 6: 6 },
        containerBounds: component.bounds
      })

      component.state.should.eql({
        selecting: false,
        selectedNodes: { 1: 1, 2: 2, 3: 3},
        selectedNodeList: [],
        selectedValues: { 4: 4, 5: 5, 6: 6},
        selectedValueList: [],
        containerBounds: component.bounds
      })

      component.updateState(null, null, null)

      component.state.should.eql({
        selecting: false,
        selectedNodes: { 1: 1, 2: 2, 3: 3},
        selectedNodeList: [],
        selectedValues: { 4: 4, 5: 5, 6: 6},
        selectedValueList: [],
        containerBounds: component.bounds
      })
    })
    it("should set values if passed", () => {
      component.setState({
        selecting: false,
        selectedNodes: { 1: 1, 2: 2, 3: 3},
        selectedValues: { 4: 4, 5: 5, 6: 6},
        containerBounds: component.bounds
      })

      component.state.should.eql({
        selecting: false,
        selectedNodes: { 1: 1, 2: 2, 3: 3},
        selectedNodeList: [],
        selectedValues: { 4: 4, 5: 5, 6: 6},
        selectedValueList: [],
        containerBounds: component.bounds
      })

      component.updateState(true, { hi: 'hi' }, { there: 'there' })

      component.state.should.eql({
        selecting: true,
        selectedNodes: { hi: 'hi' },
        selectedNodeList: [],
        selectedValues: { there: 'there' },
        selectedValueList: [],
        containerBounds: component.bounds
      })
    })

    it("should call onSelectSlot if constantSelect is enabled", () => {
      const spy = sinon.spy()
      stuff = $((
        <Thing selectable constantSelect onSelectSlot={spy}>
          <SelectableChild value="hi" key={1} />
          <SelectableChild value="hi2" key={2} />
          <SelectableChild value="hi3" key={3} />
        </Thing>
          )).render()
      const children = stuff.find(SelectableChild)
      component = stuff[0]
      component.bounds = { hi: 'hi' }
      const selectable1 = children[0]
      const selectable2 = children[1]
      const selectable3 = children[2]

      component.updateState(null, {
        3: {node: selectable3},
        1: {node: selectable1},
        2: {node: selectable2}
      }, {
        3: 'hi3',
        1: 'hi',
        2: 'hi2'
      })

      expect(spy.called).to.be.true

      spy.args[0].should.have.length(5)
      spy.args[0][0].should.be.eql({
        3: 'hi3',
        1: 'hi',
        2: 'hi2'
      })
      expect(spy.args[0][1]()).to.eql({
        3: {node: selectable3},
        1: {node: selectable1},
        2: {node: selectable2}
      })
      expect(spy.args[0][2]).to.eql(['hi', 'hi2', 'hi3'])
      expect(spy.args[0][3]()).to.eql([
        {node: selectable1},
        {node: selectable2},
        {node: selectable3}
      ])
      expect(spy.args[0][4]).to.eql({hi: 'hi'})
    })
    it("should not call onSelectSlot if constantSelection is disabled", () => {
      const spy = sinon.spy()
      stuff = $((
        <Thing selectable onSelectSlot={spy}>
          <SelectableChild value="hi" key={1} />
          <SelectableChild value="hi2" key={2} />
          <SelectableChild value="hi3" key={3} />
        </Thing>
      )).render()
      const children = stuff.find(SelectableChild)
      component = stuff[0]
      component.bounds = { hi: 'hi' }
      const selectable1 = children[0]
      const selectable2 = children[1]
      const selectable3 = children[2]

      component.updateState(null, {
        3: {node: selectable3},
        1: {node: selectable1},
        2: {node: selectable2}
      }, {
        3: 'hi3',
        1: 'hi',
        2: 'hi2'
      })

      expect(spy.called).to.be.false
    })
  })

  describe("propagateFinishedSelect", () => {
    const Thing = Selection(Blah, {
      sorter: (a, b) => a > b ? 1 : (a  {
      spy = sinon.spy()
      stuff = $((
        <Thing selectable constantSelect onFinishSelect={spy}>
        <SelectableChild value="hi" key={1}/>
        <SelectableChild value="hi2" key={2}/>
        <SelectableChild value="hi3" key={3}/>
        </Thing>
      )).render()
      component = stuff[0]
      const children = stuff.find(SelectableChild)
      component = stuff[0]
      component.bounds = {hi: 'hi'}
      selectable1 = children[0]
      selectable2 = children[1]
      selectable3 = children[2]
    })

    afterEach(() => {
      stuff.unmount()
    })

    it("should return our info", () => {
      component.updateState(null, {
        3: {node: selectable3},
        1: {node: selectable1},
        2: {node: selectable2}
      }, {
        3: 'hi3',
        1: 'hi',
        2: 'hi2'
      })

      component.propagateFinishedSelect()

      expect(spy.called).to.be.true

      spy.args[0].should.have.length(5)
      spy.args[0][0].should.be.eql({
        3: 'hi3',
        1: 'hi',
        2: 'hi2'
      })
      expect(spy.args[0][1]()).to.eql({
        3: {node: selectable3},
        1: {node: selectable1},
        2: {node: selectable2}
      })
      expect(spy.args[0][2]).to.eql(['hi', 'hi2', 'hi3'])
      expect(spy.args[0][3]()).to.eql([
        {node: selectable1},
        {node: selectable2},
        {node: selectable3}
      ])
      expect(spy.args[0][4]).to.eql({hi: 'hi'})
    })
  })

  describe("invalid", () => {
    const Thing = Selection(Blah)
    let spy
    let stuff
    let component

    beforeEach(() => {
      spy = sinon.spy()
    })
    afterEach(() => {
      stuff.unmount()
    })

    it("should call onTouchStart if defined and event is a touch event", () => {
      stuff = $(<Thing onTouchStart={spy}/>).render(true)

      component = stuff[0]
      component.invalid('hi', 'touchstart')

      expect(spy.called).to.be.true
    })
    it("should call onMouseDown if defined and event is a mouse event", () => {
      stuff = $(<Thing onMouseDown={spy}/>).render(true)

      component = stuff[0]
      component.invalid('hi', 'mousedown')

      expect(spy.called).to.be.true
    })
  })

  describe("start", () => {
    const Thing = Selection(Blah)
    let spy
    let stuff
    let component

    beforeEach(() => {
      spy = sinon.spy()
    })

    it("should call select if constantSelect is active", () => {
      stuff = $(<Thing constantSelect />).render()

      component = stuff[0]

      component.selectionManager.select = spy
      component.start(1, 2, 3)

      expect(spy.called).to.be.true
    })

    it("should call deselect if constantSelect is not active", () => {
      stuff = $(<Thing />).render()

      component = stuff[0]

      component.selectionManager.deselect = spy
      component.start(1, 2, 3)

      expect(spy.called).to.be.true
    })
  })

  describe("cancel", () => {
    const Thing = Selection(Blah)
    let spy
    let stuff
    let component

    beforeEach(() => {
      spy = sinon.spy()
      stuff = $(<Thing />).render()
      component = stuff[0]
    })

    it("should call deselect", () => {
      component.selectionManager.deselect = spy

      component.cancel()

      expect(spy.called).to.be.true
    })

    it("should call propageFinishedSelect", () => {
      component.propagateFinishedSelect = spy
      component.cancel()

      expect(spy.called).to.be.true
    })

    it("should turn off selection", () => {
      component.setState = spy
      component.cancel()

      expect(spy.called).to.be.true

      spy.args[0][0].should.eql({ selecting: false })
    })
  })

  describe("end", () => {
    it("should call propagateFinishedSelect and deselect if constantSelect is on")
    it("should select any items in the selection rectangle, and propagateFinishedSelect")
  })

  describe("change", () => {
    it("should enable selection")
    it("should call select if constantSelect is enabled")
  })

  describe("makeInputManager", () => {
    it("should do nothing if ref is null")
    it("should set up inputManager and ref on first valid call")
    it("should do nothing if ref is the same as a previous call")
    it("should umount inputManager and re-set if ref changes")
  })

  describe("render", () => {
    it("should create a container div if ")
  })
})
<commit_msg>test everything but render in Selection, add render behaviors to test<commit_after>import 'should'
import $ from 'teaspoon'
import React, { Component, PropTypes } from 'react'

import Selection from '../src/Selection.jsx'
import Selectable from '../src/Selectable.jsx'
import InputManager from '../src/InputManager.js'

describe("Selection", () => {
  const Blah = class A extends Component {
    static displayName = 'A'
    static propTypes = {
      name: PropTypes.string,
      children: PropTypes.any
    }
    render() {
      return (

hi {this.props.name}

          {this.props.children}

      )
    }
  }
  const Child = class B extends Component {
    static displayName='B'
    static propTypes = {
      value: PropTypes.string,
      id: PropTypes.number
    }
    render() {
      return
{this.props.value}

    }
  }
  const options = {
    value: (props) => props.value,
    key: (props) => props.id,
    cacheBounds: true
  }
  const SelectableChild = Selectable(Child, options)
  describe("higher-order container creation", () => {
    it("should make a component", () => {
      const Thing = Selection(Blah)
      Thing.displayName.should.be.eql('Selection(A)')

      const stuff = $(<Thing>
hi
</Thing>).render()

      stuff.find('.foo').text().should.eql('hi')

      const nextstuff = $(<Thing name="Greg" />).render()

      nextstuff.find('p').text().should.eql('hi Greg')
    })

    it("should error if a non-component is passed in", () => {
      expect(() => {
        Selection(false)
      }).to.throw('Component is not a class, must be a stateful React Component class')
    })

    it("should force a container div for ", () => {
      const Thing = Selection(() => null, { containerDiv: false })

      const stuff = $(<Thing />).render()
      expect(stuff[0].containerDiv).to.be.true
    })

    it("should pull displayname from displayName", () => {
      const Thing = Selection( class {
        static displayName = 'Hi'
        render() {}
      })
      Thing.displayName.should.equal('Selection(Hi)')
    })

    it("should pull displayname from name if displayName is not present", () => {
      const Thing = Selection( class Hi {
        render() {}
      })
      Thing.displayName.should.match(/^Selection\((Hi|Component)\)$/) // IE 10/11
    })
  })

  describe("updateState", () => {
    const Thing = Selection(Blah, {
      sorter: (a, b) => a > b ? 1 : (a  {
      stuff = $(<Thing />).render()
      component = stuff[0]
    })
    afterEach(() => {
      stuff.unmount()
    })

    it("should keep state the same if passed null", () => {
      component.setState({
        selecting: false,
        selectedNodes: { 1: 1, 2: 2, 3: 3 },
        selectedValues: { 4: 4, 5: 5, 6: 6 },
        containerBounds: component.bounds
      })

      component.state.should.eql({
        selecting: false,
        selectedNodes: { 1: 1, 2: 2, 3: 3},
        selectedNodeList: [],
        selectedValues: { 4: 4, 5: 5, 6: 6},
        selectedValueList: [],
        containerBounds: component.bounds
      })

      component.updateState(null, null, null)

      component.state.should.eql({
        selecting: false,
        selectedNodes: { 1: 1, 2: 2, 3: 3},
        selectedNodeList: [],
        selectedValues: { 4: 4, 5: 5, 6: 6},
        selectedValueList: [],
        containerBounds: component.bounds
      })
    })
    it("should set values if passed", () => {
      component.setState({
        selecting: false,
        selectedNodes: { 1: 1, 2: 2, 3: 3},
        selectedValues: { 4: 4, 5: 5, 6: 6},
        containerBounds: component.bounds
      })

      component.state.should.eql({
        selecting: false,
        selectedNodes: { 1: 1, 2: 2, 3: 3},
        selectedNodeList: [],
        selectedValues: { 4: 4, 5: 5, 6: 6},
        selectedValueList: [],
        containerBounds: component.bounds
      })

      component.updateState(true, { hi: 'hi' }, { there: 'there' })

      component.state.should.eql({
        selecting: true,
        selectedNodes: { hi: 'hi' },
        selectedNodeList: [],
        selectedValues: { there: 'there' },
        selectedValueList: [],
        containerBounds: component.bounds
      })
    })

    it("should call onSelectSlot if constantSelect is enabled", () => {
      const spy = sinon.spy()
      stuff = $((
        <Thing selectable constantSelect onSelectSlot={spy}>
          <SelectableChild value="hi" key={1} />
          <SelectableChild value="hi2" key={2} />
          <SelectableChild value="hi3" key={3} />
        </Thing>
          )).render()
      const children = stuff.find(SelectableChild)
      component = stuff[0]
      component.bounds = { hi: 'hi' }
      const selectable1 = children[0]
      const selectable2 = children[1]
      const selectable3 = children[2]

      component.updateState(null, {
        3: {node: selectable3},
        1: {node: selectable1},
        2: {node: selectable2}
      }, {
        3: 'hi3',
        1: 'hi',
        2: 'hi2'
      })

      expect(spy.called).to.be.true

      spy.args[0].should.have.length(5)
      spy.args[0][0].should.be.eql({
        3: 'hi3',
        1: 'hi',
        2: 'hi2'
      })
      expect(spy.args[0][1]()).to.eql({
        3: {node: selectable3},
        1: {node: selectable1},
        2: {node: selectable2}
      })
      expect(spy.args[0][2]).to.eql(['hi', 'hi2', 'hi3'])
      expect(spy.args[0][3]()).to.eql([
        {node: selectable1},
        {node: selectable2},
        {node: selectable3}
      ])
      expect(spy.args[0][4]).to.eql({hi: 'hi'})
    })
    it("should not call onSelectSlot if constantSelection is disabled", () => {
      const spy = sinon.spy()
      stuff = $((
        <Thing selectable onSelectSlot={spy}>
          <SelectableChild value="hi" key={1} />
          <SelectableChild value="hi2" key={2} />
          <SelectableChild value="hi3" key={3} />
        </Thing>
      )).render()
      const children = stuff.find(SelectableChild)
      component = stuff[0]
      component.bounds = { hi: 'hi' }
      const selectable1 = children[0]
      const selectable2 = children[1]
      const selectable3 = children[2]

      component.updateState(null, {
        3: {node: selectable3},
        1: {node: selectable1},
        2: {node: selectable2}
      }, {
        3: 'hi3',
        1: 'hi',
        2: 'hi2'
      })

      expect(spy.called).to.be.false
    })
  })

  describe("propagateFinishedSelect", () => {
    const Thing = Selection(Blah, {
      sorter: (a, b) => a > b ? 1 : (a  {
      spy = sinon.spy()
      stuff = $((
        <Thing selectable constantSelect onFinishSelect={spy}>
        <SelectableChild value="hi" key={1}/>
        <SelectableChild value="hi2" key={2}/>
        <SelectableChild value="hi3" key={3}/>
        </Thing>
      )).render()
      component = stuff[0]
      const children = stuff.find(SelectableChild)
      component = stuff[0]
      component.bounds = {hi: 'hi'}
      selectable1 = children[0]
      selectable2 = children[1]
      selectable3 = children[2]
    })

    afterEach(() => {
      stuff.unmount()
    })

    it("should return our info", () => {
      component.updateState(null, {
        3: {node: selectable3},
        1: {node: selectable1},
        2: {node: selectable2}
      }, {
        3: 'hi3',
        1: 'hi',
        2: 'hi2'
      })

      component.propagateFinishedSelect()

      expect(spy.called).to.be.true

      spy.args[0].should.have.length(5)
      spy.args[0][0].should.be.eql({
        3: 'hi3',
        1: 'hi',
        2: 'hi2'
      })
      expect(spy.args[0][1]()).to.eql({
        3: {node: selectable3},
        1: {node: selectable1},
        2: {node: selectable2}
      })
      expect(spy.args[0][2]).to.eql(['hi', 'hi2', 'hi3'])
      expect(spy.args[0][3]()).to.eql([
        {node: selectable1},
        {node: selectable2},
        {node: selectable3}
      ])
      expect(spy.args[0][4]).to.eql({hi: 'hi'})
    })
  })

  describe("invalid", () => {
    const Thing = Selection(Blah)
    let spy
    let stuff
    let component

    beforeEach(() => {
      spy = sinon.spy()
    })
    afterEach(() => {
      stuff.unmount()
    })

    it("should call onTouchStart if defined and event is a touch event", () => {
      stuff = $(<Thing onTouchStart={spy}/>).render(true)

      component = stuff[0]
      component.invalid('hi', 'touchstart')

      expect(spy.called).to.be.true
    })
    it("should call onMouseDown if defined and event is a mouse event", () => {
      stuff = $(<Thing onMouseDown={spy}/>).render(true)

      component = stuff[0]
      component.invalid('hi', 'mousedown')

      expect(spy.called).to.be.true
    })
  })

  describe("start", () => {
    const Thing = Selection(Blah)
    let spy
    let stuff
    let component

    beforeEach(() => {
      spy = sinon.spy()
    })

    it("should call select if constantSelect is active", () => {
      stuff = $(<Thing constantSelect />).render()

      component = stuff[0]

      component.selectionManager.select = spy
      component.start(1, 2, 3)

      expect(spy.called).to.be.true
    })

    it("should call deselect if constantSelect is not active", () => {
      stuff = $(<Thing />).render()

      component = stuff[0]

      component.selectionManager.deselect = spy
      component.start(1, 2, 3)

      expect(spy.called).to.be.true
    })
  })

  describe("cancel", () => {
    const Thing = Selection(Blah)
    let spy
    let stuff
    let component

    beforeEach(() => {
      spy = sinon.spy()
      stuff = $(<Thing />).render()
      component = stuff[0]
    })

    it("should call deselect", () => {
      component.selectionManager.deselect = spy

      component.cancel()

      expect(spy.called).to.be.true
    })

    it("should call propageFinishedSelect", () => {
      component.propagateFinishedSelect = spy
      component.cancel()

      expect(spy.called).to.be.true
    })

    it("should turn off selection", () => {
      component.setState = spy
      component.cancel()

      expect(spy.called).to.be.true

      spy.args[0][0].should.eql({ selecting: false })
    })
  })

  describe("end", () => {
    const Thing = Selection(Blah)

    it("should call propagateFinishedSelect and deselect if constantSelect is on", () => {
      const stuff = $(<Thing selectable constantSelect />).render()
      const component = stuff[0]
      component.propagateFinishedSelect = sinon.spy()
      component.selectionManager.deselect = sinon.spy()
      component.end(1, 2, 3)

      expect(component.propagateFinishedSelect.called).to.be.true
      expect(component.selectionManager.deselect.called).to.be.true
    })
    it("should select any items in the selection rectangle, and propagateFinishedSelect", () => {
      const stuff = $(<Thing selectable />).render()
      const component = stuff[0]
      component.propagateFinishedSelect = sinon.spy()
      component.selectionManager.select = sinon.spy()
      component.end(1, 2, 3)

      expect(component.propagateFinishedSelect.called).to.be.true
      expect(component.selectionManager.select.called).to.be.true
    })
  })

  describe("change", () => {
    const Thing = Selection(Blah)

    it("should enable selection", () => {
      const stuff = $(<Thing />).render()
      const component = stuff[0]
      component.setState = sinon.spy()

      component.change(1)

      expect(component.setState.called).to.be.true
      component.setState.args[0][0].should.eql({
        selecting: true
      })
    })
    it("should call select if constantSelect is enabled", () => {
      const stuff = $(<Thing constantSelect />).render()
      const component = stuff[0]
      component.selectionManager.select = sinon.spy()

      component.change(1)

      expect(component.selectionManager.select.called).to.be.true
    })
  })

  describe("makeInputManager", () => {
    const Thing = Selection(Blah)

    it("should do nothing if ref is null", () => {
      const spy = sinon.spy()

      const im = function(...args) {
        spy(...args)
      }

      const stuff = $(<Thing />).render()
      stuff[0].makeInputManager(null, im)

      expect(spy.called).to.be.false
    })
    it("should set up inputManager and ref on first valid call", () => {
      const spy = sinon.spy()
      let watch = null

      const im = function(...args) {
        spy(...args)
        watch = this
      }

      const stuff = $(<Thing />).render()
      const component = stuff[0]
      component.makeInputManager('hi', im)

      expect(spy.called).to.be.true
      watch.should.equal(component.inputManager)
      component.ref.should.equal('hi')
    })
    it("should do nothing if ref is the same as a previous call", () => {
      const spy = sinon.spy()

      const im = function(...args) {
        spy(...args)
      }

      const stuff = $(<Thing />).render()
      const component = stuff[0]
      component.makeInputManager('hi', im)
      component.makeInputManager('hi', im)

      expect(spy.calledOnce).to.be.true
    })
    it("should umount inputManager and re-set if ref changes", () => {
      const spy = sinon.spy()
      const spy2 = sinon.spy()

      class im {
        constructor(...args) {
          spy(...args)
        }
        unmount(...args) {
          spy2(...args)
        }
      }

      const stuff = $(<Thing />).render()
      const component = stuff[0]
      component.makeInputManager('hi', im)
      component.makeInputManager('hi2', im)

      expect(spy.calledTwice).to.be.true
      expect(spy2.called).to.be.true
    })
  })

  describe("render", () => {
    it("should create a container div if containerDiv is specified")
    it("should pass in all props")
    describe("container div", () => {
      it("should capture mousedown")
      it("should capture touchstart")
    })
    describe("raw component", () => {
      it("should capture mousedown")
      it("should capture touchstart")
    })
  })
})
<|endoftext|>


<commit_before>// Karma configuration
// Generated on Thu Mar 03 2016 19:57:50 GMT-0600 (CST)
var Set = require('collections/set');

// Disable security warnings
process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = '1';

module.exports = function (config) {
  // Set up default files to test against
  var karmaTest = 'karma-test.js';
  var successTest = 'success-test.js';
  var phantomJsTest = 'phantomjs-test.js';
  var eofCommentTest = 'eof-comment-test.js';
  var failureTest = 'failure-test.js';
  var sourceMapTest = 'source-map-test.js';
  var uncaughtExceptionTest = 'uncaught-exception-test.js';
  var mainRequireTest = 'main-require-test.js';
  var nodeCommonTest = 'node-common-test.js';
  var nodeRequireTest = 'node-require-test.js';
  var nodeScriptSrcTest = 'node-script-src-test.js';
  var customContextFileTest = 'custom-context-file-test.js';
  var filenameOverrideTest = 'filename-override-test.js';
  var testFiles = ['*-test.js'];
  var excludeFiles = new Set([
    customContextFileTest, failureTest, filenameOverrideTest, karmaTest,
    nodeRequireTest, phantomJsTest, sourceMapTest, uncaughtExceptionTest,
    mainRequireTest]);

  // If we are testing uncaught exceptions, then update our tests
  if (process.env.TEST_TYPE === 'UNCAUGHT_EXCEPTION') {
    testFiles = [uncaughtExceptionTest];
    excludeFiles.delete(uncaughtExceptionTest);
  } else if (process.env.TEST_TYPE === 'EOF_COMMENT') {
    testFiles = [eofCommentTest];
    excludeFiles.delete(eofCommentTest);
  } else if (process.env.TEST_TYPE === 'FAILURE') {
    testFiles = [failureTest];
    excludeFiles.delete(failureTest);
  } else if (process.env.TEST_TYPE === 'KARMA') {
    testFiles = [karmaTest];
    excludeFiles.delete(karmaTest);
  } else if (process.env.TEST_TYPE === 'PHANTOMJS') {
    testFiles = [successTest, phantomJsTest];
    excludeFiles = new Set();
  } else if (process.env.TEST_TYPE === 'SOURCE_MAP') {
    testFiles = [sourceMapTest];
    excludeFiles.delete(sourceMapTest);
  } else if (process.env.TEST_TYPE === 'CUSTOM_CONTEXT_FILE') {
    testFiles = [customContextFileTest];
    excludeFiles.delete(customContextFileTest);
  } else if (process.env.TEST_TYPE === 'FILENAME_OVERRIDE') {
    testFiles = [filenameOverrideTest];
    excludeFiles.delete(filenameOverrideTest);
  } else if (process.env.TEST_TYPE === 'MAIN_REQUIRE') {
    testFiles = [mainRequireTest];
    excludeFiles.delete(mainRequireTest);
  } else if (process.env.TEST_TYPE === 'NODE_REQUIRE') {
    testFiles = [nodeCommonTest, nodeRequireTest];
    excludeFiles.add(nodeScriptSrcTest);
    excludeFiles.delete(nodeRequireTest);
  } else if (process.env.TEST_TYPE) {
    throw new Error('Unrecognized test type "' + process.env.TEST_TYPE + '"');
  }

  // Define our config
  config.set({
    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',

    // Custom context/debug files and launchers
    customContextFile: process.env.TEST_TYPE === 'CUSTOM_CONTEXT_FILE' ?
      __dirname + '/test-files/custom-context.html' : null,
    customDebugFile: process.env.TEST_TYPE === 'CUSTOM_CONTEXT_FILE' ?
      __dirname + '/test-files/custom-debug.html' : null,
    customLaunchers: {
      // TODO: Update some tests to not use `WithNodeIntegration`
      ElectronWithNodeIntegration: {
        base: 'Electron',
        browserWindowOptions: {
          webPreferences: {
            nodeIntegration: true
          }
        }
      },
      ElectronMainRequire: {
        base: 'ElectronWithNodeIntegration',
        require: __dirname + '/test-files/main-require.js'
      },
      VisibleElectron: {
        base: 'ElectronWithNodeIntegration',
        flags: ['--show']
      }
    },
    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['mocha'],

    // list of files / patterns to load in the browser
    files: testFiles,

    // list of files to exclude
    exclude: excludeFiles.toArray(),

    browserNoActivityTimeout: 2000,
    client: {
      // DEV: We use `client` as these options affect the client side of `karma`
      //   Based on https://github.com/karma-runner/karma-mocha/tree/v1.1.1#configuration
      __filenameOverride: process.env.TEST_TYPE === 'FILENAME_OVERRIDE' ?
        __dirname + '/test-files/filename-override-context.html' : null,
      loadScriptsViaRequire: process.env.TEST_TYPE === 'NODE_REQUIRE',
      useIframe: false
    },

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
      '*-test.js': ['electron']
    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['ElectronWithNodeIntegration'],

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false,

    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: Infinity,

    // Load in our module as a plugin
    // https://github.com/karma-runner/karma-chrome-launcher/blob/v0.2.2/examples/simple/karma.conf.js
    plugins: [
        require('../../'),
        'karma-mocha',
        'karma-phantomjs-launcher'
    ]
  });
};
<commit_msg>Fixed up multi-level launcher inheritance issue<commit_after>// Karma configuration
// Generated on Thu Mar 03 2016 19:57:50 GMT-0600 (CST)
var Set = require('collections/set');

// Disable security warnings
process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = '1';

module.exports = function (config) {
  // Set up default files to test against
  var karmaTest = 'karma-test.js';
  var successTest = 'success-test.js';
  var phantomJsTest = 'phantomjs-test.js';
  var eofCommentTest = 'eof-comment-test.js';
  var failureTest = 'failure-test.js';
  var sourceMapTest = 'source-map-test.js';
  var uncaughtExceptionTest = 'uncaught-exception-test.js';
  var mainRequireTest = 'main-require-test.js';
  var nodeCommonTest = 'node-common-test.js';
  var nodeRequireTest = 'node-require-test.js';
  var nodeScriptSrcTest = 'node-script-src-test.js';
  var customContextFileTest = 'custom-context-file-test.js';
  var filenameOverrideTest = 'filename-override-test.js';
  var testFiles = ['*-test.js'];
  var excludeFiles = new Set([
    customContextFileTest, failureTest, filenameOverrideTest, karmaTest,
    nodeRequireTest, phantomJsTest, sourceMapTest, uncaughtExceptionTest,
    mainRequireTest]);

  // If we are testing uncaught exceptions, then update our tests
  if (process.env.TEST_TYPE === 'UNCAUGHT_EXCEPTION') {
    testFiles = [uncaughtExceptionTest];
    excludeFiles.delete(uncaughtExceptionTest);
  } else if (process.env.TEST_TYPE === 'EOF_COMMENT') {
    testFiles = [eofCommentTest];
    excludeFiles.delete(eofCommentTest);
  } else if (process.env.TEST_TYPE === 'FAILURE') {
    testFiles = [failureTest];
    excludeFiles.delete(failureTest);
  } else if (process.env.TEST_TYPE === 'KARMA') {
    testFiles = [karmaTest];
    excludeFiles.delete(karmaTest);
  } else if (process.env.TEST_TYPE === 'PHANTOMJS') {
    testFiles = [successTest, phantomJsTest];
    excludeFiles = new Set();
  } else if (process.env.TEST_TYPE === 'SOURCE_MAP') {
    testFiles = [sourceMapTest];
    excludeFiles.delete(sourceMapTest);
  } else if (process.env.TEST_TYPE === 'CUSTOM_CONTEXT_FILE') {
    testFiles = [customContextFileTest];
    excludeFiles.delete(customContextFileTest);
  } else if (process.env.TEST_TYPE === 'FILENAME_OVERRIDE') {
    testFiles = [filenameOverrideTest];
    excludeFiles.delete(filenameOverrideTest);
  } else if (process.env.TEST_TYPE === 'MAIN_REQUIRE') {
    testFiles = [mainRequireTest];
    excludeFiles.delete(mainRequireTest);
  } else if (process.env.TEST_TYPE === 'NODE_REQUIRE') {
    testFiles = [nodeCommonTest, nodeRequireTest];
    excludeFiles.add(nodeScriptSrcTest);
    excludeFiles.delete(nodeRequireTest);
  } else if (process.env.TEST_TYPE) {
    throw new Error('Unrecognized test type "' + process.env.TEST_TYPE + '"');
  }

  // Define our config
  config.set({
    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',

    // Custom context/debug files and launchers
    customContextFile: process.env.TEST_TYPE === 'CUSTOM_CONTEXT_FILE' ?
      __dirname + '/test-files/custom-context.html' : null,
    customDebugFile: process.env.TEST_TYPE === 'CUSTOM_CONTEXT_FILE' ?
      __dirname + '/test-files/custom-debug.html' : null,
    customLaunchers: {
      // TODO: Update some tests to not use `WithNodeIntegration`
      ElectronWithNodeIntegration: {
        base: 'Electron',
        browserWindowOptions: {
          webPreferences: {
            nodeIntegration: true
          }
        }
      },
      ElectronMainRequire: {
        base: 'Electron',
        browserWindowOptions: {
          webPreferences: {
            nodeIntegration: true
          }
        },
        require: __dirname + '/test-files/main-require.js'
      },
      VisibleElectron: {
        base: 'Electron',
        browserWindowOptions: {
          webPreferences: {
            nodeIntegration: true
          }
        },
        flags: ['--show']
      }
    },
    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['mocha'],

    // list of files / patterns to load in the browser
    files: testFiles,

    // list of files to exclude
    exclude: excludeFiles.toArray(),

    browserNoActivityTimeout: 2000,
    client: {
      // DEV: We use `client` as these options affect the client side of `karma`
      //   Based on https://github.com/karma-runner/karma-mocha/tree/v1.1.1#configuration
      __filenameOverride: process.env.TEST_TYPE === 'FILENAME_OVERRIDE' ?
        __dirname + '/test-files/filename-override-context.html' : null,
      loadScriptsViaRequire: process.env.TEST_TYPE === 'NODE_REQUIRE',
      useIframe: false
    },

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
      '*-test.js': ['electron']
    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['ElectronWithNodeIntegration'],

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false,

    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: Infinity,

    // Load in our module as a plugin
    // https://github.com/karma-runner/karma-chrome-launcher/blob/v0.2.2/examples/simple/karma.conf.js
    plugins: [
        require('../../'),
        'karma-mocha',
        'karma-phantomjs-launcher'
    ]
  });
};
<|endoftext|>


<commit_before>'use strict';

const environment = require('./lib/environment');

module.exports.config = {
  app_name: ['public-radio-api'],
  license_key: environment.get('new_relic_key'),
  logging: {
    level: 'info'
  }
};
<commit_msg>Removed New Relic config file<commit_after><|endoftext|>


<commit_before>import Axis from "models/axis";
import * as utils from "base/utils";

/*
 * VIZABI Size Model
 */

const SizeModel = Axis.extend({

  /**
   * Default values for this model
   */
  getClassDefaults() {
    const defaults = {
      use: null,
      which: null,
      domainMin: null,
      domainMax: null,
      zoomedMin: null,
      zoomedMax: null,
      extent: [0, 0.85],
      scaleType: null,
      allow: {
        scales: ["linear", "log", "genericLog", "pow"]
      }
    };
    return utils.deepExtend(this._super(), defaults);
  },

  _type: "size",

  buildScale() {
    //do whatever axis.buildScale does
    this._super();
    //but then also clamp a numeric scale
    if (this.scaleType !== "ordinal") this.scale.clamp(true);

  },

  autoGenerateModel() {
    if (this.which == null) {
      let concept;
      if (this.autogenerate) {
        concept = this.dataSource
          .getConceptByIndex(this.autogenerate.conceptIndex, this.autogenerate.conceptType);

        if (concept) {
          this.which = concept.concept;
          this.use = "indicator";
          this.scaleType = "linear";
        }

      }
      if (!concept) {
        this.which = "_default";
        this.use = "constant";
        this.scaleType = "ordinal";
      }
    }
    if (this.scaleType == null) {
      this.scaleType = this.dataSource
        .getConceptprops(this.which).scales[0];
    }
  }

});

export default SizeModel;
<commit_msg>Allow size to be chosen constant<commit_after>import Axis from "models/axis";
import * as utils from "base/utils";

/*
 * VIZABI Size Model
 */

const SizeModel = Axis.extend({

  /**
   * Default values for this model
   */
  getClassDefaults() {
    const defaults = {
      use: null,
      which: null,
      domainMin: null,
      domainMax: null,
      zoomedMin: null,
      zoomedMax: null,
      extent: [0, 0.85],
      scaleType: null,
      allow: {
        scales: ["ordinal", "linear", "log", "genericLog", "pow"]
      }
    };
    return utils.deepExtend(this._super(), defaults);
  },

  _type: "size",

  buildScale() {
    //do whatever axis.buildScale does
    this._super();
    //but then also clamp a numeric scale
    if (this.scaleType !== "ordinal") this.scale.clamp(true);

  },

  autoGenerateModel() {
    if (this.which == null) {
      let concept;
      if (this.autogenerate) {
        concept = this.dataSource
          .getConceptByIndex(this.autogenerate.conceptIndex, this.autogenerate.conceptType);

        if (concept) {
          this.which = concept.concept;
          this.use = "indicator";
          this.scaleType = "linear";
        }

      }
      if (!concept) {
        this.which = "_default";
        this.use = "constant";
        this.scaleType = "ordinal";
      }
    }
    if (this.scaleType == null) {
      this.scaleType = this.dataSource
        .getConceptprops(this.which).scales[0];
    }
  }

});

export default SizeModel;
<|endoftext|>


<commit_before>/**
 * @author Pedro Sanders
 * @since v1
 */
const Processor = require('@routr/core/processor/processor')
const ContextStorage = require('@routr/core/context_storage')
const getConfig = require('@routr/core/config_util')
const Registry = require('@routr/registry/registry')
const RestService = require('@routr/rest/rest')

const System = Java.type('java.lang.System')
const SipFactory = Java.type('javax.sip.SipFactory')
const Properties = Java.type('java.util.Properties')
const LogManager = Java.type('org.apache.logging.log4j.LogManager')

const LOG = LogManager.getLogger()
const ANSI_GREEN = "\u001B[32m"
const ANSI_YELLOW = "\u001B[33m"
const ANSI_RESET = "\u001B[0m"

class Server {

    constructor(locator, registrar, dataAPIs) {
        this.locator = locator
        this.registrar = registrar
        this.dataAPIs = dataAPIs
        this.contextStorage = new ContextStorage()
        this.config = getConfig()
        // Not sure if this is a good idea in terms of performance
        this.host = this.config.spec.bindAddr
    }

    buildSipProvider(sipStack, transport) {
        const defListeningPoint = sipStack.createListeningPoint(transport[0].port, transport[0].protocol.toLowerCase())
        const sipProvider = sipStack.createSipProvider(defListeningPoint)

        for (const key in transport) {
            const curTransport = transport[key]
            const proto = curTransport.protocol.toLowerCase()

            if ((proto === 'wss' || proto === 'tls') && !this.config.spec.securityContext) {
                LOG.warn(ANSI_YELLOW + 'Security context could not found. Ignoring protocol: ' + proto + ANSI_RESET)
                continue
            }

            if (curTransport.bindAddr === undefined) {
                curTransport.bindAddr = this.host
            }

            const lp = sipStack.createListeningPoint(curTransport.bindAddr, curTransport.port, proto)
            sipProvider.addListeningPoint(lp)

            LOG.info('Listening  on ' + ANSI_GREEN  + curTransport.bindAddr
                + ':' + curTransport.port
                    + ' [' + proto + ']'
                        + ANSI_RESET)
        }

        return sipProvider
    }

    showExternInfo() {
        if (this.config.spec.externAddr) {
            LOG.info("ExternAddr is " + ANSI_GREEN  + this.config.spec.externAddr + ANSI_RESET)

            if(this.config.spec.localnets) {
                LOG.info("Localnets  is " + ANSI_GREEN  + this.config.spec.localnets.join(",") + ANSI_RESET)
            }
        }
    }

    setup() {
        this.showExternInfo()

        if(this.config.spec.securityContext.debugging) {
            Java.type('java.lang.System').setProperty('javax.net.debug', 'ssl')
        }

        const sipFactory = SipFactory.getInstance()
        sipFactory.setPathName('gov.nist')

        this.sipStack = sipFactory.createSipStack(this.getProperties())

        const sipProvider = this.buildSipProvider(this.sipStack,
          this.config.spec.transport)

        this.registry = new Registry(sipProvider, this.dataAPIs)

        const processor = new Processor(sipProvider,
            this.locator,
                this.registry,
                    this.registrar, this.dataAPIs, this.contextStorage)

        sipProvider.addSipListener(processor.listener)
    }

    start()  {
      LOG.info('Starting Routr')
        this.setup()
        this.locator.start()
        this.registry.start()
        this.restService = new RestService(this, this.locator, this.registry, this.dataAPIs)
        this.restService.start()
    }

    stop() {
        LOG.info('Stopping server')
        this.restService.stop()
        this.sipStack.stop()
        this.locator.stop()
        System.exit(0)
    }

    getProperties() {
        const properties = new Properties()
        // See https://github.com/RestComm/jain-sip/blob/master/src/gov/nist/javax/sip/SipStackImpl.java for
        // more options
        properties.setProperty('javax.sip.STACK_NAME', 'routr')
        // Default host
        properties.setProperty('javax.sip.IP_ADDRESS', this.host)
        properties.setProperty('javax.sip.AUTOMATIC_DIALOG_SUPPORT', 'OFF')
        // Guard against denial of service attack.
        properties.setProperty('gov.nist.javax.sip.MAX_MESSAGE_SIZE', '1048576')
        // Drop the client connection after we are done with the transaction.
        properties.setProperty('gov.nist.javax.sip.CACHE_CLIENT_CONNECTIONS', 'false')
        properties.setProperty('gov.nist.javax.sip.TRACE_LEVEL', this.config.spec.logging.traceLevel)
        properties.setProperty('gov.nist.javax.sip.MESSAGE_PROCESSOR_FACTORY', 'gov.nist.javax.sip.stack.NioMessageProcessorFactory')
        properties.setProperty('gov.nist.javax.sip.PATCH_SIP_WEBSOCKETS_HEADERS', 'false')
        properties.setProperty('gov.nist.javax.sip.REENTRANT_LISTENER', 'true')
        properties.setProperty('gov.nist.javax.sip.NIO_BLOCKING_MODE', 'NONBLOCKING')

        // See https://groups.google.com/forum/#!topic/mobicents-public/U_c7aLAJ_MU for useful info
        if (this.config.spec.securityContext) {
            properties.setProperty('gov.nist.javax.sip.TLS_CLIENT_PROTOCOLS', this.config.spec.securityContext.client.protocols.join())
            // This must be set to 'Disabled' when using WSS
            properties.setProperty('gov.nist.javax.sip.TLS_CLIENT_AUTH_TYPE', this.config.spec.securityContext.client.authType)
            properties.setProperty('javax.net.ssl.keyStore', this.config.spec.securityContext.keyStore)
            properties.setProperty('javax.net.ssl.trustStore', this.config.spec.securityContext.trustStore)
            properties.setProperty('javax.net.ssl.keyStorePassword', this.config.spec.securityContext.keyStorePassword)
            properties.setProperty('javax.net.ssl.keyStoreType', this.config.spec.securityContext.keyStoreType)
        }
        return properties
    }

}

module.exports = Server
<commit_msg>Allows to overwrite stack properties from external file<commit_after>/**
 * @author Pedro Sanders
 * @since v1
 */
const Processor = require('@routr/core/processor/processor')
const ContextStorage = require('@routr/core/context_storage')
const getConfig = require('@routr/core/config_util')
const Registry = require('@routr/registry/registry')
const RestService = require('@routr/rest/rest')

const FileInputStream = Java.type('java.io.FileInputStream')
const System = Java.type('java.lang.System')
const SipFactory = Java.type('javax.sip.SipFactory')
const Properties = Java.type('java.util.Properties')
const LogManager = Java.type('org.apache.logging.log4j.LogManager')

const LOG = LogManager.getLogger()
const ANSI_GREEN = "\u001B[32m"
const ANSI_YELLOW = "\u001B[33m"
const ANSI_RESET = "\u001B[0m"

class Server {

    constructor(locator, registrar, dataAPIs) {
        this.locator = locator
        this.registrar = registrar
        this.dataAPIs = dataAPIs
        this.contextStorage = new ContextStorage()
        this.config = getConfig()
        // Not sure if this is a good idea in terms of performance
        this.host = this.config.spec.bindAddr
    }

    buildSipProvider(sipStack, transport) {
        const defListeningPoint = sipStack.createListeningPoint(transport[0].port, transport[0].protocol.toLowerCase())
        const sipProvider = sipStack.createSipProvider(defListeningPoint)

        for (const key in transport) {
            const curTransport = transport[key]
            const proto = curTransport.protocol.toLowerCase()

            if ((proto === 'wss' || proto === 'tls') && !this.config.spec.securityContext) {
                LOG.warn(ANSI_YELLOW + 'Security context could not found. Ignoring protocol: ' + proto + ANSI_RESET)
                continue
            }

            if (curTransport.bindAddr === undefined) {
                curTransport.bindAddr = this.host
            }

            const lp = sipStack.createListeningPoint(curTransport.bindAddr, curTransport.port, proto)
            sipProvider.addListeningPoint(lp)

            LOG.info('Listening  on ' + ANSI_GREEN  + curTransport.bindAddr
                + ':' + curTransport.port
                    + ' [' + proto + ']'
                        + ANSI_RESET)
        }

        return sipProvider
    }

    showExternInfo() {
        if (this.config.spec.externAddr) {
            LOG.info("ExternAddr is " + ANSI_GREEN  + this.config.spec.externAddr + ANSI_RESET)

            if(this.config.spec.localnets) {
                LOG.info("Localnets  is " + ANSI_GREEN  + this.config.spec.localnets.join(",") + ANSI_RESET)
            }
        }
    }

    setup() {
        this.showExternInfo()

        if(this.config.spec.securityContext.debugging) {
            Java.type('java.lang.System').setProperty('javax.net.debug', 'ssl')
        }

        const sipFactory = SipFactory.getInstance()
        sipFactory.setPathName('gov.nist')

        this.sipStack = sipFactory.createSipStack(this.getProperties())

        const sipProvider = this.buildSipProvider(this.sipStack,
          this.config.spec.transport)

        this.registry = new Registry(sipProvider, this.dataAPIs)

        const processor = new Processor(sipProvider,
            this.locator,
                this.registry,
                    this.registrar, this.dataAPIs, this.contextStorage)

        sipProvider.addSipListener(processor.listener)
    }

    start()  {
      LOG.info('Starting Routr')
        this.setup()
        this.locator.start()
        this.registry.start()
        this.restService = new RestService(this, this.locator, this.registry, this.dataAPIs)
        this.restService.start()
    }

    stop() {
        LOG.info('Stopping server')
        this.restService.stop()
        this.sipStack.stop()
        this.locator.stop()
        System.exit(0)
    }

    getProperties() {
        let properties = new Properties()
        // for more options see:
        // https://github.com/RestComm/jain-sip/blob/master/src/gov/nist/javax/sip/SipStackImpl.java
        properties.setProperty('javax.sip.STACK_NAME', 'routr')
        properties.setProperty('javax.sip.AUTOMATIC_DIALOG_SUPPORT', 'OFF')
        properties.setProperty('gov.nist.javax.sip.MESSAGE_PROCESSOR_FACTORY', 'gov.nist.javax.sip.stack.NioMessageProcessorFactory')
        properties.setProperty('gov.nist.javax.sip.PATCH_SIP_WEBSOCKETS_HEADERS', 'false')
        properties.setProperty('gov.nist.javax.sip.CACHE_CLIENT_CONNECTIONS', 'true')
        properties.setProperty('gov.nist.javax.sip.REENTRANT_LISTENER', 'true')
        properties.setProperty('gov.nist.javax.sip.NIO_BLOCKING_MODE', 'NONBLOCKING')

        // Guard against denial of service attack.
        properties.setProperty('gov.nist.javax.sip.MAX_MESSAGE_SIZE', '1048576')
        properties.setProperty('gov.nist.javax.sip.LOG_MESSAGE_CONTENT', 'false')
        properties.setProperty('gov.nist.javax.sip.TRACE_LEVEL', this.config.spec.logging.traceLevel)

        // Default host
        properties.setProperty('javax.sip.IP_ADDRESS', this.host)

        // See https://groups.google.com/forum/#!topic/mobicents-public/U_c7aLAJ_MU for useful info
        if (this.config.spec.securityContext) {
            properties.setProperty('gov.nist.javax.sip.TLS_CLIENT_PROTOCOLS', this.config.spec.securityContext.client.protocols.join())
            // This must be set to 'Disabled' when using WSS
            properties.setProperty('gov.nist.javax.sip.TLS_CLIENT_AUTH_TYPE', this.config.spec.securityContext.client.authType)
            properties.setProperty('javax.net.ssl.keyStore', this.config.spec.securityContext.keyStore)
            properties.setProperty('javax.net.ssl.trustStore', this.config.spec.securityContext.trustStore)
            properties.setProperty('javax.net.ssl.keyStorePassword', this.config.spec.securityContext.keyStorePassword)
            properties.setProperty('javax.net.ssl.keyStoreType', this.config.spec.securityContext.keyStoreType)
        }

        try {
            const filesPath = this.config.spec.dataSource.parameters.path
            properties.load(new FileInputStream(filesPath + '/stack.properties'))
        } catch(e) {
        }

        return properties
    }

}

module.exports = Server
<|endoftext|>


<commit_before>import * as util from './util'
import { castValue } from './types'
import { writeDatabase } from './sqljs-handler'

export function parseResponse (contents) {
  if (!contents || !contents.length) return []

  let { columns, values } = contents[0]
  let results = []

  for (let i = 0; i < values.length; i++) {
    let line = {}

    for (let j = 0; j < columns.length; j++) {
      line[columns[j]] = values[i][j]
    }

    results.push(line)
  }

  return results
}

export function buildOrder (partial, order) {
  if (util.isString(order)) {
    if (order === 'random') {
      return partial.orderByRaw('RANDOM()')
    }
    return partial.orderBy(order)
  }

  if (util.isArray(order)) {
    let length = order.length
    if (length === 1 || length === 2) {
      return partial.orderBy(...order)
    }
  }

  return partial
}

export function buildWhere (partial, where) {
  let [isValid, arrayLength] = isValidWhere(where)
  if (!isValid) return partial

  let cast = where
  if (!arrayLength) {
    cast = util.map(where, castValue)
  } else {
    let i = arrayLength - 1
    cast[i] = castValue(where[i])
  }

  if (!arrayLength) return partial.where(cast)
  return partial.where(...cast)
}

export function isValidWhere (where) {
  if (util.isArray(where)) {
    let len = where.length
    return [len === 2 || len === 3, len]
  }

  if (util.isObject(where)) return [true]

  return [false]
}

export function getConflictString (conflict) {
  switch (conflict.toLowerCase()) {
    case 'fail': return ' or fail '
    case 'abort': return ' or abort '
    case 'ignore': return ' or ignore '
    case 'replace': return ' or replace '
    case 'rollback': return ' or rollback '
    default: return ' '
  }
}

export function runQuery (instance, query, needResponse) {
  if (util.isFunction(instance.verbose)) {
    instance.verbose(query.toString())
  }

  if (instance.isNative) {
    if (needResponse) return query
    return query.then(res => {
      if (util.isNumber(res)) return res
      return res ? res.length : 0
    })
  }

  return instance.pool.acquire().then(db => {
    let response

    if (needResponse) {
      response = parseResponse(db.exec(query.toString()))
      if (query._sequence && query._sequence[0].method === 'hasTable') {
        response = !!response.length
      }
    } else {
      db.run(query.toString())

      if (util.isOneOf(['insert', 'update', 'delete'], query._method)) {
        response = db.getRowsModified()
      }
    }

    writeDatabase(instance, db)
    instance.pool.release(db)
    return response
  })
}
<commit_msg>refactor(helpers): removed unused function `getConflictString()`<commit_after>import * as util from './util'
import { castValue } from './types'
import { writeDatabase } from './sqljs-handler'

export function parseResponse (contents) {
  if (!contents || !contents.length) return []

  let { columns, values } = contents[0]
  let results = []

  for (let i = 0; i < values.length; i++) {
    let line = {}

    for (let j = 0; j < columns.length; j++) {
      line[columns[j]] = values[i][j]
    }

    results.push(line)
  }

  return results
}

export function buildOrder (partial, order) {
  if (util.isString(order)) {
    if (order === 'random') {
      return partial.orderByRaw('RANDOM()')
    }
    return partial.orderBy(order)
  }

  if (util.isArray(order)) {
    let length = order.length
    if (length === 1 || length === 2) {
      return partial.orderBy(...order)
    }
  }

  return partial
}

export function buildWhere (partial, where) {
  let [isValid, arrayLength] = isValidWhere(where)
  if (!isValid) return partial

  let cast = where
  if (!arrayLength) {
    cast = util.map(where, castValue)
  } else {
    let i = arrayLength - 1
    cast[i] = castValue(where[i])
  }

  if (!arrayLength) return partial.where(cast)
  return partial.where(...cast)
}

export function isValidWhere (where) {
  if (util.isArray(where)) {
    let len = where.length
    return [len === 2 || len === 3, len]
  }

  if (util.isObject(where)) return [true]

  return [false]
}

export function runQuery (instance, query, needResponse) {
  if (util.isFunction(instance.verbose)) {
    instance.verbose(query.toString())
  }

  if (instance.isNative) {
    if (needResponse) return query
    return query.then(res => {
      if (util.isNumber(res)) return res
      return res ? res.length : 0
    })
  }

  return instance.pool.acquire().then(db => {
    let response

    if (needResponse) {
      response = parseResponse(db.exec(query.toString()))
      if (query._sequence && query._sequence[0].method === 'hasTable') {
        response = !!response.length
      }
    } else {
      db.run(query.toString())

      if (util.isOneOf(['insert', 'update', 'delete'], query._method)) {
        response = db.getRowsModified()
      }
    }

    writeDatabase(instance, db)
    instance.pool.release(db)
    return response
  })
}
<|endoftext|>


<commit_before>"use strict";

var chai = require("chai"),
    sinon = require("sinon"),
    react = require("../" + require("../package.json").main),
    expect = chai.expect;

chai.Assertion.includeStack = true;
chai.use(require("sinon-chai"));

function createSignal() {

    function signal() {
        return signal.value;
    }
    signal.value = null;
    signal.listener = null;
    signal.notify = function (listener) {
        this.listener = listener;
    };
    signal.unnotify = function (listener) {
        if (this.listener === listener) {
            delete this.listener;
        }
    };
    signal.trigger = function () {
        this.listener && this.listener();
    };

    return signal;
}

describe("react()", function () {
    var signal,
        otherSignal,
        doSomething;

    beforeEach(function () {
        signal = createSignal();
        doSomething = sinon.spy();
    });

    describe(".when(signal)", function () {

        describe(".changes", function () {

            describe(".then(func)", function () {

                it("should call func every time the signal changes", function () {
                    react().when(signal).changes.then(doSomething);

                    signal.trigger();
                    signal.value = undefined;
                    signal.trigger();
                    signal.trigger();

                    expect(doSomething).to.have.been.calledTwice;
                });

            });

        });

        describe(".exists", function () {

            it("should call func every time the signal's value is neither undefined nor null", function () {
                react().when(signal).exists.then(doSomething);

                signal.trigger();
                signal.trigger();
                signal.value = true;
                signal.trigger();
                signal.trigger();
                signal.value = undefined;
                signal.trigger();

                expect(doSomething).to.have.been.calledTwice;
            });

        });

        describe(".equals(value)", function () {

            describe(".then(func)", function () {

                it("should call func every time the signal's value strictly equals the given value", function () {
                    react().when(signal).equals("1").then(doSomething);

                    signal.value = "1";
                    signal.trigger();
                    signal.trigger();
                    signal.value = 1;
                    signal.trigger();
                    signal.trigger();
                    signal.value = "1";
                    signal.trigger();

                    expect(doSomething).to.have.been.calledThrice;
                });

            });

        });

        describe(".equals(signal)", function () {

            beforeEach(function () {
                otherSignal = createSignal();
            });

            describe(".then(func)", function () {

                it("should call func every time the signal's value strictly equals the other signal's value", function () {
                    react().when(signal).equals(otherSignal).then(doSomething);

                    signal.value = "1";
                    signal.trigger();
                    otherSignal.value = 1;
                    signal.trigger();
                    signal.value = 1;
                    signal.trigger();
                    signal.value = "1";
                    signal.trigger();
                    otherSignal.value = "1";
                    otherSignal.trigger();

                    expect(doSomething).to.have.been.calledTwice;
                });

            });

        });

        describe(".contains(value)", function () {

            describe(".then(func)", function () {

                it("should call func every time the signal's string contains the given string", function () {
                    react().when(signal).contains("Hello").then(doSomething);

                    signal.trigger();
                    signal.value = "Hallo";
                    signal.trigger();
                    signal.value = "Hello";
                    signal.trigger();
                    signal.trigger();
                    signal.value = "Hallo";
                    signal.trigger();

                    expect(doSomething).to.have.been.calledTwice;
                });

                it("should call func every time the signal's array contains the given number", function () {
                    react().when(signal).contains(4).then(doSomething);

                    signal.trigger();
                    signal.value = [1, 2, 3];
                    signal.trigger();
                    signal.value.push(4);
                    signal.trigger();
                    signal.value.push(5);
                    signal.trigger();

                    expect(doSomething).to.have.been.calledTwice;
                });

                it("should call func every time the signal's array contains the given signal", function () {
                    otherSignal = createSignal();

                    react().when(signal).contains(otherSignal).then(doSomething);

                    signal.trigger();
                    signal.value = [1, 2, 3];
                    signal.trigger();
                    signal.value.push(4);
                    otherSignal.value = 4;
                    otherSignal.trigger();
                    signal.value.push(5);
                    signal.trigger();

                    expect(doSomething).to.have.been.calledTwice;
                });

            });

        });

        describe(".does", function () {

            describe(".not", function () {

                describe(".exist", function () {

                    it("should call func every time the signal's value is either undefined or null", function () {
                        react().when(signal).does.not.exist.then(doSomething);

                        signal.trigger();
                        signal.value = true;
                        signal.trigger();
                        signal.trigger();
                        signal.value = undefined;
                        signal.trigger();

                        expect(doSomething).to.have.been.calledTwice;
                    });

                });

                describe(".equal(value)", function () {

                    describe(".then(func)", function () {

                        it("should call func every time the signal's value strictly does not equal the given value", function () {
                            var doSomething = sinon.spy();

                            react().when(signal).does.not.equal("1").then(doSomething);

                            signal.value = 1;
                            signal.trigger();
                            signal.value = "1";
                            signal.trigger();
                            signal.trigger();
                            signal.value = 1;
                            signal.trigger();

                            expect(doSomething).to.have.been.calledTwice;
                        });

                    });

                });

                describe(".equal(signal)", function () {

                    beforeEach(function () {
                        otherSignal = createSignal();
                    });

                    describe(".then(func)", function () {

                        it("should call func every time the signal's value strictly does not equal the other signal's value", function () {
                            react().when(signal).does.not.equal(otherSignal).then(doSomething);

                            signal.value = "1";
                            signal.trigger();
                            otherSignal.value = 1;
                            signal.trigger();
                            signal.value = 1;
                            signal.trigger();
                            signal.value = "1";
                            signal.trigger();
                            otherSignal.value = "1";
                            otherSignal.trigger();

                            expect(doSomething).to.have.been.calledThrice;
                        });

                    });

                });

            });

        });

    });

    describe(".once(signal)", function () {

        describe(".equals(value)", function () {

            describe(".then(func)", function () {

                it("should call func whenever the signal's value changed from another value to the given value again", function () {
                    react().once(signal).equals("1").then(doSomething);

                    signal.value = "1";
                    signal.trigger();
                    signal.trigger();
                    signal.value = 1;
                    signal.trigger();
                    signal.trigger();
                    signal.value = "1";
                    signal.trigger();

                    expect(doSomething).to.have.been.calledTwice;
                });

            });

        });

    });

    describe("... .then(func)", function () {

        it("should return the composition", function () {
            var comp = react().when(signal).changes.then(doSomething);

            expect(comp).to.be.an.instanceof(react.Composition);
        });

        describe(".now()", function () {

            it("should trigger an initial evaluation", function () {
                react().when(signal).does.not.exist.then(doSomething).now();

                expect(doSomething).to.have.been.calledOnce;
            });

            it("should also return the composition", function () {
                var comp = react().when(signal).changes.then(doSomething).now();

                expect(comp).to.be.an.instanceof(react.Composition);
            });

        });

    });

});<commit_msg>- removed redundant tests<commit_after>"use strict";

var chai = require("chai"),
    sinon = require("sinon"),
    react = require("../" + require("../package.json").main),
    expect = chai.expect;

chai.Assertion.includeStack = true;
chai.use(require("sinon-chai"));

function createSignal() {

    function signal() {
        return signal.value;
    }
    signal.value = null;
    signal.listener = null;
    signal.notify = function (listener) {
        this.listener = listener;
    };
    signal.unnotify = function (listener) {
        if (this.listener === listener) {
            delete this.listener;
        }
    };
    signal.trigger = function () {
        this.listener && this.listener();
    };

    return signal;
}

describe("react()", function () {
    var signal,
        otherSignal,
        doSomething;

    beforeEach(function () {
        signal = createSignal();
        doSomething = sinon.spy();
    });

    describe(".when(signal)", function () {

        describe(".changes", function () {

            describe(".then(func)", function () {

                it("should call func every time the signal changes", function () {
                    react().when(signal).changes.then(doSomething);

                    signal.trigger();
                    signal.value = undefined;
                    signal.trigger();
                    signal.trigger();

                    expect(doSomething).to.have.been.calledTwice;
                });

            });

        });

        describe(".exists", function () {

            it("should call func every time the signal's value is neither undefined nor null", function () {
                react().when(signal).exists.then(doSomething);

                signal.trigger();
                signal.trigger();
                signal.value = true;
                signal.trigger();
                signal.trigger();
                signal.value = undefined;
                signal.trigger();

                expect(doSomething).to.have.been.calledTwice;
            });

        });

        describe(".exist", function () {

            it("should be an alias for exists", function () {
                expect(react().when(signal).exist).to.equal(react().when(signal).exists);
            });

        });

        describe(".equals(value)", function () {

            describe(".then(func)", function () {

                it("should call func every time the signal's value strictly equals the given value", function () {
                    react().when(signal).equals("1").then(doSomething);

                    signal.value = "1";
                    signal.trigger();
                    signal.trigger();
                    signal.value = 1;
                    signal.trigger();
                    signal.trigger();
                    signal.value = "1";
                    signal.trigger();

                    expect(doSomething).to.have.been.calledThrice;
                });

            });

        });

        describe(".equals(signal)", function () {

            beforeEach(function () {
                otherSignal = createSignal();
            });

            describe(".then(func)", function () {

                it("should call func every time the signal's value strictly equals the other signal's value", function () {
                    react().when(signal).equals(otherSignal).then(doSomething);

                    signal.value = "1";
                    signal.trigger();
                    otherSignal.value = 1;
                    signal.trigger();
                    signal.value = 1;
                    signal.trigger();
                    signal.value = "1";
                    signal.trigger();
                    otherSignal.value = "1";
                    otherSignal.trigger();

                    expect(doSomething).to.have.been.calledTwice;
                });

            });

        });

        describe(".equal", function () {

            it("should be an alias for equals", function () {
                expect(react().when(signal).equal).to.equal(react().when(signal).equals);
            });

        });

        describe(".contains(value)", function () {

            describe(".then(func)", function () {

                it("should call func every time the signal's string contains the given string", function () {
                    react().when(signal).contains("Hello").then(doSomething);

                    signal.trigger();
                    signal.value = "Hallo";
                    signal.trigger();
                    signal.value = "Hello";
                    signal.trigger();
                    signal.trigger();
                    signal.value = "Hallo";
                    signal.trigger();

                    expect(doSomething).to.have.been.calledTwice;
                });

                it("should call func every time the signal's array contains the given number", function () {
                    react().when(signal).contains(4).then(doSomething);

                    signal.trigger();
                    signal.value = [1, 2, 3];
                    signal.trigger();
                    signal.value.push(4);
                    signal.trigger();
                    signal.value.push(5);
                    signal.trigger();

                    expect(doSomething).to.have.been.calledTwice;
                });

                it("should call func every time the signal's array contains the given signal", function () {
                    otherSignal = createSignal();

                    react().when(signal).contains(otherSignal).then(doSomething);

                    signal.trigger();
                    signal.value = [1, 2, 3];
                    signal.trigger();
                    signal.value.push(4);
                    otherSignal.value = 4;
                    otherSignal.trigger();
                    signal.value.push(5);
                    signal.trigger();

                    expect(doSomething).to.have.been.calledTwice;
                });

            });

        });

        describe(".contain", function () {

            it("should be an alias for contains", function () {
                expect(react().when(signal).contain).to.equal(react().when(signal).contains);
            });

        });

        describe(".does", function () {

            describe(".not", function () {

                describe(".equal(value)", function () {

                    describe(".then(func)", function () {

                        it("should call func every time the signal's value does not equal the given value", function () {
                            var doSomething = sinon.spy();

                            react().when(signal).does.not.equal("1").then(doSomething);

                            signal.value = 1;
                            signal.trigger();
                            signal.value = "1";
                            signal.trigger();
                            signal.trigger();
                            signal.value = 1;
                            signal.trigger();

                            expect(doSomething).to.have.been.calledTwice;
                        });

                    });

                });

            });

        });

    });

    describe(".once(signal)", function () {

        describe(".equals(value)", function () {

            describe(".then(func)", function () {

                it("should call func whenever the signal's value changed from another value to the given value again", function () {
                    react().once(signal).equals("1").then(doSomething);

                    signal.value = "1";
                    signal.trigger();
                    signal.trigger();
                    signal.value = 1;
                    signal.trigger();
                    signal.trigger();
                    signal.value = "1";
                    signal.trigger();

                    expect(doSomething).to.have.been.calledTwice;
                });

            });

        });

    });

    describe("... .then(func)", function () {

        it("should return the composition", function () {
            var comp = react().when(signal).changes.then(doSomething);

            expect(comp).to.be.an.instanceof(react.Composition);
        });

        describe(".now()", function () {

            it("should trigger an initial evaluation", function () {
                react().when(signal).does.not.exist.then(doSomething).now();

                expect(doSomething).to.have.been.calledOnce;
            });

            it("should also return the composition", function () {
                var comp = react().when(signal).changes.then(doSomething).now();

                expect(comp).to.be.an.instanceof(react.Composition);
            });

        });

    });

});<|endoftext|>


<commit_before>$(document).ready(function(){

    // Load all the archive formats
	loadArchiveFormats(['rar', 'zip', 'tar']);

    $("#fileup").change(function(){

        // init the gallery plugin, when there is a first click on a image
        // re-bind this function when opening new comic
        $(document).one('click','#comicImg',function(){
            event.preventDefault();
            // initialize gallery
            $('#output').lightGallery({
                selector: 'a',
                zoom: true,
                fullScreen: true,
            });
            $(this).click();
        });

        // show loading
		$('.se-pre-con').fadeIn('slow');

        // destroy lightGallery
        var $lg = $('#output');
        $lg.lightGallery();
        $lg.data('lightGallery').destroy(true);

        // clear previous blobs
        clearBlobs();

        // clear previous output data
        $('#output').empty();

        var file = $(this)[0].files[0];

        // Open the file as an archive
        archiveOpenFile(file, function(archive, err) {
            if (archive)
            {
                $('#output').append(""+archive.file_name+"
");
                readContents(archive);

                // hide loading
                $('.se-pre-con').fadeOut('slow');
            }
            else
            {
                console.log(err);

                // hide loading
                $('.se-pre-con').fadeOut('slow');
            }
        });
    });

    // function for reading the contents of the archive
    function readContents(archive)
    {
        var entries = archive.entries;

        // iterate through all the contents
        for(var i=0;i<entries.length;i++)
        {
            filename = entries[i].name;
            // check, only output file, not folder
            if(getExt(filename) != '')
            {
                // call function to create blob and url. allow us to read/view the contents
                createBlobs(entries[i]);
            }
        }
    }

    // function to return file extension based on file name
    function getExt(filename)
    {
        var ext = filename.split('.').pop();
        return (ext == filename) ? '' : ext;
    }

    // function to return MIME type based on the file extension
    // NOTE: THIS FUNCTION IS NOT EFFICIENT
    function getMIME(filename)
    {
        var ext = getExt(filename).toLowerCase();

        switch(ext)
        {
            case 'jpg':
            case 'jpeg':
                return 'image/jpeg';
                break;
            case 'png':
                return 'image/png';
                break;
            case 'gif':
                return 'image/gif';
                break;
            case 'bmp':
                return 'image/bmp';
                break;
            case 'webp':
                return 'image/webp';
                break;
            default:
                return 'image/jpeg';
        }
    }

    // function to convert the archive contents into blobs, and return URL
    function createBlobs(entry)
    {
        entry.readData(function(data, err) {
            // Convert the data into an Object URL
            var blob = new Blob([data], {type: getMIME(entry.name)});
            var url = URL.createObjectURL(blob);

            // output the images
            $('#output').append("");
        });

    }

    // function to clear all previous blobs, free up memory
    function clearBlobs()
    {
        $('.imgUrl').each(function(){
            URL.revokeObjectURL($(this).attr('src'));
        });
    }

});<commit_msg>disable download option in lightGallery<commit_after>$(document).ready(function(){

    // Load all the archive formats
	loadArchiveFormats(['rar', 'zip', 'tar']);

    $("#fileup").change(function(){

        // init the gallery plugin, when there is a first click on a image
        // re-bind this function when opening new comic
        $(document).one('click','#comicImg',function(){
            event.preventDefault();
            // initialize gallery
            $('#output').lightGallery({
                selector: 'a',
                zoom: true,
                fullScreen: true,
                download: false,
            });
            $(this).click();
        });

        // show loading
		$('.se-pre-con').fadeIn('slow');

        // destroy lightGallery
        var $lg = $('#output');
        $lg.lightGallery();
        $lg.data('lightGallery').destroy(true);

        // clear previous blobs
        clearBlobs();

        // clear previous output data
        $('#output').empty();

        var file = $(this)[0].files[0];

        // Open the file as an archive
        archiveOpenFile(file, function(archive, err) {
            if (archive)
            {
                $('#output').append(""+archive.file_name+"
");
                readContents(archive);

                // hide loading
                $('.se-pre-con').fadeOut('slow');
            }
            else
            {
                console.log(err);

                // hide loading
                $('.se-pre-con').fadeOut('slow');
            }
        });
    });

    // function for reading the contents of the archive
    function readContents(archive)
    {
        var entries = archive.entries;

        // iterate through all the contents
        for(var i=0;i<entries.length;i++)
        {
            filename = entries[i].name;
            // check, only output file, not folder
            if(getExt(filename) != '')
            {
                // call function to create blob and url. allow us to read/view the contents
                createBlobs(entries[i]);
            }
        }
    }

    // function to return file extension based on file name
    function getExt(filename)
    {
        var ext = filename.split('.').pop();
        return (ext == filename) ? '' : ext;
    }

    // function to return MIME type based on the file extension
    // NOTE: THIS FUNCTION IS NOT EFFICIENT
    function getMIME(filename)
    {
        var ext = getExt(filename).toLowerCase();

        switch(ext)
        {
            case 'jpg':
            case 'jpeg':
                return 'image/jpeg';
                break;
            case 'png':
                return 'image/png';
                break;
            case 'gif':
                return 'image/gif';
                break;
            case 'bmp':
                return 'image/bmp';
                break;
            case 'webp':
                return 'image/webp';
                break;
            default:
                return 'image/jpeg';
        }
    }

    // function to convert the archive contents into blobs, and return URL
    function createBlobs(entry)
    {
        entry.readData(function(data, err) {
            // Convert the data into an Object URL
            var blob = new Blob([data], {type: getMIME(entry.name)});
            var url = URL.createObjectURL(blob);

            // output the images
            $('#output').append("");
        });

    }

    // function to clear all previous blobs, free up memory
    function clearBlobs()
    {
        $('.imgUrl').each(function(){
            URL.revokeObjectURL($(this).attr('src'));
        });
    }

});<|endoftext|>