chai = require 'chai' should = chai.should() describe 'RuleList', -> RuleList = require '../src/rule_list' describe 'AutoProxy', -> parse = RuleList['AutoProxy'].parse it 'should parse keyword conditions', -> line = 'example.com' result = parse(line, 'match', 'notmatch') result.should.have.length(1) result[0].should.eql( source: line profileName: 'match' condition: conditionType: 'KeywordCondition' pattern: 'example.com' ) it 'should parse keyword conditions with asterisks', -> line = 'example*.com' result = parse(line, 'match', 'notmatch') result.should.have.length(1) result[0].should.eql( source: line profileName: 'match' condition: conditionType: 'UrlWildcardCondition' pattern: 'http://*example*.com*' ) it 'should parse host conditions', -> line = '||example.com' result = parse(line, 'match', 'notmatch') result.should.have.length(1) result[0].should.eql( source: line profileName: 'match' condition: conditionType: 'HostWildcardCondition' pattern: '*.example.com' ) it 'should parse "starts-with" conditions', -> line = '|https://ssl.example.com' result = parse(line, 'match', 'notmatch') result.should.have.length(1) result[0].should.eql( source: line profileName: 'match' condition: conditionType: 'UrlWildcardCondition' pattern: 'https://ssl.example.com*' ) it 'should parse "starts-with" conditions for the HTTP scheme', -> line = '|http://example.com' result = parse(line, 'match', 'notmatch') result.should.have.length(1) result[0].should.eql( source: line profileName: 'match' condition: conditionType: 'UrlWildcardCondition' pattern: 'http://example.com*' ) it 'should parse url regex conditions', -> line = '/^https?:\\/\\/[^\\/]+example\.com/' result = parse(line, 'match', 'notmatch') result.should.have.length(1) result[0].should.eql( source: line profileName: 'match' condition: conditionType: 'UrlRegexCondition' pattern: '^https?:\\/\\/[^\\/]+example\.com' ) it 'should ignore comment lines', -> result = parse('!example.com', 'match', 'notmatch') result.should.have.length(0) it 'should parse multiple lines', -> result = parse 'example.com\n!comment\n||example.com', 'match', 'notmatch' result.should.have.length(2) result[0].should.eql( source: 'example.com' profileName: 'match' condition: conditionType: 'KeywordCondition' pattern: 'example.com' ) result[1].should.eql( source: '||example.com' profileName: 'match' condition: conditionType: 'HostWildcardCondition' pattern: '*.example.com' ) it 'should put exclusive rules first', -> result = parse 'example.com\n@@||example.com', 'match', 'notmatch' result.should.have.length(2) result[0].should.eql( source: '@@||example.com' profileName: 'notmatch' condition: conditionType: 'HostWildcardCondition' pattern: '*.example.com' ) result[1].should.eql( source: 'example.com' profileName: 'match' condition: conditionType: 'KeywordCondition' pattern: 'example.com' ) describe 'Switchy', -> parse = RuleList['Switchy'].parse compose = (sections) -> list = '#BEGIN\r\n\r\n' for sec, rules of sections list += "[#{sec}]\r\n" for rule in rules list += rule list += '\r\n' list += '\r\n\r\n#END\r\n' it 'should parse empty rule lists', -> list = compose {} result = parse(list, 'match', 'notmatch') result.should.have.length(0) it 'should ignore stuff before #BEGIN or after #END.', -> list = compose {} list += '[RegExp]\r\ntest\r\n' list = '[Wildcard]\r\ntest\r\n' + list result = parse(list, 'match', 'notmatch') result.should.have.length(0) it 'should parse wildcard rules', -> list = compose 'Wildcard': [ '*://example.com/abc/*' ] result = parse(list, 'match', 'notmatch') result.should.have.length(1) result[0].should.eql( source: '*://example.com/abc/*' profileName: 'match' condition: conditionType: 'UrlWildcardCondition' pattern: '*://example.com/abc/*' ) it 'should parse RegExp rules', -> list = compose 'RegExp': [ '^http://www\.example\.com/.*' ] result = parse(list, 'match', 'notmatch') result.should.have.length(1) result[0].should.eql( source: '^http://www\.example\.com/.*' profileName: 'match' condition: conditionType: 'UrlRegexCondition' pattern: '^http://www\.example\.com/.*' ) it 'should parse exclusive rules', -> list = compose 'RegExp': [ '!^http://www\.example\.com/.*' ] result = parse(list, 'match', 'notmatch') result.should.have.length(1) result[0].should.eql( source: '!^http://www\.example\.com/.*' profileName: 'notmatch' condition: conditionType: 'UrlRegexCondition' pattern: '^http://www\.example\.com/.*' ) it 'should parse multiple rules in multiple sections', -> list = compose { 'Wildcard': [ 'http://www.example.com/*' 'http://example.com/*' ] 'RegExp': [ '^http://www\.example\.com/.*' '^http://example\.com/.*' ] } result = parse(list, 'match', 'notmatch') result.should.have.length(4) result[0].should.eql( source: 'http://www.example.com/*' profileName: 'match' condition: conditionType: 'UrlWildcardCondition' pattern: 'http://www.example.com/*' ) result[1].should.eql( source: 'http://example.com/*' profileName: 'match' condition: conditionType: 'UrlWildcardCondition' pattern: 'http://example.com/*' ) result[2].should.eql( source: '^http://www\.example\.com/.*' profileName: 'match' condition: conditionType: 'UrlRegexCondition' pattern: '^http://www\.example\.com/.*' ) result[3].should.eql( source: '^http://example\.com/.*' profileName: 'match' condition: conditionType: 'UrlRegexCondition' pattern: '^http://example\.com/.*' ) it 'should put exclusive rules first', -> list = compose { 'Wildcard': [ 'http://www\.example\.com/*' ] 'RegExp': [ '!^http://www\.example\.com/.*' ] } result = parse(list, 'match', 'notmatch') result.should.have.length(2) result[0].should.eql( source: '!^http://www\.example\.com/.*' profileName: 'notmatch' condition: conditionType: 'UrlRegexCondition' pattern: '^http://www.example\.com/.*' ) result[1].should.eql( source: 'http://www\.example\.com/*' profileName: 'match' condition: conditionType: 'UrlWildcardCondition' pattern: 'http://www.example.com/*' ) describe 'Switchy (omega format)', -> parse = RuleList['Switchy'].parse compose = RuleList['Switchy'].compose it 'should parse empty rule lists', -> list = compose {rules: []} result = parse(list, 'match', 'notmatch') result.should.have.length(0) it 'should ignore comment lines.', -> list = compose {rules: []} list += ';*.example.com \r\n' result = parse(list, 'match', 'notmatch') result.should.have.length(0) it 'should compose and parse HostWildcardCondition', -> rule = source: '*.example.com' condition: conditionType: 'HostWildcardCondition', pattern: '*.example.com' profileName: 'match' list = compose({rules: [rule], defaultProfileName: 'notmatch'}) result = parse(list, 'match', 'notmatch') result.should.have.length(1) result[0].should.eql(rule) it 'should compose and parse HostRegexCondition', -> rule = source: 'HostRegex: ^http://www\.example\.com/.*' condition: conditionType: 'HostRegexCondition', pattern: '^http://www\.example\.com/.*' profileName: 'match' list = compose({rules: [rule], defaultProfileName: 'notmatch'}) result = parse(list, 'match', 'notmatch') result.should.have.length(1) result[0].should.eql(rule) it 'should compose and parse disabled rules', -> rule = source: 'Disabled: *.example.com' condition: conditionType: 'FalseCondition', pattern: '*.example.com' profileName: 'match' list = compose({rules: [rule], defaultProfileName: 'notmatch'}) result = parse(list, 'match', 'notmatch') result.should.have.length(1) result[0].should.eql(rule) it 'should compose and parse exclusive rules', -> rule = source: '!*.example.com' condition: conditionType: 'HostWildcardCondition', pattern: '*.example.com' profileName: 'notmatch' list = compose({rules: [rule], defaultProfileName: 'notmatch'}) result = parse(list, 'match', 'notmatch') result.should.have.length(1) result[0].should.eql(rule) it 'should compose and parse conditions starting with special chars', -> rule = source: ': ;abc' condition: conditionType: 'HostWildcardCondition', pattern: ';abc' profileName: 'match' list = compose({rules: [rule], defaultProfileName: 'notmatch'}) result = parse(list, 'match', 'notmatch') result.should.have.length(1) result[0].should.eql(rule) it 'should parse multiple conditions', -> rules = [{ source: '*.example.com' condition: conditionType: 'HostWildcardCondition', pattern: '*.example.com' profileName: 'match' }, { source: '*.example.org' condition: conditionType: 'HostWildcardCondition', pattern: '*.example.org' profileName: 'match' }] list = compose({rules: rules, defaultProfileName: 'notmatch'}) result = parse(list, 'match', 'notmatch') result.should.eql(rules) it 'should respect the top-down order of conditions', -> rules = [{ source: 'b.example.com' condition: conditionType: 'HostWildcardCondition', pattern: 'b.example.com' profileName: 'match' }, { source: '!a.example.org' condition: conditionType: 'HostWildcardCondition', pattern: 'a.example.org' profileName: 'notmatch' }] list = compose({rules: rules, defaultProfileName: 'notmatch'}) result = parse(list, 'match', 'notmatch') result.should.eql(rules) it 'should add a default rule when results are enabled', -> list = compose( {rules: [], defaultProfileName: 'notmatch'} {withResult: true} ) list.split(/\r|\n/).should.contain('@with result') result = parse(list, 'ignored', 'alsoIgnored') result.should.have.length(1) result[0].should.eql({ source: '*' condition: conditionType: 'HostWildcardCondition', pattern: '*' profileName: 'notmatch', }) it 'should compose and parse conditions with results', -> rules = [{ source: 'b.example.com' condition: conditionType: 'HostWildcardCondition', pattern: 'b.example.com' profileName: 'abc' }, { source: 'a.example.org' condition: conditionType: 'HostWildcardCondition', pattern: 'a.example.org' profileName: 'def' }] list = compose( {rules: rules, defaultProfileName: 'ghi'} {withResult: true} ) result = parse(list, 'ignored', 'alsoIgnored') rules.push({ source: '*' condition: conditionType: 'HostWildcardCondition', pattern: '*' profileName: 'ghi', }) result.should.eql(rules) it 'should compose and parse exclusive conditions with results', -> rules = [{ source: '!b.example.com' condition: conditionType: 'HostWildcardCondition', pattern: 'b.example.com' profileName: 'default profile' }, { source: 'a.example.org' condition: conditionType: 'HostWildcardCondition', pattern: 'a.example.org' profileName: 'some profile' }] list = compose( {rules: rules, defaultProfileName: 'default profile'} {withResult: true, useExclusive: true} ) result = parse(list, 'ignored', 'alsoIgnored') rules.push({ source: '*' condition: conditionType: 'HostWildcardCondition', pattern: '*' profileName: 'default profile', }) result.should.eql(rules)