2 // the symlink file is excluded from git, because it makes
3 // windows freak the hell out.
5 , path = require("path")
6 , symlink = path.resolve(__dirname, "fixtures/symlink")
7 try { fs.unlinkSync(symlink) } catch (e) {}
8 fs.symlinkSync("./hardlink-1", symlink)
9 process.on("exit", function () {
10 fs.unlinkSync(symlink)
14 var tap = require("tap")
15 , tar = require("../tar.js")
16 , pkg = require("../package.json")
18 , fstream = require("fstream")
19 , Reader = fstream.Reader
20 , Writer = fstream.Writer
21 , input = path.resolve(__dirname, "fixtures/")
22 , target = path.resolve(__dirname, "tmp/pack.tar")
23 , uid = process.getuid ? process.getuid() : 0
24 , gid = process.getgid ? process.getgid() : 0
28 // the global header and root fixtures/ dir are going to get
29 // a different date each time, so omit that bit.
30 // Also, dev/ino values differ across machines, so that's not
32 [ [ 'globalExtendedHeader',
46 { "NODETAR.author": pkg.author,
47 "NODETAR.name": pkg.name,
48 "NODETAR.description": pkg.description,
49 "NODETAR.version": pkg.version,
50 "NODETAR.repository.type": pkg.repository.type,
51 "NODETAR.repository.url": pkg.repository.url,
52 "NODETAR.main": pkg.main,
53 "NODETAR.scripts.test": pkg.scripts.test } ]
72 { path: 'PaxHeader/fixtures/200cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc',
85 { path: 'fixtures/200ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc',
87 'NODETAR.type': 'File',
92 'NODETAR.blksize': '4096',
93 'NODETAR.blocks': '8' } ]
96 { path: 'fixtures/200ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc',
103 ustar: 'ustar\u0000',
110 'NODETAR.depth': '1',
111 'NODETAR.type': 'File',
113 'NODETAR.blksize': '4096',
114 'NODETAR.blocks': '8' } ]
117 { path: 'fixtures/a.txt',
124 ustar: 'ustar\u0000',
133 { path: 'fixtures/b.txt',
140 ustar: 'ustar\u0000',
149 { path: 'fixtures/c.txt',
156 ustar: 'ustar\u0000',
165 { path: 'fixtures/cc.txt',
172 ustar: 'ustar\u0000',
181 { path: 'fixtures/dir/',
188 ustar: 'ustar\u0000',
197 { path: 'fixtures/dir/sub/',
204 ustar: 'ustar\u0000',
214 { path: 'fixtures/foo.js',
221 ustar: 'ustar\u0000',
230 { path: 'fixtures/hardlink-1',
237 ustar: 'ustar\u0000',
246 { path: 'fixtures/hardlink-2',
252 linkpath: 'fixtures/hardlink-1',
253 ustar: 'ustar\u0000',
262 { path: 'fixtures/omega.txt',
269 ustar: 'ustar\u0000',
278 { path: 'fixtures/packtest/',
285 ustar: 'ustar\u0000',
294 { path: 'fixtures/packtest/omega.txt',
301 ustar: 'ustar\u0000',
310 { path: 'fixtures/packtest/star.4.html',
317 ustar: 'ustar\u0000',
325 , [ 'extendedHeader',
326 { path: 'PaxHeader/fixtures/packtest/Ω.txt',
332 ustar: 'ustar\u0000',
339 { path: 'fixtures/packtest/Ω.txt',
340 'NODETAR.depth': '2',
341 'NODETAR.type': 'File',
346 'NODETAR.blksize': '4096',
347 'NODETAR.blocks': '8' } ]
350 { path: 'fixtures/packtest/Ω.txt',
357 ustar: 'ustar\u0000',
364 'NODETAR.depth': '2',
365 'NODETAR.type': 'File',
367 'NODETAR.blksize': '4096',
368 'NODETAR.blocks': '8' } ]
371 { path: 'fixtures/r/',
378 ustar: 'ustar\u0000',
387 { path: 'fixtures/r/e/',
394 ustar: 'ustar\u0000',
403 { path: 'fixtures/r/e/a/',
410 ustar: 'ustar\u0000',
419 { path: 'fixtures/r/e/a/l/',
426 ustar: 'ustar\u0000',
435 { path: 'fixtures/r/e/a/l/l/',
442 ustar: 'ustar\u0000',
451 { path: 'fixtures/r/e/a/l/l/y/',
458 ustar: 'ustar\u0000',
467 { path: 'fixtures/r/e/a/l/l/y/-/',
474 ustar: 'ustar\u0000',
483 { path: 'fixtures/r/e/a/l/l/y/-/d/',
490 ustar: 'ustar\u0000',
499 { path: 'fixtures/r/e/a/l/l/y/-/d/e/',
506 ustar: 'ustar\u0000',
515 { path: 'fixtures/r/e/a/l/l/y/-/d/e/e/',
522 ustar: 'ustar\u0000',
531 { path: 'fixtures/r/e/a/l/l/y/-/d/e/e/p/',
538 ustar: 'ustar\u0000',
547 { path: 'fixtures/r/e/a/l/l/y/-/d/e/e/p/-/',
554 ustar: 'ustar\u0000',
563 { path: 'fixtures/r/e/a/l/l/y/-/d/e/e/p/-/f/',
570 ustar: 'ustar\u0000',
579 { path: 'fixtures/r/e/a/l/l/y/-/d/e/e/p/-/f/o/',
586 ustar: 'ustar\u0000',
595 { path: 'fixtures/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/',
602 ustar: 'ustar\u0000',
611 { path: 'fixtures/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/',
618 ustar: 'ustar\u0000',
627 { path: 'fixtures/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/',
634 ustar: 'ustar\u0000',
643 { path: 'fixtures/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/',
650 ustar: 'ustar\u0000',
659 { path: 'fixtures/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/',
666 ustar: 'ustar\u0000',
675 { path: 'fixtures/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/',
682 ustar: 'ustar\u0000',
691 { path: 'fixtures/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/',
698 ustar: 'ustar\u0000',
707 { path: 'fixtures/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/',
714 ustar: 'ustar\u0000',
723 { path: 'fixtures/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/',
730 ustar: 'ustar\u0000',
739 { path: 'fixtures/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc',
746 ustar: 'ustar\u0000',
755 { path: 'fixtures/symlink',
760 linkpath: 'hardlink-1',
761 ustar: 'ustar\u0000',
769 , [ 'extendedHeader',
770 { path: 'PaxHeader/fixtures/Ω.txt',
776 ustar: 'ustar\u0000',
783 { path: "fixtures/Ω.txt"
784 , "NODETAR.depth": "1"
785 , "NODETAR.type": "File"
790 , "NODETAR.blksize": "4096"
791 , "NODETAR.blocks": "8" } ]
794 { path: 'fixtures/Ω.txt',
801 ustar: 'ustar\u0000',
808 'NODETAR.depth': '1',
809 'NODETAR.type': 'File',
811 'NODETAR.blksize': '4096',
812 'NODETAR.blocks': '8' } ]
816 // first, make sure that the hardlinks are actually hardlinks, or this
817 // won't work. Git has a way of replacing them with a copy.
818 var hard1 = path.resolve(__dirname, "fixtures/hardlink-1")
819 , hard2 = path.resolve(__dirname, "fixtures/hardlink-2")
822 try { fs.unlinkSync(hard2) } catch (e) {}
823 fs.linkSync(hard1, hard2)
825 tap.test("with global header", { timeout: 10000 }, function (t) {
829 tap.test("without global header", { timeout: 10000 }, function (t) {
833 tap.test("with from base", { timeout: 10000 }, function (t) {
834 runTest(t, true, true)
837 function alphasort (a, b) {
839 : a.toLowerCase() > b.toLowerCase() ? 1
840 : a.toLowerCase() < b.toLowerCase() ? -1
846 function runTest (t, doGH, doFromBase) {
847 var reader = Reader({ path: input
848 , filter: function () {
849 return !this.path.match(/\.(tar|hex)$/)
854 var props = doGH ? pkg : {}
855 if(doFromBase) props.fromBase = true;
857 var pack = Pack(props)
858 var writer = Writer(target)
860 // skip the global header if we're not doing that.
861 var entry = doGH ? 0 : 1
863 t.ok(reader, "reader ok")
864 t.ok(pack, "pack ok")
865 t.ok(writer, "writer ok")
869 var parse = tar.Parse()
870 t.ok(parse, "parser should be ok")
872 pack.on("data", function (c) {
873 // console.error("PACK DATA")
874 if (c.length !== 512) {
875 // this one is too noisy, only assert if it'll be relevant
876 t.equal(c.length, 512, "parser should emit data in 512byte blocks")
881 pack.on("end", function () {
882 // console.error("PACK END")
883 t.pass("parser ends")
887 pack.on("error", function (er) {
888 t.fail("pack error", er)
891 parse.on("error", function (er) {
892 t.fail("parse error", er)
895 writer.on("error", function (er) {
896 t.fail("writer error", er)
899 reader.on("error", function (er) {
900 t.fail("reader error", er)
903 parse.on("*", function (ev, e) {
904 var wanted = entries[entry++]
906 t.fail("unexpected event: "+ev)
909 t.equal(ev, wanted[0], "event type should be "+wanted[0])
912 if(wanted[1].path.indexOf('fixtures/') && wanted[1].path.length == 100)
913 wanted[1].path = wanted[1].path.replace('fixtures/', '') + 'ccccccccc'
915 if(wanted[1]) wanted[1].path = wanted[1].path.replace('fixtures/', '').replace('//', '/')
916 if(wanted[1].path == '') wanted[1].path = '/'
917 if(wanted[2] && wanted[2].path) wanted[2].path = wanted[2].path.replace('fixtures', '').replace(/^\//, '')
919 wanted[1].linkpath = wanted[1].linkpath.replace('fixtures/', '')
922 if (ev !== wanted[0] || e.path !== wanted[1].path) {
923 console.error("wanted", wanted)
924 console.error([ev, e.props])
925 e.on("end", function () {
926 console.error(e.fields)
932 t.has(e.props, wanted[1], "properties "+wanted[1].path)
934 e.on("end", function () {
936 t.ok(e.fields, "should get fields")
938 t.has(e.fields, wanted[2], "should get expected fields")
946 writer.on("close", function () {
947 t.equal(entry, entries.length, "should get all expected entries")
948 t.pass("it finished")