How to use parsedFile method in stryker-parent

Best JavaScript code snippet using stryker-parent

lints.test.js

Source:lints.test.js Github

copy

Full Screen

1const {expect} = require('chai');2const lints = require('../lib/lints');3const fs = require('fs');4const {parseToLines} = require('../lib/parser');5const {cleanErrors, getErrors} = require('../lib/errors');6describe('Linting functions', () => {7 describe('Check if line is invalid', () => {8 beforeEach(() => {9 cleanErrors();10 });11 it('Add error for invalid line', function () {12 let parsedFile = {13 escape: '\\'14 };15 let file = fs.readFileSync('./test/files/dockerfile.node.invalid_line', 'utf-8');16 parsedFile.lines = parseToLines(file);17 lints.EL0001(parsedFile);18 expect(getErrors()).to.deep.equal([{19 lineNumber: 8,20 errorCode: 'EL0001'21 }]);22 });23 it('Add error for invalid first line', function () {24 let parsedFile = {25 escape: '\\'26 };27 let file = fs.readFileSync('./test/files/dockerfile.node.invalid_first_line', 'utf-8');28 parsedFile.lines = parseToLines(file);29 lints.EL0001(parsedFile);30 expect(getErrors()).to.deep.equal([{31 lineNumber: 2,32 errorCode: 'EL0001'33 }]);34 });35 });36 describe('Check if parser directives repeat', () => {37 beforeEach(() => {38 cleanErrors();39 });40 it('Add error for repetitions', function () {41 const parsedFile = {42 parserDirectives: [43 {directive: 'escape', value: '\`', lineNumber: 1},44 {directive: 'syntax', value: 'llama', lineNumber: 2},45 {directive: 'escape', value: '\\', lineNumber: 3}46 ]47 };48 lints.ED0002(parsedFile);49 expect(getErrors()).to.deep.equal([{50 lineNumber: 3,51 errorCode: 'ED0002'52 }]);53 });54 it('Don\'t add error', function () {55 const parsedFile = {56 parserDirectives: [57 {directive: 'escape', value: '\`', lineNumber: 1},58 {directive: 'syntax', value: 'llama', lineNumber: 2}59 ]60 };61 lints.ED0002(parsedFile);62 expect(getErrors()).to.deep.equal([]);63 });64 });65 describe('Check if parser directives are lowercase', () => {66 beforeEach(() => {67 cleanErrors();68 });69 it('Add error if parser directive isn\'t lowercase', function () {70 const parsedFile = {71 parserDirectives: [72 {directive: 'ESCAPE', value: '\`', lineNumber: 1},73 {directive: 'syntax', value: 'llama', lineNumber: 2},74 {directive: 'escape', value: '\\', lineNumber: 3}75 ]76 };77 lints.ED0003(parsedFile);78 expect(getErrors()).to.deep.equal([{79 lineNumber: 1,80 errorCode: 'ED0003'81 }]);82 });83 it('Don\'t add error if parser directive is lowercase', function () {84 const parsedFile = {85 parserDirectives: [86 {directive: 'escape', value: '\`', lineNumber: 1},87 {directive: 'syntax', value: 'llama', lineNumber: 2}88 ]89 };90 lints.ED0003(parsedFile);91 expect(getErrors()).to.deep.equal([]);92 });93 });94 describe('Check if parser directive will be treated as command', () => {95 beforeEach(() => {96 cleanErrors();97 });98 it('Add error if parser directive is treated as command, command before directive', function () {99 const parsedFile = {100 lines: [101 {lineNumber: 1, text: '# command'},102 {lineNumber: 2, text: '# escape = \\'},103 {lineNumber: 4, text: '# I like trains'},104 {lineNumber: 5, text: 'FROM ubuntu:16.04'}105 ]106 };107 lints.ED0004(parsedFile);108 expect(getErrors()).to.deep.equal([{109 lineNumber: 2,110 errorCode: 'ED0004'111 }]);112 });113 it('Add error if parser directive is treated as command, instruction before directive', function () {114 const parsedFile = {115 lines: [116 {lineNumber: 1, text: 'FROM ubuntu:16.04'},117 {lineNumber: 2, text: '# escape = \\'},118 {lineNumber: 4, text: '# I like trains'},119 ]120 };121 lints.ED0004(parsedFile);122 expect(getErrors()).to.deep.equal([{123 lineNumber: 2,124 errorCode: 'ED0004'125 }]);126 });127 it('Don\'t add error if parser directive isn\'t treated as command', function () {128 const parsedFile = {129 lines: [130 {lineNumber: 1, text: '# escape = \\'},131 {lineNumber: 2, text: '# I like trains'},132 {lineNumber: 3, text: 'FROM ubuntu:16.04'}133 ]134 };135 lints.ED0004(parsedFile);136 expect(getErrors()).to.deep.equal([]);137 });138 });139 describe('Check if parser directive is on the very top of a Dockerfile', () => {140 beforeEach(() => {141 cleanErrors();142 });143 it('Add error if parser directive isn\'t on the very top of a Dockerfile', function () {144 const parsedFile = {145 lines: [146 {lineNumber: 2, text: '# escape = \\'},147 {lineNumber: 3, text: '# syntax = llama'},148 {lineNumber: 4, text: '# I like trains'},149 {lineNumber: 5, text: 'FROM ubuntu:16.04'}150 ]151 };152 lints.ED0001(parsedFile);153 expect(getErrors()).to.deep.equal([{154 lineNumber: 2,155 errorCode: 'ED0001'156 }]);157 });158 it('Don\'t add error if parser directive is on the very top of a Dockerfile', function () {159 const parsedFile = {160 lines: [161 {lineNumber: 1, text: '# escape = \\'},162 {lineNumber: 2, text: '# I like trains'},163 {lineNumber: 3, text: 'FROM ubuntu:16.04'}164 ]165 };166 lints.ED0001(parsedFile);167 expect(getErrors()).to.deep.equal([]);168 });169 });170 describe('Check if parser directive is missing value', () => {171 beforeEach(() => {172 cleanErrors();173 });174 it('Add error if parser directive is missing value', function () {175 const parsedFile = {176 parserDirectives: [177 {directive: 'escape', value: '', lineNumber: 1},178 {directive: 'syntax', value: 'llama', lineNumber: 2}179 ]180 };181 lints.ED0005(parsedFile);182 expect(getErrors()).to.deep.equal([{183 lineNumber: 1,184 errorCode: 'ED0005'185 }]);186 });187 it('Don\'t add error if parser directive isn\'t missing value', function () {188 const parsedFile = {189 parserDirectives: [190 {directive: 'escape', value: '\\', lineNumber: 1},191 {directive: 'syntax', value: 'llama', lineNumber: 2}192 ]193 };194 lints.ED0005(parsedFile);195 expect(getErrors()).to.deep.equal([]);196 });197 });198 describe('Check if pipefail is used before RUN with a pipe in', () => {199 beforeEach(() => {200 cleanErrors();201 });202 it('Add error if pipefail isn\'t used before RUN with a pipe in', function () {203 const parsedFile = {204 groups: [205 {206 instruction: 'FROM',207 arguments: ['scratch'],208 linesNumbers: [1]209 },210 {211 instruction: 'COPY',212 arguments: ['hello /'],213 linesNumbers: [2]214 },215 {216 instruction: 'RUN',217 arguments: ['wget -O - https://some.site | wc -l > /number'],218 linesNumbers: [3]219 },220 {221 instruction: 'CMD',222 arguments: ['["/hello"]'],223 linesNumbers: [4]224 }225 ]226 };227 lints.ER0001(parsedFile);228 expect(getErrors()).to.deep.equal([{229 lineNumber: 3,230 errorCode: 'ER0001'231 }]);232 });233 it('Don\'t add error if pipefail is used before RUN with a pipe in', function () {234 const parsedFile = {235 groups: [236 {237 instruction: 'FROM',238 arguments: ['scratch'],239 linesNumbers: [1]240 },241 {242 instruction: 'COPY',243 arguments: ['hello /'],244 linesNumbers: [2]245 },246 {247 instruction: 'SHELL',248 arguments: ['["/bin/bash", "-o", "pipefail", "-c"]'],249 linesNumbers: [3]250 },251 {252 instruction: 'RUN',253 arguments: ['wget -O - https://some.site | wc -l > /number'],254 linesNumbers: [4]255 },256 {257 instruction: 'CMD',258 arguments: ['["/hello"]'],259 linesNumbers: [5]260 }261 ]262 };263 lints.ER0001(parsedFile);264 expect(getErrors()).to.deep.equal([]);265 });266 });267 describe('Check if last USER is\'t root', () => {268 beforeEach(() => {269 cleanErrors();270 });271 it('Add error if last USER is root', function () {272 const parsedFile = {273 groups: [274 {275 instruction: 'FROM',276 arguments: ['scratch'],277 linesNumbers: [1]278 },279 {280 instruction: 'USER',281 arguments: ['root'],282 linesNumbers: [2]283 },284 {285 instruction: 'COPY',286 arguments: ['hello /'],287 linesNumbers: [3]288 },289 {290 instruction: 'CMD',291 arguments: ['["/hello"]'],292 linesNumbers: [4]293 },294 {295 instruction: 'CMD',296 arguments: ['["/hello"]'],297 linesNumbers: [5]298 }299 ]300 };301 lints.EU0001(parsedFile);302 expect(getErrors()).to.deep.equal([{303 lineNumber: 2,304 errorCode: 'EU0001'305 }]);306 });307 it('Don\'t add error if last USER isn\'t root', function () {308 const parsedFile = {309 groups: [310 {311 instruction: 'FROM',312 arguments: ['scratch'],313 linesNumbers: [1]314 },315 {316 instruction: 'USER',317 arguments: ['root'],318 linesNumbers: [2]319 },320 {321 instruction: 'COPY',322 arguments: ['hello /'],323 linesNumbers: [3]324 },325 {326 instruction: 'USER',327 arguments: ['llama'],328 linesNumbers: [2]329 },330 {331 instruction: 'CMD',332 arguments: ['["/hello"]'],333 linesNumbers: [4]334 },335 {336 instruction: 'CMD',337 arguments: ['["/hello"]'],338 linesNumbers: [5]339 }340 ]341 };342 lints.EU0001(parsedFile);343 expect(getErrors()).to.deep.equal([]);344 });345 });346 describe('Check if instruction is used only once', () => {347 beforeEach(() => {348 cleanErrors();349 });350 it('Add error if instruction CMD is used more then once', function () {351 const parsedFile = {352 groups: [353 {354 instruction: 'FROM',355 arguments: ['scratch'],356 linesNumbers: [1]357 },358 {359 instruction: 'COPY',360 arguments: ['hello /'],361 linesNumbers: [2]362 },363 {364 instruction: 'CMD',365 arguments: ['["/hello"]'],366 linesNumbers: [3]367 },368 {369 instruction: 'CMD',370 arguments: ['["/hello"]'],371 linesNumbers: [4]372 }373 ]374 };375 lints.EI0001(parsedFile);376 expect(getErrors()).to.deep.equal([{377 lineNumber: 4,378 errorCode: 'EI0001'379 }]);380 });381 it('Don\'t add error if instruction CMD isn\'t used more then once', function () {382 const parsedFile = {383 groups: [384 {385 instruction: 'FROM',386 arguments: ['scratch'],387 linesNumbers: [1]388 },389 {390 instruction: 'USER',391 arguments: ['root'],392 linesNumbers: [2]393 },394 {395 instruction: 'COPY',396 arguments: ['hello /'],397 linesNumbers: [3]398 },399 {400 instruction: 'USER',401 arguments: ['llama'],402 linesNumbers: [2]403 },404 {405 instruction: 'CMD',406 arguments: ['["/hello"]'],407 linesNumbers: [4]408 }409 ]410 };411 lints.EI0001(parsedFile);412 expect(getErrors()).to.deep.equal([]);413 });414 });415 describe('Check if before FROM are only ARG\'s', () => {416 beforeEach(() => {417 cleanErrors();418 });419 it('Add error if instruction FROM is preceded by something else then ARG', function () {420 const parsedFile = {421 groups: [422 {423 instruction: 'CMD',424 arguments: ['["/hello"]'],425 linesNumbers: [1]426 },427 {428 instruction: 'FROM',429 arguments: ['scratch'],430 linesNumbers: [2]431 },432 {433 instruction: 'COPY',434 arguments: ['hello /'],435 linesNumbers: [3]436 },437 {438 instruction: 'CMD',439 arguments: ['["/hello"]'],440 linesNumbers: [4]441 }442 ]443 };444 lints.EI0002(parsedFile);445 expect(getErrors()).to.deep.equal([{446 lineNumber: 1,447 errorCode: 'EI0002'448 }]);449 });450 it('Don\'t add error if instruction FROM is preceded by ARG', function () {451 const parsedFile = {452 groups: [453 {454 instruction: 'ARG',455 arguments: ['Llama'],456 linesNumbers: [1]457 },458 {459 instruction: 'FROM',460 arguments: ['scratch'],461 linesNumbers: [2]462 },463 {464 instruction: 'COPY',465 arguments: ['hello /'],466 linesNumbers: [3]467 },468 {469 instruction: 'CMD',470 arguments: ['["/hello"]'],471 linesNumbers: [4]472 }473 ]474 };475 lints.EI0002(parsedFile);476 expect(getErrors()).to.deep.equal([]);477 });478 });479 describe('Check if instruction FROM exists', () => {480 beforeEach(() => {481 cleanErrors();482 });483 it('Add error if instruction FROM isn\'t exists', function () {484 const parsedFile = {485 groups: [486 {487 instruction: 'COPY',488 arguments: ['hello /'],489 linesNumbers: [2]490 },491 {492 instruction: 'CMD',493 arguments: ['["/hello"]'],494 linesNumbers: [3]495 }496 ]497 };498 lints.EF0001(parsedFile);499 expect(getErrors()).to.deep.equal([{500 lineNumber: 2,501 errorCode: 'EF0001'502 }]);503 });504 it('Don\'t add error if instruction FROM exists', function () {505 const parsedFile = {506 groups: [507 {508 instruction: 'FROM',509 arguments: ['scratch'],510 linesNumbers: [1]511 },512 {513 instruction: 'COPY',514 arguments: ['hello /'],515 linesNumbers: [2]516 },517 {518 instruction: 'CMD',519 arguments: ['["/hello"]'],520 linesNumbers: [3]521 }522 ]523 };524 lints.EF0001(parsedFile);525 expect(getErrors()).to.deep.equal([]);526 });527 });528 describe('Check if --from refer to defined from alias', () => {529 beforeEach(() => {530 cleanErrors();531 });532 it('Add error if --from reference to not defined FROM with index', function () {533 const parsedFile = {534 groups: [535 {536 instruction: 'FROM',537 arguments: ['scratch as build'],538 linesNumbers: [1]539 },540 {541 instruction: 'COPY',542 arguments: ['--from=1 hello /'],543 linesNumbers: [2]544 },545 {546 instruction: 'FROM',547 arguments: ['scratch as llama'],548 linesNumbers: [5]549 }550 ],551 aliases: [552 {553 name: 'build',554 lineNumber: 1555 },556 {557 name: 'llama',558 lineNumber: 5559 }560 ]561 };562 lints.EC0002(parsedFile);563 expect(getErrors()).to.deep.equal([{564 lineNumber: 2,565 errorCode: 'EC0002'566 }]);567 });568 it('Add error if --from reference to not defined FROM with alias', function () {569 const parsedFile = {570 groups: [571 {572 instruction: 'FROM',573 arguments: ['scratch as build'],574 linesNumbers: [1]575 },576 {577 instruction: 'COPY',578 arguments: ['--from=llama hello /'],579 linesNumbers: [2]580 },581 {582 instruction: 'FROM',583 arguments: ['scratch as llama'],584 linesNumbers: [5]585 }586 ],587 aliases: [588 {589 name: 'build',590 lineNumber: 1591 },592 {593 name: 'llama',594 lineNumber: 5595 }596 ]597 };598 lints.EC0002(parsedFile);599 expect(getErrors()).to.deep.equal([{600 lineNumber: 2,601 errorCode: 'EC0002'602 }]);603 });604 it('Don\'t add error if --from reference to defined FROM alias', function () {605 const parsedFile = {606 groups: [607 {608 instruction: 'FROM',609 arguments: ['scratch as build'],610 linesNumbers: [1]611 },612 {613 instruction: 'FROM',614 arguments: ['scratch as llama'],615 linesNumbers: [5]616 },617 {618 instruction: 'COPY',619 arguments: ['--from=build hello /'],620 linesNumbers: [6]621 }622 ],623 aliases: [624 {625 name: 'build',626 lineNumber: 1627 },628 {629 name: 'llama',630 lineNumber: 5631 }632 ]633 };634 lints.EC0002(parsedFile);635 expect(getErrors()).to.deep.equal([]);636 });637 });638 describe('Check if --from reference to its own FROM alias', () => {639 beforeEach(() => {640 cleanErrors();641 });642 it('Add error if --from reference to its own FROM alias', function () {643 const parsedFile = {644 groups: [645 {646 instruction: 'FROM',647 arguments: ['scratch as build'],648 linesNumbers: [1]649 },650 {651 instruction: 'COPY',652 arguments: ['--from=build hello /'],653 linesNumbers: [2]654 }655 ],656 aliases: [657 {658 name: 'build',659 lineNumber: 1660 }661 ]662 };663 lints.EC0001(parsedFile);664 expect(getErrors()).to.deep.equal([{665 lineNumber: 2,666 errorCode: 'EC0001'667 }]);668 });669 it('Add error if --from reference to its own FROM alias with index', function () {670 const parsedFile = {671 groups: [672 {673 instruction: 'FROM',674 arguments: ['scratch as build'],675 linesNumbers: [1]676 },677 {678 instruction: 'COPY',679 arguments: ['--from=0 hello /'],680 linesNumbers: [2]681 }682 ],683 aliases: [684 {685 name: 'build',686 lineNumber: 1687 }688 ]689 };690 lints.EC0001(parsedFile);691 expect(getErrors()).to.deep.equal([{692 lineNumber: 2,693 errorCode: 'EC0001'694 }]);695 });696 it('Don\'t add error if --from not reference to its own FROM alias', function () {697 const parsedFile = {698 groups: [699 {700 instruction: 'FROM',701 arguments: ['scratch as build'],702 linesNumbers: [1]703 },704 {705 instruction: 'FROM',706 arguments: ['scratch as llama'],707 linesNumbers: [5]708 },709 {710 instruction: 'COPY',711 arguments: ['--from=build hello /'],712 linesNumbers: [6]713 }714 ],715 aliases: [716 {717 name: 'build',718 lineNumber: 1719 },720 {721 name: 'llama',722 lineNumber: 5723 }724 ]725 };726 lints.EC0001(parsedFile);727 expect(getErrors()).to.deep.equal([]);728 });729 });730 describe('Check if instruction is uppercase', () => {731 beforeEach(() => {732 cleanErrors();733 });734 it('Add error if instruction isn\'t uppercase', function () {735 const parsedFile = {736 groups: [737 {738 instruction: 'from',739 arguments: ['buildpack-deps:jessie'],740 linesNumbers: [1]741 }742 ]743 };744 lints.EI0005(parsedFile);745 expect(getErrors()).to.deep.equal([{746 lineNumber: 1,747 errorCode: 'EI0005'748 }]);749 });750 it('Don\'t add error if instruction is uppercase', function () {751 const parsedFile = {752 groups: [753 {754 instruction: 'FROM',755 arguments: ['buildpack-deps:jessie'],756 linesNumbers: [1]757 }758 ]759 };760 lints.EI0005(parsedFile);761 expect(getErrors()).to.deep.equal([]);762 });763 });764 describe('Check if instruction is deprecated', () => {765 beforeEach(() => {766 cleanErrors();767 });768 it('Add error if instruction is deprecated', function () {769 const parsedFile = {770 groups: [771 {772 instruction: 'MAINTAINER',773 arguments: ['llama@jebait.tv'],774 linesNumbers: [3]775 }776 ]777 };778 lints.EI0003(parsedFile);779 expect(getErrors()).to.deep.equal([{780 lineNumber: 3,781 errorCode: 'EI0003'782 }]);783 });784 it('Don\'t add error if instruction isn\'t deprecated', function () {785 const parsedFile = {786 groups: [787 {788 instruction: 'FROM',789 arguments: ['buildpack-deps:jessie'],790 linesNumbers: [1]791 }792 ]793 };794 lints.EI0003(parsedFile);795 expect(getErrors()).to.deep.equal([]);796 });797 });798 describe('Check quotes in JSON array', () => {799 beforeEach(() => {800 cleanErrors();801 });802 it('Add error if JSON array argument is using wrong syntax', function () {803 const parsedFile = {804 groups: [805 {806 instruction: 'RUN',807 arguments: ['[\'/bin/bash\', "-c", "echo hello"]'],808 linesNumbers: [34]809 }810 ]811 };812 lints.EJ0001(parsedFile);813 expect(getErrors()).to.deep.equal([{814 lineNumber: 34,815 errorCode: 'EJ0001'816 }]);817 });818 it('Don\'t add error if JSON array is valid', function () {819 const parsedFile = {820 groups: [821 {822 instruction: 'RUN',823 arguments: ['["/bin/bash", "-c", "echo hello"]'],824 linesNumbers: [34]825 }826 ]827 };828 lints.EJ0001(parsedFile);829 expect(getErrors()).to.deep.equal([]);830 });831 });832 describe('Check if JSON array is suggested', () => {833 beforeEach(() => {834 cleanErrors();835 });836 it('Add error if JSON array is suggested', function () {837 const parsedFile = {838 groups: [839 {840 instruction: 'CMD',841 arguments: ['/usr/bin/wc --help'],842 linesNumbers: [100]843 }844 ]845 };846 lints.EJ0002(parsedFile);847 expect(getErrors()).to.deep.equal([{848 lineNumber: 100,849 errorCode: 'EJ0002'850 }]);851 });852 it('Don\'t add error if JSON array is suggested', function () {853 const parsedFile = {854 groups: [855 {856 instruction: 'CMD',857 arguments: ['["/usr/bin/wc","--help"]'],858 linesNumbers: [100]859 }860 ]861 };862 lints.EJ0002(parsedFile);863 expect(getErrors()).to.deep.equal([]);864 });865 });866 describe('Check if JSON array is required', () => {867 beforeEach(() => {868 cleanErrors();869 });870 it('Add error if JSON array is required', function () {871 const parsedFile = {872 groups: [873 {874 instruction: 'SHELL',875 arguments: ['cmd /S /C'],876 linesNumbers: [100]877 }878 ]879 };880 lints.EJ0003(parsedFile);881 expect(getErrors()).to.deep.equal([{882 lineNumber: 100,883 errorCode: 'EJ0003'884 }]);885 });886 it('Don\'t add error if JSON array is required', function () {887 const parsedFile = {888 groups: [889 {890 instruction: 'SHELL',891 arguments: ['["cmd","/S","/C"]'],892 linesNumbers: [100]893 }894 ]895 };896 lints.EJ0003(parsedFile);897 expect(getErrors()).to.deep.equal([]);898 });899 });900 describe('Check if FROM alias is unique', () => {901 beforeEach(() => {902 cleanErrors();903 });904 it('Add error if FROM alias is\'t unique', function () {905 const parsedFile = {906 aliases: [907 {908 name: 'build',909 lineNumber: 1910 },911 {912 name: 'build',913 lineNumber: 2914 }915 ]916 };917 lints.EF0002(parsedFile);918 expect(getErrors()).to.deep.equal([{919 lineNumber: 2,920 errorCode: 'EF0002'921 }]);922 });923 it('Don\'t add error if FROM alias is unique', function () {924 const parsedFile = {925 aliases: [926 {927 name: 'llama',928 lineNumber: 1929 },930 {931 name: 'build',932 lineNumber: 2933 }934 ]935 };936 lints.EF0002(parsedFile);937 expect(getErrors()).to.deep.equal([]);938 });939 });940 describe('Check if FROM use tag latest', () => {941 beforeEach(() => {942 cleanErrors();943 });944 it('Add error if FROM use tag latest', function () {945 const parsedFile = {946 groups: [947 {948 instruction: 'FROM',949 arguments: ['ubuntu:latest as jebait'],950 linesNumbers: [1]951 }952 ]953 };954 lints.EF0003(parsedFile);955 expect(getErrors()).to.deep.equal([{956 lineNumber: 1,957 errorCode: 'EF0003'958 }]);959 });960 it('Don\'t add error if FROM not use tag latest', function () {961 const parsedFile = {962 groups: [963 {964 instruction: 'FROM',965 arguments: ['ubuntu:notlatest as jebait'],966 linesNumbers: [1]967 }968 ]969 };970 lints.EF0003(parsedFile);971 expect(getErrors()).to.deep.equal([]);972 });973 });974 describe('Check if FROM use tag', () => {975 beforeEach(() => {976 cleanErrors();977 });978 it('Add error if FROM not use tag', function () {979 const parsedFile = {980 groups: [981 {982 instruction: 'FROM',983 arguments: ['ubuntu'],984 linesNumbers: [1]985 }986 ],987 aliases: []988 };989 lints.EF0004(parsedFile);990 expect(getErrors()).to.deep.equal([{991 lineNumber: 1,992 errorCode: 'EF0004'993 }]);994 });995 it('Add error if FROM use undefined alias', function () {996 const parsedFile = {997 groups: [998 {999 instruction: 'FROM',1000 arguments: ['build'],1001 linesNumbers: [1]1002 }1003 ],1004 aliases: [{name: null, lineNumber: 1}]1005 };1006 lints.EF0004(parsedFile);1007 expect(getErrors()).to.deep.equal([{1008 lineNumber: 1,1009 errorCode: 'EF0004'1010 }]);1011 });1012 it('Don\'t add error if FROM use tag', function () {1013 const parsedFile = {1014 groups: [1015 {1016 instruction: 'FROM',1017 arguments: ['ubuntu:notlatest'],1018 linesNumbers: [1]1019 }1020 ],1021 aliases: []1022 };1023 lints.EF0004(parsedFile);1024 expect(getErrors()).to.deep.equal([]);1025 });1026 it('Don\'t add error if FROM use alias', function () {1027 const parsedFile = {1028 groups: [1029 {1030 instruction: 'FROM',1031 arguments: ['ubuntu:notlatest as build'],1032 linesNumbers: [1]1033 },1034 {1035 instruction: 'FROM',1036 arguments: ['build'],1037 linesNumbers: [2]1038 }1039 ],1040 aliases: [{name: "build", lineNumber: 1}, {name: null, lineNumber: 2}]1041 };1042 lints.EF0004(parsedFile);1043 expect(getErrors()).to.deep.equal([]);1044 });1045 });1046 describe('Check if apt-get list is deleted after install', () => {1047 beforeEach(() => {1048 cleanErrors();1049 });1050 it('Add error if deleting apt-get lists is missing', function () {1051 const parsedFile = {1052 groups: [1053 {1054 instruction: 'RUN',1055 arguments: ['apt-get update && apt-get install -y python'],1056 linesNumbers: [4]1057 }1058 ]1059 };1060 lints.ER0002(parsedFile);1061 expect(getErrors()).to.deep.equal([{1062 lineNumber: 4,1063 errorCode: 'ER0002'1064 }]);1065 });1066 it('Don\'t add error if deleting apt-get lists exists', function () {1067 const parsedFile = {1068 groups: [1069 {1070 instruction: 'RUN',1071 arguments: [1072 'apt-get update && apt-get install -y python \\',1073 '&& apt-get clean \\',1074 '&& rm -rf /var/lib/apt/lists/*'1075 ],1076 linesNumbers: [4, 5, 6]1077 }1078 ]1079 };1080 lints.ER0002(parsedFile);1081 expect(getErrors()).to.deep.equal([]);1082 });1083 });1084 describe('Check if command sudo is used', () => {1085 beforeEach(() => {1086 cleanErrors();1087 });1088 it('Add error if sudo is used', function () {1089 const parsedFile = {1090 groups: [1091 {1092 instruction: 'RUN',1093 arguments: ['sudo apt-get install'],1094 linesNumbers: [4]1095 }1096 ]1097 };1098 lints.ER0004(parsedFile);1099 expect(getErrors()).to.deep.equal([{1100 lineNumber: 4,1101 errorCode: 'ER0004'1102 }]);1103 });1104 it('Don\'t add error if sudo is used in echo', function () {1105 const parsedFile = {1106 groups: [1107 {1108 instruction: 'RUN',1109 arguments: ['echo "%sudo ALL=(ALL) NOPASSWD: ALL"'],1110 linesNumbers: [4]1111 }1112 ]1113 };1114 lints.ER0004(parsedFile);1115 expect(getErrors()).to.deep.equal([]);1116 });1117 });1118 describe('Check if command cd is used', () => {1119 beforeEach(() => {1120 cleanErrors();1121 });1122 it('Add error if cd is used', function () {1123 const parsedFile = {1124 groups: [1125 {1126 instruction: 'RUN',1127 arguments: ['cd /usr/src/app'],1128 linesNumbers: [4]1129 }1130 ]1131 };1132 lints.ER0003(parsedFile);1133 expect(getErrors()).to.deep.equal([{1134 lineNumber: 4,1135 errorCode: 'ER0003'1136 }]);1137 });1138 });1139 describe('Check if pointless commands are used', () => {1140 beforeEach(() => {1141 cleanErrors();1142 });1143 it('Add error if command top is used', function () {1144 const parsedFile = {1145 groups: [1146 {1147 instruction: 'RUN',1148 arguments: ['top'],1149 linesNumbers: [4]1150 }1151 ]1152 };1153 lints.ER0005(parsedFile);1154 expect(getErrors()).to.deep.equal([{1155 lineNumber: 4,1156 errorCode: 'ER0005'1157 }]);1158 });1159 it('Don\'t add error if pointless command is used in install', function () {1160 const parsedFile = {1161 groups: [1162 {1163 instruction: 'RUN',1164 arguments: ['apt-get install -y sudo vim nano less tree bash-completion mariadb-client iputils-ping '],1165 linesNumbers: [4]1166 }1167 ]1168 };1169 lints.ER0005(parsedFile);1170 expect(getErrors()).to.deep.equal([])1171 });1172 });1173 describe('Check if not recommended commands are used', () => {1174 beforeEach(() => {1175 cleanErrors();1176 });1177 it('Add error if apt-get upgrade is used', function () {1178 const parsedFile = {1179 groups: [1180 {1181 instruction: 'RUN',1182 arguments: ['apt-get update && apt-get upgrade'],1183 linesNumbers: [4]1184 }1185 ]1186 };1187 lints.ER0006(parsedFile);1188 expect(getErrors()).to.deep.equal([{1189 lineNumber: 4,1190 errorCode: 'ER0006'1191 }]);1192 });1193 });1194 describe('Check if ADD is used for fetching packages', () => {1195 beforeEach(() => {1196 cleanErrors();1197 });1198 it('Add error if ADD is used for fetching packages', function () {1199 const parsedFile = {1200 groups: [1201 {1202 instruction: 'ADD',1203 arguments: ['http://example.com/big.tar.xz /usr/src/things/'],1204 linesNumbers: [4]1205 }1206 ]1207 };1208 lints.EA0001(parsedFile);1209 expect(getErrors()).to.deep.equal([{1210 lineNumber: 4,1211 errorCode: 'EA0001'1212 }]);1213 });1214 });1215 describe('Check if COPY is used for archives', () => {1216 beforeEach(() => {1217 cleanErrors();1218 });1219 it('Add error if COPY is used for archives', function () {1220 const parsedFile = {1221 groups: [1222 {1223 instruction: 'COPY',1224 arguments: ['big.tar.xz /usr/src/things/'],1225 linesNumbers: [4]1226 }1227 ]1228 };1229 lints.EC0003(parsedFile);1230 expect(getErrors()).to.deep.equal([{1231 lineNumber: 4,1232 errorCode: 'EC0003'1233 }]);1234 });1235 });1236 describe('Check if wget and curl are used simultaneously', () => {1237 beforeEach(() => {1238 cleanErrors();1239 });1240 it('Add error if wget and curl are used simultaneously,but first curl', function () {1241 const parsedFile = {1242 groups: [1243 {1244 instruction: 'RUN',1245 arguments: ['curl -O - https://some.site | wc -l > /number'],1246 linesNumbers: [3]1247 },1248 {1249 instruction: 'RUN',1250 arguments: ['wget -O - https://some.site | wc -l > /number'],1251 linesNumbers: [4]1252 }1253 ]1254 };1255 lints.ER0007(parsedFile);1256 expect(getErrors()).to.deep.equal([{1257 lineNumber: 4,1258 errorCode: 'ER0007'1259 }]);1260 });1261 it('Add error if wget and curl are used simultaneously,but first wget', function () {1262 const parsedFile = {1263 groups: [1264 {1265 instruction: 'RUN',1266 arguments: ['wget -O - https://some.site | wc -l > /number'],1267 linesNumbers: [3]1268 },1269 {1270 instruction: 'RUN',1271 arguments: ['curl -O - https://some.site | wc -l > /number'],1272 linesNumbers: [4]1273 }1274 ]1275 };1276 lints.ER0007(parsedFile);1277 expect(getErrors()).to.deep.equal([{1278 lineNumber: 4,1279 errorCode: 'ER0007'1280 }]);1281 });1282 it('Don\'t add error if wget and curl aren\'t used simultaneously', function () {1283 const parsedFile = {1284 groups: [1285 {1286 instruction: 'RUN',1287 arguments: ['wget -O - https://some.site | wc -l > /number'],1288 linesNumbers: [3]1289 },1290 {1291 instruction: 'RUN',1292 arguments: ['wget -O - https://some.site | wc -l > /number'],1293 linesNumbers: [4]1294 }1295 ]1296 };1297 lints.ER0007(parsedFile);1298 expect(getErrors()).to.deep.equal([]);1299 });1300 });1301 describe('Check if default shell is overwrite', () => {1302 beforeEach(() => {1303 cleanErrors();1304 });1305 it('Add error if shell is overwrite', function () {1306 const parsedFile = {1307 groups: [1308 {1309 instruction: 'RUN',1310 arguments: ['ln -sfv /bin/bash /bin/sh'],1311 linesNumbers: [4]1312 }1313 ]1314 };1315 lints.ER0008(parsedFile);1316 expect(getErrors()).to.deep.equal([{1317 lineNumber: 4,1318 errorCode: 'ER0008'1319 }]);1320 });1321 it('Don\'t add error if shell isn\'t overwrite', function () {1322 const parsedFile = {1323 groups: [1324 {1325 instruction: 'RUN',1326 arguments: ['curl -O - https://some.site | wc -l > /number'],1327 linesNumbers: [4]1328 }1329 ]1330 };1331 lints.ER0008(parsedFile);1332 expect(getErrors()).to.deep.equal([]);1333 });1334 });1335 describe('Check if flag -y/--asumme-yes isn\'t used', () => {1336 beforeEach(() => {1337 cleanErrors();1338 });1339 it('Add error if flag -y/--asumme-yes isn\'t used', function () {1340 const parsedFile = {1341 groups: [1342 {1343 instruction: 'RUN',1344 arguments: ['apt-get install python=2.7'],1345 linesNumbers: [4]1346 }1347 ]1348 };1349 lints.ER0009(parsedFile);1350 expect(getErrors()).to.deep.equal([{1351 lineNumber: 4,1352 errorCode: 'ER0009'1353 }]);1354 });1355 it('Don\'t add error if flag -yq is used', function () {1356 const parsedFile = {1357 groups: [1358 {1359 instruction: 'RUN',1360 arguments: ['apt-get install -yq python=2.7'],1361 linesNumbers: [4]1362 }1363 ]1364 };1365 lints.ER0009(parsedFile);1366 expect(getErrors()).to.deep.equal([]);1367 });1368 it('Don\'t add error if flag -y is used', function () {1369 const parsedFile = {1370 groups: [1371 {1372 instruction: 'RUN',1373 arguments: ['apt-get install -y python=2.7'],1374 linesNumbers: [4]1375 }1376 ]1377 };1378 lints.ER0009(parsedFile);1379 expect(getErrors()).to.deep.equal([]);1380 });1381 it('Don\'t add error if flag --assume-yes is used', function () {1382 const parsedFile = {1383 groups: [1384 {1385 instruction: 'RUN',1386 arguments: ['apt-get install --assume-yes python=2.7'],1387 linesNumbers: [4]1388 }1389 ]1390 };1391 lints.ER0009(parsedFile);1392 expect(getErrors()).to.deep.equal([]);1393 });1394 });1395 describe('Check if flag --no-install-recommends isn\'t used', () => {1396 beforeEach(() => {1397 cleanErrors();1398 });1399 it('Add error if flag --no-install-recommends isn\'t used', function () {1400 const parsedFile = {1401 groups: [1402 {1403 instruction: 'RUN',1404 arguments: ['apt-get install -y python=2.7'],1405 linesNumbers: [4]1406 }1407 ]1408 };1409 lints.ER0010(parsedFile);1410 expect(getErrors()).to.deep.equal([{1411 lineNumber: 4,1412 errorCode: 'ER0010'1413 }]);1414 });1415 it('Don\'t add error if flag --no-install-recommends is used', function () {1416 const parsedFile = {1417 groups: [1418 {1419 instruction: 'RUN',1420 arguments: ['apt-get install -y --no-install-recommends python=2.7'],1421 linesNumbers: [4]1422 }1423 ]1424 };1425 lints.ER0010(parsedFile);1426 expect(getErrors()).to.deep.equal([]);1427 });1428 });1429 describe('Check if COPY is used for archives', () => {1430 beforeEach(() => {1431 cleanErrors();1432 });1433 it('Add error if COPY is used for archives', function () {1434 const parsedFile = {1435 groups: [1436 {1437 instruction: 'ADD',1438 arguments: ['requirements.txt /usr/src/app/'],1439 linesNumbers: [4]1440 }1441 ]1442 };1443 lints.EA0002(parsedFile);1444 expect(getErrors()).to.deep.equal([{1445 lineNumber: 4,1446 errorCode: 'EA0002'1447 }]);1448 });1449 it('Don\'t add error if COPY isn\'t used for archives', function () {1450 const parsedFile = {1451 groups: [1452 {1453 instruction: 'ADD',1454 arguments: ['ubuntu-bionic-core-cloudimg-amd64-root.tar.gz /'],1455 linesNumbers: [4]1456 }1457 ]1458 };1459 lints.EA0002(parsedFile);1460 expect(getErrors()).to.deep.equal([]);1461 });1462 });1463 describe('Check if COPY with more then 2 arguments ends with /', () => {1464 beforeEach(() => {1465 cleanErrors();1466 });1467 it('Add error if COPY with more then 2 arguments don\'t ends with /', function () {1468 const parsedFile = {1469 groups: [1470 {1471 instruction: 'COPY',1472 arguments: ['package.json yarn.lock my_app'],1473 linesNumbers: [4]1474 }1475 ]1476 };1477 lints.EC0004(parsedFile);1478 expect(getErrors()).to.deep.equal([{1479 lineNumber: 4,1480 errorCode: 'EC0004'1481 }]);1482 });1483 it('Don\'t add error if COPY with more then 2 arguments ends with /', function () {1484 const parsedFile = {1485 groups: [1486 {1487 instruction: 'ADD',1488 arguments: ['package.json yarn.lock my_app/'],1489 linesNumbers: [4]1490 }1491 ]1492 };1493 lints.EC0004(parsedFile);1494 expect(getErrors()).to.deep.equal([]);1495 });1496 });1497 describe('Check if command apk add use flag --no-cache', () => {1498 beforeEach(() => {1499 cleanErrors();1500 });1501 it('Add error if command apk add don\'t use flag --no-cache', function () {1502 const parsedFile = {1503 groups: [1504 {1505 instruction: 'RUN',1506 arguments: ['apk add foo=1.0'],1507 linesNumbers: [4]1508 }1509 ],1510 escape: '\\'1511 };1512 lints.ER0011(parsedFile);1513 expect(getErrors()).to.deep.equal([{1514 lineNumber: 4,1515 errorCode: 'ER0011'1516 }]);1517 });1518 it('Don\'t add error if command apk add use flag --no-cache', function () {1519 const parsedFile = {1520 groups: [1521 {1522 instruction: 'RUN',1523 arguments: ['apk add --no-cache foo=1.0'],1524 linesNumbers: [4]1525 }1526 ]1527 };1528 lints.ER0011(parsedFile);1529 expect(getErrors()).to.deep.equal([]);1530 });1531 });1532 describe('Check if packages in apt-get install are using version pining', () => {1533 beforeEach(() => {1534 cleanErrors();1535 });1536 it('Add error if packages in apt-get install aren\'t using version pining', function () {1537 const parsedFile = {1538 groups: [1539 {1540 instruction: 'RUN',1541 arguments: ['apt-get install python'],1542 linesNumbers: [4]1543 }1544 ],1545 escape: '\\'1546 };1547 lints.ER0012(parsedFile);1548 expect(getErrors()).to.deep.equal([{1549 lineNumber: 4,1550 errorCode: 'ER0012'1551 }]);1552 });1553 it('Don\'t add error if packages in apt-get install are using version pining', function () {1554 const parsedFile = {1555 groups: [1556 {1557 instruction: 'RUN',1558 arguments: ['apt-get install python=2.7'],1559 linesNumbers: [4]1560 }1561 ]1562 };1563 lints.ER0012(parsedFile);1564 expect(getErrors()).to.deep.equal([]);1565 });1566 });1567 describe('Check if packages in pip install are using version pining', () => {1568 beforeEach(() => {1569 cleanErrors();1570 });1571 it('Add error if packages in pip install aren\'t using version pining', function () {1572 const parsedFile = {1573 groups: [1574 {1575 instruction: 'RUN',1576 arguments: ['pip install django'],1577 linesNumbers: [4]1578 }1579 ],1580 escape: '\\'1581 };1582 lints.ER0013(parsedFile);1583 expect(getErrors()).to.deep.equal([{1584 lineNumber: 4,1585 errorCode: 'ER0013'1586 }]);1587 });1588 it('Don\'t add error if packages in pip are using version pining', function () {1589 const parsedFile = {1590 groups: [1591 {1592 instruction: 'RUN',1593 arguments: ['pip install django==1.9'],1594 linesNumbers: [4]1595 }1596 ]1597 };1598 lints.ER0013(parsedFile);1599 expect(getErrors()).to.deep.equal([]);1600 });1601 it('Don\'t add error if packages in pip are using version pining and flag', function () {1602 const parsedFile = {1603 groups: [1604 {1605 instruction: 'RUN',1606 arguments: ['pip install django==1.9 --no-cache-dir'],1607 linesNumbers: [4]1608 }1609 ]1610 };1611 lints.ER0013(parsedFile);1612 expect(getErrors()).to.deep.equal([]);1613 });1614 });1615 describe('Check if packages in npm install are using version pining', () => {1616 beforeEach(() => {1617 cleanErrors();1618 });1619 it('Add error if packages in npm install aren\'t using version pining', function () {1620 const parsedFile = {1621 groups: [1622 {1623 instruction: 'RUN',1624 arguments: ['npm install @myorg/mypackage'],1625 linesNumbers: [4]1626 }1627 ],1628 escape: '\\'1629 };1630 lints.ER0014(parsedFile);1631 expect(getErrors()).to.deep.equal([{1632 lineNumber: 4,1633 errorCode: 'ER0014'1634 }]);1635 });1636 it('Don\'t add error if packages in npm install are using version pining', function () {1637 const parsedFile = {1638 groups: [1639 {1640 instruction: 'RUN',1641 arguments: ['npm install express@"4.1.1" sax@0.1.1'],1642 linesNumbers: [4]1643 }1644 ]1645 };1646 lints.ER0014(parsedFile);1647 expect(getErrors()).to.deep.equal([]);1648 });1649 });1650 describe('Check if packages in apk add are using version pining', () => {1651 beforeEach(() => {1652 cleanErrors();1653 });1654 it('Add error if packages in apk add aren\'t using version pining', function () {1655 const parsedFile = {1656 groups: [1657 {1658 instruction: 'RUN',1659 arguments: ['apk add asterisk'],1660 linesNumbers: [4]1661 }1662 ],1663 escape: '\\'1664 };1665 lints.ER0015(parsedFile);1666 expect(getErrors()).to.deep.equal([{1667 lineNumber: 4,1668 errorCode: 'ER0015'1669 }]);1670 });1671 it('Don\'t add error if packages in apk add are using version pining', function () {1672 const parsedFile = {1673 groups: [1674 {1675 instruction: 'RUN',1676 arguments: ['apk add asterisk=1.6.0.21-r0'],1677 linesNumbers: [4]1678 }1679 ]1680 };1681 lints.ER0015(parsedFile);1682 expect(getErrors()).to.deep.equal([]);1683 });1684 });1685 describe('Check if packages in gem install are using version pining', () => {1686 beforeEach(() => {1687 cleanErrors();1688 });1689 it('Add error if packages in gem install aren\'t using version pining', function () {1690 const parsedFile = {1691 groups: [1692 {1693 instruction: 'RUN',1694 arguments: ['gem install \\', 'bundler'],1695 linesNumbers: [4, 5]1696 }1697 ],1698 escape: '\\'1699 };1700 lints.ER0016(parsedFile);1701 expect(getErrors()).to.deep.equal([{1702 lineNumber: 4,1703 errorCode: 'ER0016'1704 }]);1705 });1706 it('Don\'t add error if packages in gem install are using version pining', function () {1707 const parsedFile = {1708 groups: [1709 {1710 instruction: 'RUN',1711 arguments: ['gem install bundler:1.1'],1712 linesNumbers: [4]1713 }1714 ]1715 };1716 lints.ER0016(parsedFile);1717 expect(getErrors()).to.deep.equal([]);1718 });1719 it('Don\'t add error if packages in gem install are using version pining with flag -v', function () {1720 const parsedFile = {1721 groups: [1722 {1723 instruction: 'RUN',1724 arguments: ['gem install --platform test bundler -v 1.1 --'],1725 linesNumbers: [4]1726 }1727 ]1728 };1729 lints.ER0016(parsedFile);1730 expect(getErrors()).to.deep.equal([]);1731 });1732 });1733 describe('Check if ONBUILD contain not allowed instruction', () => {1734 beforeEach(() => {1735 cleanErrors();1736 });1737 it('Add error if ONBUILD contain not allowed instruction', function () {1738 const parsedFile = {1739 groups: [1740 {1741 instruction: 'ONBUILD',1742 arguments: [''],1743 linesNumbers: [4],1744 onBuild: true1745 }1746 ],1747 escape: '\\'1748 };1749 lints.EI0004(parsedFile);1750 expect(getErrors()).to.deep.equal([{1751 lineNumber: 4,1752 errorCode: 'EI0004'1753 }]);1754 });1755 it('Don\'t add error if ONBUILD contain allowed instruction', function () {1756 const parsedFile = {1757 groups: [1758 {1759 instruction: 'RUN',1760 arguments: ['gem install bundler:1.1'],1761 linesNumbers: [4]1762 }1763 ]1764 };1765 lints.EI0004(parsedFile);1766 expect(getErrors()).to.deep.equal([]);1767 });1768 });1769 describe('Check if WORKDIR use absolute path', () => {1770 beforeEach(() => {1771 cleanErrors();1772 });1773 it('Add error if WORKDIR not use absolute path', function () {1774 const parsedFile = {1775 groups: [1776 {1777 instruction: 'WORKDIR',1778 arguments: ['usr/src/app'],1779 linesNumbers: [4]1780 }1781 ],1782 escape: '\\'1783 };1784 lints.EW0001(parsedFile);1785 expect(getErrors()).to.deep.equal([{1786 lineNumber: 4,1787 errorCode: 'EW0001'1788 }]);1789 });1790 it('Don\'t add error if WORKDIR use absolute path', function () {1791 const parsedFile = {1792 groups: [1793 {1794 instruction: 'WORKDIR',1795 arguments: ['/usr/src/app'],1796 linesNumbers: [4]1797 }1798 ]1799 };1800 lints.EW0001(parsedFile);1801 expect(getErrors()).to.deep.equal([]);1802 });1803 });1804 describe('Check if ports in EXOPSE are valid', () => {1805 beforeEach(() => {1806 cleanErrors();1807 });1808 it('Add error if ports in EXOPSE aren\'t valid', function () {1809 const parsedFile = {1810 groups: [1811 {1812 instruction: 'EXPOSE',1813 arguments: ['99999 99 999999'],1814 linesNumbers: [4]1815 }1816 ],1817 escape: '\\'1818 };1819 lints.EE0001(parsedFile);1820 expect(getErrors()).to.deep.equal([{1821 lineNumber: 4,1822 errorCode: 'EE0001'1823 }]);1824 });1825 it('Don\'t add error if ports in EXOPSE are valid', function () {1826 const parsedFile = {1827 groups: [1828 {1829 instruction: 'EXPOSE',1830 arguments: ['1234 11 12 13'],1831 linesNumbers: [4]1832 }1833 ]1834 };1835 lints.EE0001(parsedFile);1836 expect(getErrors()).to.deep.equal([]);1837 });1838 it('Don\'t add error if port with protocol in EXOPSE are valid', function () {1839 const parsedFile = {1840 groups: [1841 {1842 instruction: 'EXPOSE',1843 arguments: ['80/udp'],1844 linesNumbers: [4]1845 }1846 ]1847 };1848 lints.EE0001(parsedFile);1849 expect(getErrors()).to.deep.equal([]);1850 });1851 it('Don\'t add error if port was passed with variable to EXOPSE without default value', function () {1852 const parsedFile = {1853 groups: [1854 {1855 instruction: 'EXPOSE',1856 arguments: ['""'],1857 linesNumbers: [4]1858 }1859 ]1860 };1861 lints.EE0001(parsedFile);1862 expect(getErrors()).to.deep.equal([]);1863 });1864 });...

Full Screen

Full Screen

lints.js

Source:lints.js Github

copy

Full Screen

1const {instructionStart, instructionEnd} = require('./groups_helpers');2const {lineContainDirective, directives} = require('./directives_helpers');3const {4 regexInstruction, getArgumentsArrayForInstruction, nearestFrom,5 getArgumentsLine, getArgumentsArrayForCommand, regexCommand, findLineNumber,6 cmdInHealthcheck, isIgnored7} = require('./lints_helpers');8const {addError} = require('./errors');9function invalidLine(parsedFile) {10 let filteredLines = parsedFile.lines.filter((line) => {11 return !line.text.startsWith("#") && line.text.length > 012 });13 let escape = parsedFile.escape;14 let inInstruction = false;15 for (let i = 0; i < filteredLines.length; i++) {16 if (!inInstruction) {17 if (instructionStart(filteredLines[i])) {18 inInstruction = true;19 } else {20 addError(filteredLines[i].lineNumber, 'EL0001')21 }22 } else {23 if (!instructionStart(filteredLines[i]) && !instructionEnd(filteredLines, i, escape)) {24 inInstruction = false;25 addError(filteredLines[i].lineNumber, 'EL0001')26 }27 }28 }29}30function checkForRepetitions(parsedFile) {31 directives.forEach((directive) => {32 let list = parsedFile.parserDirectives.filter((el) => {33 return el.directive.toLowerCase() === directive34 });35 if (list.length > 1) {36 for (let index = 1; index < list.length; index++) {37 addError(list[index].lineNumber, "ED0002");38 }39 }40 });41}42function lowercaseConvention(parsedFile) {43 parsedFile.parserDirectives.forEach((el) => {44 if (el.directive !== el.directive.toLowerCase()) {45 addError(el.lineNumber, "ED0003")46 }47 })48}49function directiveWillBeIgnored(parsedFile) {50 let treatedAsCommand = false;51 for (let i = 0; i < parsedFile.lines.length; i++) {52 if (!treatedAsCommand) {53 if (parsedFile.lines[i].text.startsWith("#") && !lineContainDirective(parsedFile.lines[i].text)) {54 treatedAsCommand = true55 } else {56 treatedAsCommand = true57 }58 } else if (parsedFile.lines[i].text.startsWith("#") && lineContainDirective(parsedFile.lines[i].text)) {59 addError(parsedFile.lines[i].lineNumber, "ED0004");60 }61 }62}63function directivesOnTopOfDockerfile(parsedFile) {64 if (parsedFile.lines[0].text.startsWith("#") && parsedFile.lines[0].lineNumber !== 1) {65 if (lineContainDirective(parsedFile.lines[0].text)) {66 addError(parsedFile.lines[0].lineNumber, "ED0001");67 }68 }69}70function missingValueForDirective(parsedFile) {71 for (let i = 0; i < parsedFile.parserDirectives.length; i++) {72 if (parsedFile.parserDirectives[i].value.length === 0) {73 addError(parsedFile.parserDirectives[i].lineNumber, "ED0005")74 }75 }76}77function pipefailBeforeRun(parsedFile) {78 let pipesUsedList = [];79 for (let i = 0; i < parsedFile.groups.length; i++) {80 if (parsedFile.groups[i].instruction.toUpperCase() === 'RUN' && !isIgnored('ER0001', parsedFile.groups[i].linesNumbers[0], parsedFile.inlineIgnores)) {81 for (let j = 0; j < parsedFile.groups[i].arguments.length; j++) {82 //dodajemy do listy kazde wystapienie pipeline83 if (parsedFile.groups[i].arguments[j].match(/(^|\s)\|(\s|\\)/)) {84 pipesUsedList.push({85 lineNumber: parsedFile.groups[i].linesNumbers[j],86 groupNumber: i87 })88 }89 }90 }91 }92 for (let i = 0; i < pipesUsedList.length; i++) {93 pipesLoop:94 //szukamy instukcji SHELL w grupach pomiedzy wystapieniem pipeline i instukcji FROM95 for (let j = pipesUsedList[i].groupNumber; j >= 0; j--) {96 if (parsedFile.groups[j].instruction.toUpperCase() === 'SHELL') {97 for (let k = 0; k < parsedFile.groups[j].arguments.length; k++) {98 if (parsedFile.groups[j].arguments[k].match(regexInstruction('pipefail'))) {99 break pipesLoop100 }101 }102 }103 if (parsedFile.groups[j].instruction.toUpperCase() === 'FROM') {104 addError(pipesUsedList[i].lineNumber, 'ER0001');105 break106 }107 }108 }109}110function lastUserShouldNotBeRoot(parsedFile) {111 let lastUserRoot = {112 status: false,113 lineNumber: 0114 };115 parsedFile.groups.forEach((group) => {116 if (group.instruction.toUpperCase() === 'USER' && !isIgnored('EU0001', group.linesNumbers[0], parsedFile.inlineIgnores)) {117 if (group.arguments[0].toLowerCase() === 'root') {118 lastUserRoot = {119 status: true,120 lineNumber: group.linesNumbers[0]121 }122 } else {123 lastUserRoot = {124 status: false,125 lineNumber: group.linesNumbers[0]126 }127 }128 }129 });130 if (lastUserRoot.status) {131 addError(lastUserRoot.lineNumber, 'EU0001');132 }133}134function onlyOnceAllowedInstructions(parsedFile) {135 const onlyOnceAllowed = ["CMD", "HEALTHCHECK", "ENTRYPOINT"];136 for (let i = 0; i < onlyOnceAllowed.length; i++) {137 let count = 0;138 parsedFile.groups.forEach((group, index) => {139 if (!isIgnored('EI0001', group.linesNumbers[0], parsedFile.inlineIgnores)) {140 if (group.instruction.toUpperCase() === onlyOnceAllowed[i] && !cmdInHealthcheck(parsedFile, index)) {141 count++;142 if (count > 1) {143 addError(group.linesNumbers[0], 'EI0001')144 }145 }146 }147 })148 }149}150function onlyArgBeforeFrom(parsedFile) {151 let fromLineNumber = 0;152 let fromGroupIndex;153 for (let index = 0; index < parsedFile.groups.length; index++) {154 if (parsedFile.groups[index].instruction.toUpperCase() === 'FROM') {155 fromLineNumber = parsedFile.groups[index].linesNumbers[0];156 fromGroupIndex = index;157 break158 }159 }160 //jezeli FROM nie jest w pierwszej linii, sprawdzamy grupy nad nim161 if (fromLineNumber !== 1) {162 for (let i = 0; i < fromGroupIndex; i++) {163 if (parsedFile.groups[i].instruction.toUpperCase() !== 'ARG' && !isIgnored('EI0002', parsedFile.groups[i].linesNumbers[0], parsedFile.inlineIgnores)) {164 addError(parsedFile.groups[i].linesNumbers[0], "EI0002")165 }166 }167 }168}169function fromExists(parsedFile) {170 let fromLineNumber = 0;171 for (let index = 0; index < parsedFile.groups.length; index++) {172 if (parsedFile.groups[index].instruction.toUpperCase() === 'FROM') {173 fromLineNumber = parsedFile.groups[index].linesNumbers[0];174 break175 }176 }177 if (fromLineNumber === 0) {178 addError(parsedFile.groups[0].linesNumbers[0], 'EF0001')179 }180}181function copyFromOptionShouldReferenceToDefinedFromAlias(parsedFile) {182 for (let i = 0; i < parsedFile.groups.length; i++) {183 if (parsedFile.groups[i].instruction.toUpperCase() === 'COPY' && !isIgnored('EC0002', parsedFile.groups[i].linesNumbers[0], parsedFile.inlineIgnores)) {184 let optionAsString = parsedFile.groups[i].arguments[0].match(/(?<=--from=)(\S+)/);185 let nearest = nearestFrom(parsedFile.groups[i].linesNumbers[0], parsedFile.aliases);186 if (optionAsString) {187 //Odwalanie sie do FROM przez alias188 if (isNaN(optionAsString[0]) && nearest.name !== optionAsString[0].toLowerCase()) {189 let exists = false;190 for (let j = 0; j < nearest.index; j++) {191 if (parsedFile.aliases[j].name === optionAsString[0]) {192 exists = true;193 }194 }195 if (!exists) {196 addError(parsedFile.groups[i].linesNumbers[0], 'EC0002')197 }198 } else {199 //Odwolanie sie do FROM przez index200 let optionAsInt = parseInt(optionAsString[0]);201 if (optionAsInt > nearest.index) {202 addError(parsedFile.groups[i].linesNumbers[0], 'EC0002')203 }204 }205 }206 }207 }208}209function copyFromOptionReferenceToOwnFromAlias(parsedFile) {210 for (let i = 0; i < parsedFile.groups.length; i++) {211 if (parsedFile.groups[i].instruction.toUpperCase() === 'COPY' && !isIgnored('EC0001', parsedFile.groups[i].linesNumbers[0], parsedFile.inlineIgnores)) {212 let optionAsString = parsedFile.groups[i].arguments[0].match(/(?<=--from=)(\w+)/);213 let nearest = nearestFrom(parsedFile.groups[i].linesNumbers[0], parsedFile.aliases);214 if (optionAsString) {215 //Odwalanie sie do FROM przez alias216 if (isNaN(optionAsString[0]) && nearest.name === optionAsString[0].toLowerCase()) {217 addError(parsedFile.groups[i].linesNumbers[0], 'EC0001')218 } else {219 //Odwolanie sie do FROM przez index220 let optionAsInt = parseInt(optionAsString[0]);221 if (optionAsInt === nearest.index) {222 addError(parsedFile.groups[i].linesNumbers[0], 'EC0001')223 }224 }225 }226 }227 }228}229function uppercaseCheck(parsedFile) {230 for (let i = 0; i < parsedFile.groups.length; i++) {231 if (parsedFile.groups[i].instruction !== parsedFile.groups[i].instruction.toUpperCase() && !isIgnored('EI0005', parsedFile.groups[i].linesNumbers[0], parsedFile.inlineIgnores)) {232 addError(parsedFile.groups[i].linesNumbers[0], 'EI0005')233 }234 }235}236function deprecatedInstruction(parsedFile) {237 const deprecatedInstructions = [{238 name: "MAINTAINER",239 errorCode: 'EI0003'240 }];241 for (let i = 0; i < parsedFile.groups.length; i++) {242 deprecatedInstructions.forEach((instruction) => {243 if (parsedFile.groups[i].instruction.toUpperCase() === instruction.name && !isIgnored(instruction.errorCode, parsedFile.groups[i].linesNumbers[0], parsedFile.inlineIgnores)) {244 addError(parsedFile.groups[i].linesNumbers[0], instruction.errorCode)245 }246 });247 }248}249function lintJson(parsedFile) {250 let instructions = ["RUN", "CMD", "VOLUME", "ENTRYPOINT", "SHELL"];251 for (let i = 0; i < parsedFile.groups.length; i++) {252 for (let j = 0; j < instructions.length; j++) {253 if (parsedFile.groups[i].instruction.toUpperCase() === instructions[j] && !isIgnored('EJ0001', parsedFile.groups[i].linesNumbers[0], parsedFile.inlineIgnores)) {254 //sprawdzanie czy JSON array zostal uzyty255 if (parsedFile.groups[i].arguments[0].startsWith('[') && parsedFile.groups[i].arguments[0].endsWith(']')) {256 //czy nie jest pusta tablica257 if (parsedFile.groups[i].arguments[0].length > 2) {258 let jsonArray = parsedFile.groups[i].arguments[0]259 .substring(1, parsedFile.groups[i].arguments[0].length - 1)260 .split(',');261 jsonArray = jsonArray.map((item) => {262 return item.trim();263 });264 //sprawdzanie czy kazdy element tablicy ma odpowiedni cudzyslow265 jsonArray.forEach((item) => {266 if (!item.startsWith('"') || !item.endsWith('"')) {267 addError(parsedFile.groups[i].linesNumbers[0], "EJ0001")268 }269 })270 }271 }272 }273 }274 }275}276function shouldUseJson(parsedFile) {277 let instructions = ["CMD", "ENTRYPOINT"];278 for (let i = 0; i < parsedFile.groups.length; i++) {279 for (let j = 0; j < instructions.length; j++) {280 if (parsedFile.groups[i].instruction.toUpperCase() === instructions[j] && !isIgnored('EJ0002', parsedFile.groups[i].linesNumbers[0], parsedFile.inlineIgnores)) {281 if (!parsedFile.groups[i].arguments[0].startsWith('[') && !parsedFile.groups[i].arguments[0].endsWith(']')) {282 addError(parsedFile.groups[i].linesNumbers[0], 'EJ0002')283 }284 }285 }286 }287}288function mustUseJson(parsedFile) {289 for (let i = 0; i < parsedFile.groups.length; i++) {290 if (parsedFile.groups[i].instruction.toUpperCase() === "SHELL" && !isIgnored('EJ0003', parsedFile.groups[i].linesNumbers[0], parsedFile.inlineIgnores)) {291 if (!parsedFile.groups[i].arguments[0].startsWith('[') && !parsedFile.groups[i].arguments[0].endsWith(']')) {292 addError(parsedFile.groups[i].linesNumbers[0], 'EJ0003')293 }294 }295 }296}297function fromAliasMustBeUnique(parsedFile) {298 for (let i = parsedFile.aliases.length - 1; i >= 0; i--) {299 for (let j = i - 1; j >= 0; j--) {300 if (!isIgnored('EF0002', parsedFile.aliases[i].lineNumber, parsedFile.inlineIgnores)) {301 if (parsedFile.aliases[i].name === parsedFile.aliases[j].name && parsedFile.aliases[i].name) {302 addError(parsedFile.aliases[i].lineNumber, 'EF0002')303 }304 }305 }306 }307}308function usedTagLatest(parsedFile) {309 for (let i = 0; i < parsedFile.groups.length; i++) {310 if (parsedFile.groups[i].instruction.toUpperCase() === "FROM" && !isIgnored('EF0003', parsedFile.groups[i].linesNumbers[0], parsedFile.inlineIgnores)) {311 //jezeli nie jest uzyta zmienna ARG albo ENV312 if (!parsedFile.groups[i].arguments[0].startsWith('$') && parsedFile.groups[i].arguments[0].match(/:latest([^\w]|$)/)) {313 addError(parsedFile.groups[i].linesNumbers[0], 'EF0003');314 }315 }316 }317}318function alwaysTag(parsedFile) {319 for (let i = 0; i < parsedFile.groups.length; i++) {320 if (!isIgnored('EF0004', parsedFile.groups[i].linesNumbers[0], parsedFile.inlineIgnores)) {321 if (parsedFile.groups[i].instruction.toUpperCase() === "FROM" && parsedFile.groups[i].arguments[0].toLowerCase() !== 'scratch') {322 //jezeli nie jest uzyta zmienna ARG albo ENV i nie ma taga323 if (!parsedFile.groups[i].arguments[0].startsWith('$') && !parsedFile.groups[i].arguments[0].match(/:/)) {324 if (parsedFile.aliases.length !== 0) {325 //sprawdzamy czy FROM nie odwołuje się od wczesniej zdefiniowanego aliasa326 let test = parsedFile.aliases.find((alias) => {327 return alias.name === parsedFile.groups[i].arguments[0].match(/^[\w.]+/)[0].toLowerCase()328 });329 if (!test) {330 addError(parsedFile.groups[i].linesNumbers[0], 'EF0004');331 }332 } else {333 addError(parsedFile.groups[i].linesNumbers[0], 'EF0004');334 }335 }336 }337 }338 }339}340function deleteAptGetListsAfterInstall(parsedFile) {341 for (let m = 0; m < parsedFile.groups.length; m++) {342 if (parsedFile.groups[m].instruction.toUpperCase() === 'RUN' && !isIgnored('ER0002', parsedFile.groups[m].linesNumbers[0], parsedFile.inlineIgnores)) {343 let argumentsArrays = getArgumentsArrayForCommand(getArgumentsLine(parsedFile.groups[m], parsedFile.escape), 'apt-get');344 //sprawdzamy czy w tej samej grupie RUN po wystapieniu apt-get install jest komenda do usuniecia listy345 if (argumentsArrays) {346 for (let i = 0; i < argumentsArrays.length; i++) {347 if (argumentsArrays[i].array[0] === 'install') {348 let test = parsedFile.groups[m].arguments.filter((line) => {349 return line.match(/rm.+\/var\/lib\/apt\/lists\/\*/)350 });351 if (test.length === 0) {352 addError(findLineNumber(parsedFile.groups[m], parsedFile.escape, argumentsArrays[i].startIndex), 'ER0002');353 }354 }355 }356 }357 }358 }359}360function notUseSudo(parsedFile) {361 for (let m = 0; m < parsedFile.groups.length; m++) {362 if (parsedFile.groups[m].instruction.toUpperCase() === 'RUN' && !isIgnored('ER0004', parsedFile.groups[m].linesNumbers[0], parsedFile.inlineIgnores)) {363 let line = getArgumentsLine(parsedFile.groups[m], parsedFile.escape);364 let regex = new RegExp(`(^|[;|&])\\s*sudo`, 'g');365 let usedSudo = [];366 let find;367 while ((find = regex.exec(line)) !== null) {368 usedSudo.push(find.index)369 }370 for (let i = 0; i < usedSudo.length; i++) {371 addError(findLineNumber(parsedFile.groups[m], parsedFile.escape, usedSudo[i]), 'ER0004')372 }373 }374 }375}376function useWorkdir(parsedFile) {377 for (let m = 0; m < parsedFile.groups.length; m++) {378 if (parsedFile.groups[m].instruction.toUpperCase() === 'RUN' && !isIgnored('ER0003', parsedFile.groups[m].linesNumbers[0], parsedFile.inlineIgnores)) {379 for (let i = 0; i < parsedFile.groups[m].arguments.length; i++) {380 if (parsedFile.groups[m].arguments[i].match(regexCommand('cd'))) {381 addError(parsedFile.groups[m].linesNumbers[i], 'ER0003')382 }383 }384 }385 }386}387function lookForPointlessCommands(parsedFile) {388 const pointlessCommands = ['ssh', 'vim', 'shutdown', 'service', 'ps', 'free', 'top', 'kill', 'mount', 'ifconfig'];389 for (let m = 0; m < parsedFile.groups.length; m++) {390 if (parsedFile.groups[m].instruction.toUpperCase() === 'RUN' && !isIgnored('ER0005', parsedFile.groups[m].linesNumbers[0], parsedFile.inlineIgnores)) {391 let line = getArgumentsLine(parsedFile.groups[m], parsedFile.escape);392 for (let i = 0; i < pointlessCommands.length; i++) {393 if (line.match(regexCommand(pointlessCommands[i]))) {394 addError(parsedFile.groups[m].linesNumbers[0], 'ER0005')395 }396 }397 }398 }399}400function lookForNotRecommendedCommands(parsedFile) {401 const commandsWithArg = [402 {command: 'apt-get', contain: 'upgrade'},403 {command: 'apk', contain: 'upgrade'}];404 const commands = ['dist-upgrade', 'apt'];405 for (let m = 0; m < parsedFile.groups.length; m++) {406 if (parsedFile.groups[m].instruction.toUpperCase() === 'RUN' && !isIgnored('ER0006', parsedFile.groups[m].linesNumbers[0], parsedFile.inlineIgnores)) {407 let line = getArgumentsLine(parsedFile.groups[m], parsedFile.escape);408 for (let i = 0; i < commandsWithArg.length; i++) {409 let argumentsArrays = getArgumentsArrayForCommand(line, commandsWithArg[i].command);410 for (let j = 0; j < argumentsArrays.length; j++) {411 for (let k = 0; k < argumentsArrays[j].array.length; k++) {412 if (argumentsArrays[j].array[k] === commandsWithArg[i].contain) {413 addError(findLineNumber(parsedFile.groups[m], parsedFile.escape, argumentsArrays[j].startIndex), 'ER0006')414 }415 }416 }417 }418 for (let i = 0; i < commands.length; i++) {419 let regex = regexInstruction(commands[i]);420 for (let j = 0; j < parsedFile.groups[m].arguments.length; j++) {421 if (parsedFile.groups[m].arguments[j].match(regex) && !isIgnored('ER0006', parsedFile.groups[m].linesNumbers[0], parsedFile.inlineIgnores)) {422 addError(parsedFile.groups[m].linesNumbers[j], 'ER0006')423 }424 }425 }426 }427 }428}429function usedAddForFetchPackages(parsedFile) {430 for (let i = 0; i < parsedFile.groups.length; i++) {431 if (parsedFile.groups[i].instruction.toUpperCase() === 'ADD' && !isIgnored('EA0001', parsedFile.groups[i].linesNumbers[0], parsedFile.inlineIgnores)) {432 if (parsedFile.groups[i].arguments[0].match(/^(http|https).+\.tar(\.xz|\.gz|\.bz2)\s/)) {433 addError(parsedFile.groups[i].linesNumbers[0], 'EA0001')434 }435 }436 }437}438function copyUsedForArchives(parsedFile) {439 for (let i = 0; i < parsedFile.groups.length; i++) {440 if (parsedFile.groups[i].instruction.toUpperCase() === 'COPY' && !isIgnored('EC0003', parsedFile.groups[i].linesNumbers[0], parsedFile.inlineIgnores)) {441 if (parsedFile.groups[i].arguments[0].match(/^.+\.tar(\.xz|\.gz|\.bz2)\s/)) {442 addError(parsedFile.groups[i].linesNumbers[0], 'EC0003')443 }444 }445 }446}447function eitherUseWgetOrCurl(parsedFile) {448 let tool = '';449 for (let m = 0; m < parsedFile.groups.length; m++) {450 if (parsedFile.groups[m].instruction.toUpperCase() === 'RUN' && !isIgnored('ER0007', parsedFile.groups[m].linesNumbers[0], parsedFile.inlineIgnores)) {451 //pierwsze wystapienie wget albo curl jest zapisywane,452 //przy kolejnch sprawdzane czy to samo narzedzie zostalo uzyte453 if (tool === 'wget') {454 for (let i = 0; i < parsedFile.groups[m].arguments.length; i++) {455 let toolTemp = parsedFile.groups[m].arguments[i].match(regexInstruction('curl'));456 if (toolTemp) {457 addError(parsedFile.groups[m].linesNumbers[i], 'ER0007')458 }459 }460 } else if (tool === 'curl') {461 for (let i = 0; i < parsedFile.groups[m].arguments.length; i++) {462 let toolTemp = parsedFile.groups[m].arguments[i].match(regexInstruction('wget'));463 if (toolTemp) {464 addError(parsedFile.groups[m].linesNumbers[i], 'ER0007')465 }466 }467 } else {468 for (let i = 0; i < parsedFile.groups[m].arguments.length; i++) {469 let toolTemp = parsedFile.groups[m].arguments[i].match(/\bwget\b|\bcurl\b/);470 if (toolTemp) {471 tool = toolTemp[0].toLowerCase();472 break;473 }474 }475 }476 }477 }478}479function useShell(parsedFile) {480 for (let m = 0; m < parsedFile.groups.length; m++) {481 if (parsedFile.groups[m].instruction.toUpperCase() === 'RUN' && !isIgnored('ER0008', parsedFile.groups[m].linesNumbers[0], parsedFile.inlineIgnores)) {482 let argumentsArrays = getArgumentsArrayForCommand(getArgumentsLine(parsedFile.groups[m], parsedFile.escape), 'ln');483 if (argumentsArrays) {484 for (let i = 0; i < argumentsArrays.length; i++) {485 for (let j = 0; j < argumentsArrays[i].array.length; j++) {486 if (argumentsArrays[i].array[j] === '/bin/sh') {487 addError(findLineNumber(parsedFile.groups[m], parsedFile.escape, argumentsArrays[i].startIndex), 'ER0008')488 }489 }490 }491 }492 }493 }494}495function useFlagY(parsedFile) {496 const optionsArray = ['-y', '--yes', '-qq', '--assume-yes'];497 const shortOptionsArray = ['y', 'qq'];498 for (let m = 0; m < parsedFile.groups.length; m++) {499 if (parsedFile.groups[m].instruction.toUpperCase() === 'RUN' && !isIgnored('ER0009', parsedFile.groups[m].linesNumbers[0], parsedFile.inlineIgnores)) {500 let argumentsArrays = getArgumentsArrayForCommand(getArgumentsLine(parsedFile.groups[m], parsedFile.escape), 'apt-get', true);501 if (argumentsArrays) {502 for (let i = 0; i < argumentsArrays.length; i++) {503 if (argumentsArrays[i].array[0] === 'install') {504 for (let j = 0; j < argumentsArrays[i].array.length; j++) {505 //sprawdzamy czy wystepuje flaga z optionsArray506 for (let k = 0; k < optionsArray.length; k++) {507 if (argumentsArrays[i].array[j] === optionsArray[k]) {508 return;509 } else if (argumentsArrays[i].array[j].match(/^-\w+/)) {510 //sprawdzamy czy wystepuje flaga z shortOptionsArray511 for (let l = 0; l < shortOptionsArray.length; l++) {512 if (argumentsArrays[i].array[j].match(new RegExp(shortOptionsArray[l]))) {513 return;514 }515 }516 }517 }518 }519 addError(findLineNumber(parsedFile.groups[m], parsedFile.escape, argumentsArrays[i].startIndex), 'ER0009')520 }521 }522 }523 }524 }525}526function useNoInstallRecommends(parsedFile) {527 for (let m = 0; m < parsedFile.groups.length; m++) {528 if (parsedFile.groups[m].instruction.toUpperCase() === 'RUN' && !isIgnored('ER0010', parsedFile.groups[m].linesNumbers[0], parsedFile.inlineIgnores)) {529 let argumentsArrays = getArgumentsArrayForCommand(getArgumentsLine(parsedFile.groups[m], parsedFile.escape), 'apt-get', true);530 if (argumentsArrays) {531 argLoop:532 for (let i = 0; i < argumentsArrays.length; i++) {533 let installExists = argumentsArrays[i].array.find((ele) => {534 return ele === 'install'535 });536 if (installExists) {537 for (let j = 0; j < argumentsArrays[i].array.length; j++) {538 if (argumentsArrays[i].array[j] === '--no-install-recommends') {539 continue argLoop540 }541 }542 addError(findLineNumber(parsedFile.groups[m], parsedFile.escape, argumentsArrays[i].startIndex), 'ER0010')543 }544 }545 }546 }547 }548}549function usedAddInsteadOfCopy(parsedFile) {550 for (let m = 0; m < parsedFile.groups.length; m++) {551 if (parsedFile.groups[m].instruction.toUpperCase() === 'ADD' && !isIgnored('EA0002', parsedFile.groups[m].linesNumbers[0], parsedFile.inlineIgnores)) {552 let array = getArgumentsArrayForInstruction(getArgumentsLine(parsedFile.groups[m], parsedFile.escape));553 for (let i = 0; i < array.length - 1; i++) {554 if (!array[i].match(/(^.+\.tar(\.xz|\.gz|\.bz2))|^(http|https).+/)) {555 addError(parsedFile.groups[m].linesNumbers[0], 'EA0002');556 break;557 }558 }559 }560 }561}562function checkNumberOfArguments(parsedFile) {563 for (let m = 0; m < parsedFile.groups.length; m++) {564 if (parsedFile.groups[m].instruction.toUpperCase() === 'COPY' && !isIgnored('EC0004', parsedFile.groups[m].linesNumbers[0], parsedFile.inlineIgnores)) {565 let array = getArgumentsArrayForInstruction(getArgumentsLine(parsedFile.groups[m], parsedFile.escape));566 if (array.length > 2) {567 if (!array[array.length - 1].endsWith('/')) {568 addError(parsedFile.groups[m].linesNumbers[0], 'EC0004')569 }570 }571 }572 }573}574function useNoCache(parsedFile) {575 for (let m = 0; m < parsedFile.groups.length; m++) {576 if (parsedFile.groups[m].instruction.toUpperCase() === 'RUN' && !isIgnored('ER0011', parsedFile.groups[m].linesNumbers[0], parsedFile.inlineIgnores)) {577 let argumentsArrays = getArgumentsArrayForCommand(getArgumentsLine(parsedFile.groups[m], parsedFile.escape), 'apk', true);578 if (argumentsArrays) {579 for (let i = 0; i < argumentsArrays.length; i++) {580 if (argumentsArrays[i].array.find((e) => {581 return e === 'add'582 })) {583 for (let j = 0; j < argumentsArrays[i].array.length; j++) {584 if (argumentsArrays[i].array[j] === '--no-cache') {585 return586 }587 }588 addError(findLineNumber(parsedFile.groups[m], parsedFile.escape, argumentsArrays[i].startIndex), 'ER0011')589 }590 }591 }592 }593 }594}595function pinVersionInAptGetInstall(parsedFile) {596 for (let m = 0; m < parsedFile.groups.length; m++) {597 if (parsedFile.groups[m].instruction.toUpperCase() === 'RUN' && !isIgnored('ER0012', parsedFile.groups[m].linesNumbers[0], parsedFile.inlineIgnores)) {598 let argumentsArrays = getArgumentsArrayForCommand(getArgumentsLine(parsedFile.groups[m], parsedFile.escape), 'apt-get');599 if (argumentsArrays) {600 for (let i = 0; i < argumentsArrays.length; i++) {601 if (argumentsArrays[i].array[0] === 'install') {602 for (let j = 1; j < argumentsArrays[i].array.length; j++) {603 //nie zawiera znaku do pinowania wersji604 if (!argumentsArrays[i].array[j].match(/=/)) {605 addError(findLineNumber(parsedFile.groups[m], parsedFile.escape, argumentsArrays[i].startIndex), 'ER0012');606 break;607 }608 }609 }610 }611 }612 }613 }614}615function pinVersionInPip(parsedFile) {616 for (let m = 0; m < parsedFile.groups.length; m++) {617 if (parsedFile.groups[m].instruction.toUpperCase() === 'RUN' && !isIgnored('ER0013', parsedFile.groups[m].linesNumbers[0], parsedFile.inlineIgnores)) {618 let argumentsArrays = getArgumentsArrayForCommand(getArgumentsLine(parsedFile.groups[m], parsedFile.escape), 'pip|pip3', true);619 if (argumentsArrays) {620 for (let i = 0; i < argumentsArrays.length; i++) {621 if (argumentsArrays[i].array[0] === 'install') {622 //nie zawiera flagi oznaczajacej ze piny moga byc zdefiniowane w osobnym pliku623 const otherSource = ["-r", "-requirement", "."];624 let req = argumentsArrays[i].array.find((arg) => {625 for (let j = 0; j < otherSource.length; j++) {626 if (arg === otherSource[j]) {627 return true628 }629 }630 });631 if (!req) {632 for (let j = 1; j < argumentsArrays[i].array.length; j++) {633 //nie zawiera znaku do pinowania wersji oraz nie jest flaga634 if (!argumentsArrays[i].array[j].match(/[@=<>!]/) && !argumentsArrays[i].array[j].match(/-/)) {635 addError(findLineNumber(parsedFile.groups[m], parsedFile.escape, argumentsArrays[i].startIndex), 'ER0013');636 break637 }638 }639 }640 }641 }642 }643 }644 }645}646function pinVersionInNpm(parsedFile) {647 const optionsArray = ['install', 'i', 'add'];648 for (let m = 0; m < parsedFile.groups.length; m++) {649 if (parsedFile.groups[m].instruction.toUpperCase() === 'RUN' && !isIgnored('ER0014', parsedFile.groups[m].linesNumbers[0], parsedFile.inlineIgnores)) {650 let argumentsArrays = getArgumentsArrayForCommand(getArgumentsLine(parsedFile.groups[m], parsedFile.escape), 'npm');651 if (argumentsArrays) {652 for (let i = 0; i < argumentsArrays.length; i++) {653 if (argumentsArrays[i].array.length > 1) {654 for (let k = 0; k < optionsArray.length; k++) {655 if (argumentsArrays[i].array[0] === optionsArray[k]) {656 for (let j = 1; j < argumentsArrays[i].array.length; j++) {657 //nie zawiera znakow do pinowania wersji658 if (!argumentsArrays[i].array[j].match(/[@#][^/]+$/)) {659 addError(findLineNumber(parsedFile.groups[m], parsedFile.escape, argumentsArrays[i].startIndex), 'ER0014');660 break661 }662 }663 }664 }665 }666 }667 }668 }669 }670}671function pinVersionInApkAdd(parsedFile) {672 const optionsWithArg = ['-t', '--virtual', '-p', '--root', '-X', '--repository', '--progress-fd', '--wait', '--keys-dir', '--repository-file'];673 for (let m = 0; m < parsedFile.groups.length; m++) {674 if (parsedFile.groups[m].instruction.toUpperCase() === 'RUN' && !isIgnored('ER0015', parsedFile.groups[m].linesNumbers[0], parsedFile.inlineIgnores)) {675 let argumentsArrays = getArgumentsArrayForCommand(getArgumentsLine(parsedFile.groups[m], parsedFile.escape), 'apk', true);676 if (argumentsArrays) {677 for (let i = 0; i < argumentsArrays.length; i++) {678 let apkArray = [];679 argLoop:680 for (let j = 0; j < argumentsArrays[i].array.length; j++) {681 if (argumentsArrays[i].array[j].startsWith('-')) {682 for (let k = 0; k < optionsWithArg.length; k++) {683 if (argumentsArrays[i].array[j] === optionsWithArg[k]) {684 j++;685 continue argLoop686 }687 }688 } else {689 apkArray.push(argumentsArrays[i].array[j])690 }691 }692 if (apkArray[0] === 'add') {693 for (let l = 1; l < apkArray.length; l++) {694 //nie zawiera znakow do pinowania wersji695 if (!apkArray[l].match(/[=<>]/)) {696 addError(findLineNumber(parsedFile.groups[m], parsedFile.escape, argumentsArrays[i].startIndex), 'ER0015');697 break698 }699 }700 }701 }702 }703 }704 }705}706function pinVersionInGemInstall(parsedFile) {707 const optionsWithArg = ['--platform', '-i', '--install-dir', '-n', '--bindir',708 '--documents', '--build-root', '-P', '--trust-policy', '-g', '--file', '--without',709 '-B', '--bulk-threshold', '-s', '--source', '-p', '--no-http-proxy', '--http-proxy', '-config-file'];710 for (let m = 0; m < parsedFile.groups.length; m++) {711 if (parsedFile.groups[m].instruction.toUpperCase() === 'RUN' && !isIgnored('ER0016', parsedFile.groups[m].linesNumbers[0], parsedFile.inlineIgnores)) {712 let argumentsArrays = getArgumentsArrayForCommand(getArgumentsLine(parsedFile.groups[m], parsedFile.escape), 'gem', true);713 if (argumentsArrays) {714 for (let i = 0; i < argumentsArrays.length; i++) {715 let gemsArray = [];716 if (argumentsArrays[i].array[0] === 'install' || argumentsArrays[i].array[0] === 'i') {717 for (let j = 1; j < argumentsArrays[i].array.length; j++) {718 //dodajemy do tablicy gemy i flagi -v/--version719 if (!argumentsArrays[i].array[j].startsWith('-')) {720 gemsArray.push(argumentsArrays[i].array[j])721 } else if (argumentsArrays[i].array[j] === '-v' || argumentsArrays[i].array[j] === '--version') {722 gemsArray.push(argumentsArrays[i].array[j]);723 gemsArray.push(argumentsArrays[i].array[j + 1]);724 j += 1;725 } else if (argumentsArrays[i].array[j] === '--') {726 //koniec gemow727 break;728 } else if (argumentsArrays[i].array[j].startsWith('-')) {729 //przesuwamy sie w tablicy o dwa miejsca jezeli wystepuje flaga z paramterami730 for (let k = 0; k < optionsWithArg.length; k++) {731 if (argumentsArrays[i].array[j] === optionsWithArg[k]) {732 j += 1;733 break734 }735 }736 }737 }738 }739 for (let j = 0; j < gemsArray.length; j++) {740 //jezeli nie zawiera symbolu do pinowania albo flagi -v/--version741 if (!gemsArray[j].match(/:/)) {742 if (gemsArray[j + 1] === '-v' || gemsArray[j + 1] === '--version') {743 j += 2;744 } else {745 addError(findLineNumber(parsedFile.groups[m], parsedFile.escape, argumentsArrays[i].startIndex), 'ER0016');746 break747 }748 }749 }750 }751 }752 }753 }754}755function notAllowedInstructionsInOnbuild(parsedFile) {756 const cantContain = ["ONBUILD", "FROM", "MAINTAINER"];757 for (let m = 0; m < parsedFile.groups.length; m++) {758 if (parsedFile.groups[m].onBuild) {759 cantContain.forEach((instruction) => {760 if (parsedFile.groups[m].instruction === instruction && !isIgnored('EI0004', parsedFile.groups[m].linesNumbers[0], parsedFile.inlineIgnores)) {761 addError(parsedFile.groups[m].linesNumbers[0], 'EI0004');762 }763 })764 }765 }766}767function useAbsoluteInWorkdir(parsedFile) {768 for (let m = 0; m < parsedFile.groups.length; m++) {769 if (parsedFile.groups[m].instruction.toUpperCase() === 'WORKDIR' && !isIgnored('EW0001', parsedFile.groups[m].linesNumbers[0], parsedFile.inlineIgnores)) {770 //jezeli nie jest ARG albo ENV771 if (!parsedFile.groups[m].arguments[0].startsWith('/') && !parsedFile.groups[m].arguments[0].startsWith('$')) {772 addError(parsedFile.groups[m].linesNumbers[0], 'EW0001');773 }774 }775 }776}777function validUnixPorts(parsedFile) {778 for (let m = 0; m < parsedFile.groups.length; m++) {779 if (parsedFile.groups[m].instruction.toUpperCase() === 'EXPOSE' && !isIgnored('EE0001', parsedFile.groups[m].linesNumbers[0], parsedFile.inlineIgnores)) {780 let array = getArgumentsArrayForInstruction(getArgumentsLine(parsedFile.groups[m], parsedFile.escape));781 array = array.reduce((array, e) => {782 const port = e.match(/\d+/);783 if (port) {784 array.push(port[0]);785 }786 return array;787 }, [])788 for (let i = 0; i < array.length; i++) {789 if (array[i] < 0 || array[i] > 65535) {790 addError(parsedFile.groups[m].linesNumbers[0], 'EE0001');791 break;792 }793 }794 }795 }796}797module.exports = {798 EL0001: invalidLine,799 ED0001: directivesOnTopOfDockerfile,800 ED0002: checkForRepetitions,801 ED0003: lowercaseConvention,802 ED0004: directiveWillBeIgnored,803 ED0005: missingValueForDirective,804 ER0001: pipefailBeforeRun,805 EU0001: lastUserShouldNotBeRoot,806 EI0001: onlyOnceAllowedInstructions,807 EI0002: onlyArgBeforeFrom,808 EF0001: fromExists,809 EC0001: copyFromOptionReferenceToOwnFromAlias,810 EC0002: copyFromOptionShouldReferenceToDefinedFromAlias,811 EI0003: deprecatedInstruction,812 EJ0001: lintJson,813 EJ0002: shouldUseJson,814 EJ0003: mustUseJson,815 EF0002: fromAliasMustBeUnique,816 EF0003: usedTagLatest,817 EF0004: alwaysTag,818 ER0002: deleteAptGetListsAfterInstall,819 ER0003: useWorkdir,820 ER0004: notUseSudo,821 ER0005: lookForPointlessCommands,822 ER0006: lookForNotRecommendedCommands,823 EA0001: usedAddForFetchPackages,824 EC0003: copyUsedForArchives,825 ER0007: eitherUseWgetOrCurl,826 ER0008: useShell,827 ER0009: useFlagY,828 ER0010: useNoInstallRecommends,829 EA0002: usedAddInsteadOfCopy,830 EC0004: checkNumberOfArguments,831 ER0011: useNoCache,832 ER0012: pinVersionInAptGetInstall,833 ER0013: pinVersionInPip,834 ER0014: pinVersionInNpm,835 ER0015: pinVersionInApkAdd,836 ER0016: pinVersionInGemInstall,837 EI0004: notAllowedInstructionsInOnbuild,838 EW0001: useAbsoluteInWorkdir,839 EE0001: validUnixPorts,840 EI0005: uppercaseCheck,...

Full Screen

Full Screen

iso_boxer_spec.js

Source:iso_boxer_spec.js Github

copy

Full Screen

1var ISOBoxer = require('../../dist/iso_boxer.js'),2 fs = require('fs');3function loadParsedFixture(file) {4 var arrayBuffer = new Uint8Array(fs.readFileSync(file)).buffer;5 return ISOBoxer.parseBuffer(arrayBuffer);6}7describe('ISOBoxer', function() {8 it('should parse a buffer', function() {9 // Sample 'ftyp' box (20 bytes)10 var arrayBuffer = new Uint8Array([ 0x00, 0x00, 0x00, 0x14, 0x66, 0x74, 0x79, 0x70, 0x69, 0x73, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x01, 0x69, 0x73, 0x6f, 0x6d ]).buffer;11 var parsedFile = ISOBoxer.parseBuffer(arrayBuffer);12 var box = parsedFile.boxes[0];13 14 expect(parsedFile.boxes.length).toEqual(1);15 expect(box.type).toEqual('ftyp');16 expect(box.size).toEqual(20);17 expect(box.major_brand).toEqual('isom');18 expect(box.minor_version).toEqual(1);19 expect(box.compatible_brands).toEqual(['isom']);20 });21 it('should convert a simple dataView to a string', function() {22 var arrayBuffer = new Uint8Array([0x74, 0x65, 0x73, 0x74, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67]).buffer;23 var dataView = new DataView(arrayBuffer);24 expect(ISOBoxer.Utils.dataViewToString(dataView)).toEqual('test string');25 });26 it('should allow adding additional box processors', function() {27 var emptyFunction = function() { };28 var parsedFile = loadParsedFixture('./test/fixtures/captions.mp4');29 var box = parsedFile.boxes[0];30 ISOBoxer.addBoxProcessor('xxxx', emptyFunction);31 expect(box._boxProcessors['xxxx']).toEqual(emptyFunction);32 });33 describe('when parsing an incomplete buffer', function() {34 it('should mark the incomplete box and root object as incomplete', function() {35 var parsedFile = loadParsedFixture('./test/fixtures/spliced_1500.m4v');36 expect(parsedFile._incomplete).toEqual(true);37 expect(parsedFile.boxes.length).toEqual(5);38 expect(parsedFile.boxes[parsedFile.boxes.length - 1]._incomplete).toEqual(true);39 });40 it('should not mark complete boxes as incomplete', function() {41 var parsedFile = loadParsedFixture('./test/fixtures/spliced_1500.m4v');42 for (var i = 0; i < parsedFile.boxes.length - 1; i++) {43 expect(parsedFile.boxes[i]._incomplete).toEqual(undefined);44 }45 });46 it('should reject boxes that are cut in the header and set incomplete on the root', function() {47 var parsedFile = loadParsedFixture('./test/fixtures/spliced_34.m4v');48 expect(parsedFile._incomplete).toEqual(true);49 expect(parsedFile.boxes.length).toEqual(1);50 });51 it('should not parse boxes nested inside incomplete boxes', function() {52 var parsedFile = loadParsedFixture('./test/fixtures/spliced_251.m4v');53 expect(parsedFile._incomplete).toEqual(true);54 expect(parsedFile.boxes.length).toEqual(2);55 expect(parsedFile.boxes[1].boxes).toEqual(undefined);56 expect(parsedFile.fetch('trak')).toEqual(undefined);57 });58 });59 describe('when parsing garbage buffer', function() {60 it('should exit the parser if garbage is zero', function() {61 var zero = new Uint8Array(1500);62 var parsedFile = ISOBoxer.parseBuffer(zero.buffer);63 expect(parsedFile.boxes.length).toEqual(1);64 expect(parsedFile.boxes[0].size).toEqual(0);65 })66 });...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1var parsedFile = require('stryker-parent').parsedFile;2console.log(parsedFile('test.js'));3var parsedFile = require('stryker-child').parsedFile;4console.log(parsedFile('test.js'));5var parsedFile = require(require.resolve('stryker-parent')).parsedFile;6console.log(parsedFile('test.js'));7var parsedFile = require('stryker-child').parsedFile;8console.log(parsedFile('test.js'));

Full Screen

Using AI Code Generation

copy

Full Screen

1const strykerParent = require('stryker-parent');2const file = strykerParent.parsedFile('test.js');3console.log(file);4const strykerParent = require('stryker-parent');5const file = strykerParent.parsedFile('test.js');6console.log(file);7const strykerParent = require('stryker-parent');8const file = strykerParent.parsedFile('test.js');9console.log(file);10const strykerParent = require('stryker-parent');11const file = strykerParent.parsedFile('test.js');12console.log(file);13const strykerParent = require('stryker-parent');14const file = strykerParent.parsedFile('test.js');15console.log(file);16const strykerParent = require('stryker-parent');17const file = strykerParent.parsedFile('test.js');18console.log(file);19const strykerParent = require('stryker-parent');20const file = strykerParent.parsedFile('test.js');21console.log(file);22const strykerParent = require('stryker-parent');23const file = strykerParent.parsedFile('test.js');24console.log(file);25const strykerParent = require('stryker-parent');26const file = strykerParent.parsedFile('test.js');27console.log(file);28const strykerParent = require('stryker-parent');29const file = strykerParent.parsedFile('test.js');30console.log(file);31const strykerParent = require('stryker-parent');

Full Screen

Using AI Code Generation

copy

Full Screen

1const strykerParent = require('stryker-parent');2const parsedFile = strykerParent.parsedFile;3const path = require('path');4const file = parsedFile(path.resolve(__dirname, 'test.js'));5console.log(file);6const strykerParent = require('stryker-parent');7const parsedFile = strykerParent.parsedFile;8const path = require('path');9const file = parsedFile(path.resolve(__dirname, 'test.js'));10console.log(file);11const strykerParent = require('stryker-parent');12const parsedFile = strykerParent.parsedFile;13const path = require('path');14const file = parsedFile(path.resolve(__dirname, 'test.js'));15console.log(file);16const strykerParent = require('stryker-parent');17const parsedFile = strykerParent.parsedFile;18const path = require('path');19const file = parsedFile(path.resolve(__dirname, 'test.js'));20console.log(file);21const strykerParent = require('stryker-parent');22const parsedFile = strykerParent.parsedFile;23const path = require('path');24const file = parsedFile(path.resolve(__dirname, 'test.js'));25console.log(file);26const strykerParent = require('stryker-parent');27const parsedFile = strykerParent.parsedFile;28const path = require('path');29const file = parsedFile(path.resolve(__dirname, 'test.js'));30console.log(file);31const strykerParent = require('stryker-parent');32const parsedFile = strykerParent.parsedFile;33const path = require('path');34const file = parsedFile(path.resolve(__dirname, 'test.js'));35console.log(file);36const strykerParent = require('stryker-parent');

Full Screen

Using AI Code Generation

copy

Full Screen

1var strykerParent = require('stryker-parent');2strykerParent.parsedFile('test.js', function (err, parsedFile) {3 console.log(parsedFile);4});5var strykerParent = require('stryker-parent');6strykerParent.parsedFile('test.js', function (err, parsedFile) {7 console.log(parsedFile);8});9var strykerParent = require('stryker-parent');10strykerParent.parsedFile('test.js', function (err, parsedFile) {11 console.log(parsedFile);12});13var strykerParent = require('stryker-parent');14strykerParent.parsedFile('test.js', function (err, parsedFile) {15 console.log(parsedFile);16});17var strykerParent = require('stryker-parent');18strykerParent.parsedFile('test.js', function (err, parsedFile) {19 console.log(parsedFile);20});21var strykerParent = require('stryker-parent');22strykerParent.parsedFile('test.js', function (err, parsedFile) {23 console.log(parsedFile);24});25var strykerParent = require('stryker-parent');26strykerParent.parsedFile('test.js', function (err, parsedFile) {27 console.log(parsedFile);28});29var strykerParent = require('stryker-parent');30strykerParent.parsedFile('test.js', function (err, parsedFile) {31 console.log(parsedFile);32});33var strykerParent = require('stryker-parent');34strykerParent.parsedFile('test.js', function (err, parsedFile) {35 console.log(parsedFile);36});

Full Screen

Using AI Code Generation

copy

Full Screen

1const strykerParent = require('stryker-parent');2const strykerParent = require('stryker-parent');3strykerParent.parsedFile('test.js');4const strykerParent = require('stryker-parent');5strykerParent.parsedFile('test.js');6const strykerParent = require('stryker-parent');7strykerParent.parsedFile('test.js');8const strykerParent = require('stryker-parent');9strykerParent.parsedFile('test.js');10const strykerParent = require('stryker-parent');11strykerParent.parsedFile('test.js');12const strykerParent = require('stryker-parent');13strykerParent.parsedFile('test.js');14const strykerParent = require('stryker-parent');15strykerParent.parsedFile('test.js');16const strykerParent = require('stryker-parent');17strykerParent.parsedFile('test.js');18const strykerParent = require('stryker-parent');19strykerParent.parsedFile('test.js');20const strykerParent = require('stryker-parent');21strykerParent.parsedFile('test.js');22const strykerParent = require('stryker-parent');23strykerParent.parsedFile('test.js');24const strykerParent = require('stryker-parent');25strykerParent.parsedFile('test.js');

Full Screen

Using AI Code Generation

copy

Full Screen

1var strykerParent = require('stryker-parent');2var parsedFile = strykerParent.parsedFile('test.js');3var strykerParent = require('stryker-parent');4var parsedFile = strykerParent.parsedFile('test.js');5var strykerParent = require('stryker-parent');6var parsedFile = strykerParent.parsedFile('test.js');7var strykerParent = require('stryker-parent');8var parsedFile = strykerParent.parsedFile('test.js');9var strykerParent = require('stryker-parent');10var parsedFile = strykerParent.parsedFile('test.js');11var strykerParent = require('stryker-parent');12var parsedFile = strykerParent.parsedFile('test.js');13var strykerParent = require('stryker-parent');14var parsedFile = strykerParent.parsedFile('test.js');15var strykerParent = require('stryker-parent');

Full Screen

Using AI Code Generation

copy

Full Screen

1const strykerParent = require('stryker-parent');2const parsedFile = strykerParent.parsedFile;3const file = parsedFile('test.js');4console.log(file.isTypeScript());5const strykerParent = require('stryker-parent');6const parsedFile = strykerParent.parsedFile;7const file = parsedFile('test.ts');8console.log(file.isTypeScript());9stryker-parent is licensed under [MIT](

Full Screen

Using AI Code Generation

copy

Full Screen

1var stryker = require('stryker-parent');2var file = stryker.parsedFile('example.js');3console.log(file);4function add(a, b) {5 return a + b;6}7module.exports = function(config) {8 config.set({9 });10};11var stryker = require('stryker-parent');12var file = stryker.originalFile('example.js');13describe('add', function() {14 it('should add two numbers', function() {15 var result = add(2, 3);16 expect(result).to.be.equal(5);17 });18});19function add(a, b) {20 return a + b;21}22module.exports = function(config) {23 config.set({24 });25};26var stryker = require('stryker-parent');

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run stryker-parent automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful