<commit_before>var chai    = require( 'chai' ),
    mocha   = require( 'mocha' ),
    ArrayDB = require( __dirname + '/../src/arraydb' ).ArrayDB,
    expect  = chai.expect,
    should  = chai.should;

describe( 'ArrayDB objects', function() {

    it( 'should not be Arrays objects', function() {

        var a = new ArrayDB();

        expect( a ).not.to.be.a( 'array' );

    });

    it( 'should inherit Arrays\' properties', function() {

        var a = new ArrayDB();

        expect( a.constructor ).to.equal( Array );
        expect( a.length ).to.equal( 0 );
        a.push( 2 );
        expect( a.length ).to.equal( 1 );

    });

    it( 'can be initialized with an array', function() {

        var a = new ArrayDB([ 1, 2, 'foo' ]);

        expect( a.length ).to.equal( 3 );
        expect( a[0] ).to.equal( 1 );
        expect( a[1] ).to.equal( 2 );
        expect( a[2] ).to.equal( 'foo' );

    });

    it( 'can be initialized with a set of arguments', function() {

        var a = new ArrayDB( 1, 2, 'foo' ),
            b = new ArrayDB( [], [] );

        expect( a.length ).to.equal( 3 );
        expect( b.length ).to.equal( 2 );
        expect( a[0] ).to.equal( 1 );
        expect( a[1] ).to.equal( 2 );
        expect( a[2] ).to.equal( 'foo' );

    });

    describe('.query method', function() {

        it( 'should be a function', function() {

            var a = new ArrayDB();

            expect( a.query ).to.be.a( 'function' );

        });

        it( 'should return an array', function() {

            var a = new ArrayDB();

            expect( a.query() ).to.be.a( 'array' );
            expect( a.query([]) ).to.be.a( 'array' );
            expect( a.query({}) ).to.be.a( 'array' );
            expect( a.query(0) ).to.be.a( 'array' );
            expect( a.query(NaN) ).to.be.a( 'array' );
            expect( a.query(true) ).to.be.a( 'array' );

        });

        it( 'should works without Array#filter', function() {

            var a = new ArrayDB( 1, 2, 3 ),

                _filter = Array.prototype.filter;

            Array.prototype.filter = null;

            expect( a.query( 42 ) ).to.deep.equal( [] );

            Array.prototype.filter = _filter;

        });

        it( 'should be empty if the query is empty', function() {

            var a = new ArrayDB(),
                b = new ArrayDB([]),
                c = new ArrayDB( 1, 2, 3 );

            expect( a.query() ).to.deep.equal( [] );
            expect( b.query() ).to.deep.equal( [] );
            expect( c.query() ).to.deep.equal( [] );

        });

        it( 'should limit the results count if the `limit` param is set',
            function() {

            var a = new ArrayDB( 1, 1, 1, 2, 12, 1, 5 );

            expect( a.query( 1, 2 ).length ).to.equal( 2 );
            expect( a.query({ query: 1, limit: 2 }).length ).to.equal( 2 );

        });

        it( 'should slice the results if the `offset` param is set',
            function() {

            var a = new ArrayDB( 1, 1, 1, 2, 12, 1, 5 );

            expect( a.query( 1, 10, 1 ).length ).to.equal( 3 );
            expect( a.query({ query: 1, offset: 1 }).length ).to.equal( 3 );

        });

        it( 'should work without Array#filter', function() {

            var a = new ArrayDB( 42, 'something', [], 42, 78 ),
                f = Array.prototype.filter;

            Array.prototype.filter = null;

            expect( a.query( 42 ).length ).to.equal( 2 );
            expect( a.query( 42, 1 ).length ).to.equal( 1 );
            expect( a.query( 42, 3, 1 ).length ).to.equal( 1 );

            expect( a.query({ query: 42 }).length ).to.equal( 2 );
            expect( a.query({ query: 42, limit: 1 }).length ).to.equal( 1 );
            expect( a.query({ query: 42, offset: 1 }).length ).to.equal( 1 );

            Array.prototype.filter = f;

        });

        // #1
        it( 'should handle simple circular references', function() {

            var o = { foo: 42 },
                q = { foo: 42 },
                a;

            o.bar = o;
            q.bar = q;

            a = new ArrayDB( o, { foo: 42 }, { foo: 43 } );

            expect(a.query({ query: q }).length ).to.equal( 1 );
        });

        // TODO add more complex circular references

        describe( 'in strict mode', function() {

            it( 'should match only elements of the same type', function() {

                var a = new ArrayDB( 2, '2', [2], true );

                expect( a.query({
                    query: 2, strict: true }).length ).to.equal( 1 );<commit_msg>more complex circular references tests added.<commit_after>var chai    = require( 'chai' ),
    mocha   = require( 'mocha' ),
    ArrayDB = require( __dirname + '/../src/arraydb' ).ArrayDB,
    expect  = chai.expect,
    should  = chai.should;

describe( 'ArrayDB objects', function() {

    it( 'should not be Arrays objects', function() {

        var a = new ArrayDB();

        expect( a ).not.to.be.a( 'array' );

    });

    it( 'should inherit Arrays\' properties', function() {

        var a = new ArrayDB();

        expect( a.constructor ).to.equal( Array );
        expect( a.length ).to.equal( 0 );
        a.push( 2 );
        expect( a.length ).to.equal( 1 );

    });

    it( 'can be initialized with an array', function() {

        var a = new ArrayDB([ 1, 2, 'foo' ]);

        expect( a.length ).to.equal( 3 );
        expect( a[0] ).to.equal( 1 );
        expect( a[1] ).to.equal( 2 );
        expect( a[2] ).to.equal( 'foo' );

    });

    it( 'can be initialized with a set of arguments', function() {

        var a = new ArrayDB( 1, 2, 'foo' ),
            b = new ArrayDB( [], [] );

        expect( a.length ).to.equal( 3 );
        expect( b.length ).to.equal( 2 );
        expect( a[0] ).to.equal( 1 );
        expect( a[1] ).to.equal( 2 );
        expect( a[2] ).to.equal( 'foo' );

    });

    describe('.query method', function() {

        it( 'should be a function', function() {

            var a = new ArrayDB();

            expect( a.query ).to.be.a( 'function' );

        });

        it( 'should return an array', function() {

            var a = new ArrayDB();

            expect( a.query() ).to.be.a( 'array' );
            expect( a.query([]) ).to.be.a( 'array' );
            expect( a.query({}) ).to.be.a( 'array' );
            expect( a.query(0) ).to.be.a( 'array' );
            expect( a.query(NaN) ).to.be.a( 'array' );
            expect( a.query(true) ).to.be.a( 'array' );

        });

        it( 'should works without Array#filter', function() {

            var a = new ArrayDB( 1, 2, 3 ),

                _filter = Array.prototype.filter;

            Array.prototype.filter = null;

            expect( a.query( 42 ) ).to.deep.equal( [] );

            Array.prototype.filter = _filter;

        });

        it( 'should be empty if the query is empty', function() {

            var a = new ArrayDB(),
                b = new ArrayDB([]),
                c = new ArrayDB( 1, 2, 3 );

            expect( a.query() ).to.deep.equal( [] );
            expect( b.query() ).to.deep.equal( [] );
            expect( c.query() ).to.deep.equal( [] );

        });

        it( 'should limit the results count if the `limit` param is set',
            function() {

            var a = new ArrayDB( 1, 1, 1, 2, 12, 1, 5 );

            expect( a.query( 1, 2 ).length ).to.equal( 2 );
            expect( a.query({ query: 1, limit: 2 }).length ).to.equal( 2 );

        });

        it( 'should slice the results if the `offset` param is set',
            function() {

            var a = new ArrayDB( 1, 1, 1, 2, 12, 1, 5 );

            expect( a.query( 1, 10, 1 ).length ).to.equal( 3 );
            expect( a.query({ query: 1, offset: 1 }).length ).to.equal( 3 );

        });

        it( 'should work without Array#filter', function() {

            var a = new ArrayDB( 42, 'something', [], 42, 78 ),
                f = Array.prototype.filter;

            Array.prototype.filter = null;

            expect( a.query( 42 ).length ).to.equal( 2 );
            expect( a.query( 42, 1 ).length ).to.equal( 1 );
            expect( a.query( 42, 3, 1 ).length ).to.equal( 1 );

            expect( a.query({ query: 42 }).length ).to.equal( 2 );
            expect( a.query({ query: 42, limit: 1 }).length ).to.equal( 1 );
            expect( a.query({ query: 42, offset: 1 }).length ).to.equal( 1 );

            Array.prototype.filter = f;

        });

        // #1
        it( 'should handle simple circular references', function() {

            var o = { foo: 42 },
                q = { foo: 42 },
                a;

            o.bar = o;
            q.bar = q;

            a = new ArrayDB( o, { foo: 42 }, { foo: 43 } );

            expect(a.query({ query: q }).length ).to.equal( 1 );
        });

        it( 'should handle deep circular references', function() {

            var o = { foo: 42 },
                q = { foo: 42 },
                a;

            o.bar = { foo: 42, bar: o };
            q.bar = q;

            a = new ArrayDB( o, { foo: 42 }, { foo: 43 } );

            expect(a.query({ query: q }).length ).to.equal( 1 );
        });

        it( 'should not match a circular-referenced query '
          + 'with a non-circular-referenced object', function() {

              var circ   = { foo: 42 },
                  normal = { foo: 42, bar: { foo: 42, bar: { foo: 42 } } },
                  a;

              circ.bar = circ;

              a = new ArrayDB( normal, { foo: 56 }, null );

              // as a pattern, `circ` doesn’t match `normal`
              expect(a.query({ query: circ }).length ).to.equal( 0 );

        });

        it( 'should be able to match a non-circular-referenced query '
          + 'with a circular-referenced object', function() {

              var circ   = { foo: 42 },
                  normal = { foo: 42, bar: { foo: 42, bar: { foo: 42 } } },
                  a;

              circ.bar = circ;

              a = new ArrayDB( circ, { foo: 56 }, null );

              // as a pattern, `normal` matches `circ`
              expect(a.query({ query: normal }).length ).to.equal( 1 );

        });

        describe( 'in strict mode', function() {

            it( 'should match only elements of the same type', function() {

                var a = new ArrayDB( 2, '2', [2], true );

                expect( a.query({
                    query: 2, strict: true }).length ).to.equal( 1 );
{'fraction_non_alphanumeric': 0.16950442309521543, 'fraction_numerical': 0.02273375820412822, 'mean_word_length': 1.5117056856187292, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1836127', 'n_tokens_mistral': 3529, 'n_tokens_neox': 3143, 'n_words': 1040}