desc: These tests are aimed at &&, ||, and !
tests:

    ## basic operator usage

    # Python overloads '&' for 'and'
    - py: [r.expr(True) & True, True & r.expr(True), "r.all(True,True)"]
      js: r(true).and(true)
      rb: [r(true) & true, r(true).and(true)]
      ot: true
    - py: [r.expr(True) & False, True & r.expr(False)]
      cd: r(true).and(false)
      ot: false
    - py: [r.expr(False) & False, False & r.expr(False)]
      cd: r(false).and(false)
      ot: false

    # Python overloads '|' for 'or'
    - py: [r.expr(True) | True, True | r.expr(True), "r.any(True,True)"]
      cd: r(true).or(true)
      rb: [r(true).or(true), r(true) | true]
      ot: true
    - py: [r.expr(True) | False, True | r.expr(False)]
      cd: r(true).or(false)
      ot: true
    - py: [r.expr(False) | False, False | r.expr(False)]
      cd: r(false).or(false)
      ot: false

    # Python overloads '~' for 'not'
    - py: ~r.expr(True)
      cd: r(true).not()
      ot: false
    - py: ~r.expr(False)
      cd: r(false).not()
      ot: true
    - py: r.expr(True).not_()
      cd: r(true).not()
      ot: false
    - py: r.expr(False).not_()
      cd: r(false).not()
      ot: true

    ## DeMorgan's rules!

    - py:
        - ~(True & r.expr(True)) == (~r.expr(True) | ~r.expr(True))
        - ~(True & r.expr(False)) == (~r.expr(True) | ~r.expr(False))
        - ~(False & r.expr(False)) == (~r.expr(False) | ~r.expr(False))
        - ~(False & r.expr(True)) == (~r.expr(False) | ~r.expr(True))
      cd:
        - r(true).and(true).not().eq(r(true).not().or(r(true).not()))
        - r(true).and(false).not().eq(r(true).not().or(r(false).not()))
        - r(false).and(false).not().eq(r(false).not().or(r(false).not()))
        - r(false).and(true).not().eq(r(false).not().or(r(true).not()))
      ot: true

    # 'and' and 'or' take an arbitrary number of arguments though this functionality
    # can only be accessed in JS at the moment
    - js: r(true).and(true, true, true, true)
      cd: []
      ot: true
    - js: r(true).and(true, true, false, true)
      cd: []
      ot: false
    - js: r(true).and(false, true, false, true)
      cd: []
      ot: false
    - js: r(false).or(false, false, false, false)
      cd: []
      ot: false
    - js: r(false).or(false, false, true, false)
      cd: []
      ot: true
    - js: r(false).or(true, false, true, false)
      cd: []
      ot: true

    # Type errors
    - py: r.expr(1) & True
      cd: r(1).and(true)
      ot: true

    - py: r.expr(False) | 'str'
      cd: r(false).or('str')
      ot: ("str")

    - py: ~r.expr(1)
      cd: r(1).not()
      ot: false

    - py: ~r.expr(null)
      cd: r(null).not()
      ot: true
