jo / grunt-couch

Build and publish Couchapps and CouchDB design documents with grunt. Simple.
MIT License
48 stars 19 forks source link

Problems compiling arrays: they become objects #26

Open wu-lee opened 8 years ago

wu-lee commented 8 years ago

I have a case in which a module like this:

module.exports = {
    foo: {
        bah: {
            title: 'Bah',
            list: ['Uno', 'Duo']
        },
    },
};

...gets compiled to this:

{
  "docs": [
    {
      "foo": {
        "bah": {
          "title": "Bah",
          "list": {
            0: "Uno",
            1: "Duo"
          }
        }
      }
    }
  ]
}

Specifically, the Array attribute list becomes an Object. This causes my application to fail since an Array really is what I need.

One might wonder why I don't submit this as an issue for couchdb-compile. Well, the reason is that grunt-couch still uses couch-compile 1.0.1, which is old and has been renamed since. And I don't think that couchdb-compile suffers from this problem. (Note I am having trouble installing couchdb-compile's dependencies, some appear to be missing from npm; will file a separate issue for this later.)

So, as the authors for these modules are one and the same, perhaps you know what the problem is already and have fixed it in couchdb-compile? In which case the remedy would seem to be simply update grunt-couch to use a more recent version.

My investigations are not complete yet, but it appears to be that the async module's map function used by couch-compile@1.0.1 perpetrates the conversion of Arrays to Objects. And yet this Array -> Object conversion is not spotted in the grunt-couch tests, even when I add an explicit test, because nodeunit uses NodeJS's assert.deepEquals() function, which rather alarmingly does this in my currently installed and admittedly old version of NodeJS, 0.10.37:

assert.deepEqual([], {}, 'should not be equal.');  // passes!
assert.deepEqual(['a','b'], {0:'a', 1:'b'}, 'should not be equal.'); // passes!

This deficiency seems to have been worked around in newer versions of NodeJS by adding a deepStrictEqual() function:

https://github.com/nodejs/node-v0.x-archive/issues/7161

However I haven't yet tested with this new version yet, as this may not actually solve my problem.

Can you comment? And is there some reason why grunt-couch cannot simply use the recent version of couchdb-compile? (I see there is a pull request for this already, which has not been merged.)

Thanks.

wu-lee commented 8 years ago

My initial tests can be found here: https://github.com/wu-lee/grunt-couch/tree/wu-lee/issue-26

wu-lee commented 8 years ago

I can confirm that grunt-couch using couchdb-compile@~1.6.2 does not have this issue. Tested using

https://github.com/wu-lee/grunt-couch/tree/wu-lee/use_current_compile

This branch contains a fix which @argl's pull request doesn't include. Tests now pass.

jo commented 8 years ago

I have released grunt-couch@1.5.0, which incorporates the update of couchdb-compile.

Can you confirm that this issue is resolved now?

wu-lee commented 8 years ago

Thanks for merging all the PRs, and I've just tried an upgrade. If I install grunt-couch from git and npm-install it, its then tests run fine.

However, I had some problems in my project which uses grunt-couch after updating it to use the latest grunt-couch. There is this error:

npm ERR! peerinvalid The package grunt does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer grunt-contrib-jshint@1.0.0 wants grunt@>=0.4.0
npm ERR! peerinvalid Peer grunt-contrib-watch@0.6.1 wants grunt@~0.4.0
npm ERR! peerinvalid Peer grunt-couch@1.5.0 wants grunt@~1.0.1

npm ERR! System Linux 3.13.0-85-generic
npm ERR! command "/usr/bin/node" "/usr/bin/npm" "update" "grunt" "--save-dev"
npm ERR! cwd /home/nick/i/gitworking/controllis/constock
npm ERR! node -v v0.10.37
npm ERR! npm -v 1.4.28
npm ERR! code EPEERINVALID
npm ERR! 

Upgrading various parts of the mix don't seem to help me, and removing grunt-couch from packages and re-installing it didn't either. I tried upgrading my global grunt install with npm update -g grunt, which was 0.4.5, but it just gets me the same version. I think this is what got me to 1.0.1 eventually:

npm install -g grunt@1.0.1
npm install  grunt@1.0.1

However, now with grunt 1.0.1 running, I still get that peer dependency error. The only solution I've found yet is to install a patched version of grunt-couch with a lower version grunt dependency, as per my fixes2 branch.

To be honest I've yet to understand what the peerDependencies option is for, but it's the devDependency which seems to matter here. (I'm currently running node v0.10.37)

wu-lee commented 8 years ago

What works for me: downgrade the peerDependencies as per the final commit in my branch #fixes2.