Merge branch 'feature/use-proper-dirstructure' of manuel/converter into develop

This commit is contained in:
Manuel Friedli 2018-09-01 01:34:35 +02:00 committed by Gitea
commit 0558f35d29
49 changed files with 694 additions and 78 deletions

View file

@ -1,36 +1,27 @@
import {AppComponent} from './app.component'; import {AppComponent} from './app.component';
import {async, ComponentFixture, TestBed} from '@angular/core/testing'; import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {FormsModule} from '@angular/forms'; import {FormsModule} from '@angular/forms';
import {InputComponentManagerService} from './inputcomponentmanager.service'; import {InputComponentManagerService} from './input-component-manager.service';
import {Step} from './step'; import {Step} from './step';
import {ConverterRegistryService} from './converterregistry.service'; import {ConverterRegistryService} from './converter-registry.service';
import {Converter} from './converter/converter'; import {VersionComponent} from './version/version.component';
import createSpyObj = jasmine.createSpyObj;
describe('AppComponent', () => { describe('AppComponent', () => {
let sut: AppComponent; let sut: AppComponent;
let fixture: ComponentFixture<AppComponent>; let fixture: ComponentFixture<AppComponent>;
const firstStep: Step = new Step(0); const firstStep: Step = new Step(0);
const inputComponentManagerServiceStub = { const inputComponentManagerServiceStub = createSpyObj(['getFirst']);
getFirst: () => { inputComponentManagerServiceStub.getFirst.and.returnValue(firstStep);
return firstStep;
}
};
const converterRegistryServiceStub = { const converterRegistryServiceStub = createSpyObj(['getAllConverters', 'getConverter']);
getAllConverters: (): Converter[] => { converterRegistryServiceStub.getAllConverters.and.returnValue([]);
return []; converterRegistryServiceStub.getConverter.and.returnValue(undefined);
},
getConverter: (id: string): Converter => {
return undefined;
}
};
beforeEach(async(() => { beforeEach(async(() => {
/*return */
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [AppComponent], declarations: [AppComponent, VersionComponent],
imports: [FormsModule], imports: [FormsModule],
providers: [ providers: [
{provide: InputComponentManagerService, useValue: inputComponentManagerServiceStub}, {provide: InputComponentManagerService, useValue: inputComponentManagerServiceStub},

View file

@ -1,6 +1,6 @@
import {Component, OnInit} from '@angular/core'; import {Component, OnInit} from '@angular/core';
import {ConverterRegistryService} from './converterregistry.service'; import {ConverterRegistryService} from './converter-registry.service';
import {InputComponentManagerService} from './inputcomponentmanager.service'; import {InputComponentManagerService} from './input-component-manager.service';
import {Step} from './step'; import {Step} from './step';
import {Converter} from './converter/converter'; import {Converter} from './converter/converter';

View file

@ -1,9 +1,9 @@
import {BrowserModule} from '@angular/platform-browser'; import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core'; import {NgModule} from '@angular/core';
import {AppComponent} from './app.component'; import {AppComponent} from './app.component';
import {ConverterRegistryService} from './converterregistry.service'; import {ConverterRegistryService} from './converter-registry.service';
import {InputComponentManagerService} from './inputcomponentmanager.service'; import {InputComponentManagerService} from './input-component-manager.service';
import {NativeLibraryWrapperService} from './nativelibrarywrapper.service'; import {NativeLibraryWrapperService} from './native-library-wrapper.service';
import {FormsModule} from '@angular/forms'; import {FormsModule} from '@angular/forms';
import {VersionComponent} from './version/version.component'; import {VersionComponent} from './version/version.component';

View file

@ -0,0 +1,15 @@
import { TestBed, inject } from '@angular/core/testing';
import { ConverterRegistryService } from './converter-registry.service';
describe('ConverterRegistryService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [ConverterRegistryService]
});
});
it('should be created', inject([ConverterRegistryService], (service: ConverterRegistryService) => {
expect(service).toBeTruthy();
}));
});

View file

@ -1,27 +1,29 @@
import {Injectable} from '@angular/core'; import {Base64Decoder} from './converter/base64-decoder';
import {Base64Encoder} from './converter/base64-encoder';
import {BinToDecConverter} from './converter/bin-to-dec-converter';
import {Converter} from './converter/converter'; import {Converter} from './converter/converter';
import {Base64Encoder} from './converter/base64encoder'; import {DecToBinConverter} from './converter/dec-to-bin-converter';
import {Base64Decoder} from './converter/base64decoder'; import {DecToHexConverter} from './converter/dec-to-hex-converter';
import {URIEncoder} from './converter/uriencoder'; import {HexToDecConverter} from './converter/hex-to-dec-converter';
import {HTMLEntitiesDecoder} from './converter/htmlentities-decoder';
import {HTMLEntitiesEncoder} from './converter/htmlentities-encoder';
import {Injectable} from '@angular/core';
import {NativeLibraryWrapperService} from './native-library-wrapper.service';
import {PunycodeDecoder} from './converter/punycode-decoder';
import {PunycodeEncoder} from './converter/punycode-encoder';
import {QuotedPrintableDecoder} from './converter/quoted-printable-decoder';
import {QuotedPrintableEncoder} from './converter/quoted-printable-encoder';
import {ROT13Converter} from './converter/rot13-converter';
import {URIComponentDecoder} from './converter/uricomponent-decoder';
import {URIComponentEncoder} from './converter/uricomponent-encoder';
import {URIDecoder} from './converter/uridecoder'; import {URIDecoder} from './converter/uridecoder';
import {URIComponentEncoder} from './converter/uricomponentencoder'; import {URIEncoder} from './converter/uriencoder';
import {URIComponentDecoder} from './converter/uricomponentdecoder'; import {UTF8Decoder} from './converter/utf8-decoder';
import {HTMLEntitiesEncoder} from './converter/htmlentitiesencoder'; import {UTF8Encoder} from './converter/utf8-encoder';
import {HTMLEntitiesDecoder} from './converter/htmlentitiesdecoder';
import {DecToHexConverter} from './converter/dectohexconverter';
import {HexToDecConverter} from './converter/hextodecconverter';
import {DecToBinConverter} from './converter/dectobinconverter';
import {BinToDecConverter} from './converter/bintodecconverter';
import {QuotedPrintableDecoder} from './converter/quotedprintabledecoder';
import {QuotedPrintableEncoder} from './converter/quotedprintableencoder';
import {NativeLibraryWrapperService} from './nativelibrarywrapper.service';
import {PunycodeEncoder} from './converter/punycodeencoder';
import {PunycodeDecoder} from './converter/punycodedecoder';
import {UTF8Encoder} from './converter/utf8encoder';
import {UTF8Decoder} from './converter/utf8decoder';
import {ROT13Converter} from './converter/rot13converter';
@Injectable() @Injectable({
providedIn: 'root'
})
export class ConverterRegistryService { export class ConverterRegistryService {
private converters: Converter[] = []; private converters: Converter[] = [];

View file

@ -0,0 +1,27 @@
import {Base64Decoder} from './base64-decoder';
describe('Base64Decoder', () => {
let sut: Base64Decoder;
beforeEach(() => sut = new Base64Decoder());
it('should create an instance', () => {
expect(sut).toBeTruthy();
});
it('should have a display name', () => {
expect(sut.getDisplayname()).toBeTruthy();
});
it('should have the id "base64decode"', () => {
expect(sut.getId()).toEqual('base64decode');
});
it('should decode "SGVsbG8sIFdvcmxkIQ==" to "Hello, World!"', () => {
expect(sut.convert('SGVsbG8sIFdvcmxkIQ==')).toEqual('Hello, World!');
});
it('should raise an exception on invalid input', () => {
expect(() => sut.convert('foo bar.')).toThrowError('Could not decode base64 string. Maybe corrupt input?');
});
});

View file

@ -0,0 +1,27 @@
import {Base64Encoder} from './base64-encoder';
describe('Base64Encoder', () => {
let sut: Base64Encoder;
beforeEach(() => sut = new Base64Encoder());
it('should create an instance', () => {
expect(sut).toBeTruthy();
});
it('should have a display name', () => {
expect(sut.getDisplayname()).toBeTruthy();
});
it('should have the id "base64encode"', () => {
expect(sut.getId()).toEqual('base64encode');
});
it('should encode "Oh, guete Tag!" to "T2gsIGd1ZXRlIFRhZyE="', () => {
expect(sut.convert('Oh, guete Tag!')).toEqual('T2gsIGd1ZXRlIFRhZyE=');
});
it('should raise an exception on invalid input', () => {
expect(() => sut.convert('€')).toThrowError(/Looks like you've got a character outside of the Latin1 range there./);
});
});

View file

@ -14,7 +14,7 @@ export class Base64Encoder implements Converter {
return btoa(input); return btoa(input);
} catch (exception) { } catch (exception) {
console.error(exception); console.error(exception);
throw new Error('Ouch! Looks like you\'ve got a UTF-8 character there. Too bad, this is not supported yet. ' throw new Error('Ouch! Looks like you\'ve got a character outside of the Latin1 range there. Too bad, this is not supported yet. '
+ 'We\'re working on it and hope to be ready soon! Why don\'t you ' + 'We\'re working on it and hope to be ready soon! Why don\'t you '
+ '<a href="https://duckduckgo.com/?q=cute+kitties&iar=images">enjoy some kittens</a> meanwhile?'); + '<a href="https://duckduckgo.com/?q=cute+kitties&iar=images">enjoy some kittens</a> meanwhile?');
} }

View file

@ -0,0 +1,27 @@
import {BinToDecConverter} from './bin-to-dec-converter';
describe('BinToDecConverter', () => {
let sut: BinToDecConverter;
beforeEach(() => sut = new BinToDecConverter());
it('should create an instance', () => {
expect(sut).toBeTruthy();
});
it('should have a display name', () => {
expect(sut.getDisplayname()).toBeTruthy();
});
it('should have the id "bintodec"', () => {
expect(sut.getId()).toEqual('bintodec');
});
it('should convert "11011" to "27"', () => {
expect(sut.convert('11011')).toEqual('27');
});
it('should raise an exception on invalid input', () => {
expect(() => sut.convert('1foo bar')).toThrowError('The input seems not to be a valid binary number.');
});
});

View file

@ -11,7 +11,7 @@ export class BinToDecConverter implements Converter {
convert(input: string): string { convert(input: string): string {
const n: number = parseInt(input, 2); const n: number = parseInt(input, 2);
if (isNaN(n)) { if (isNaN(n) || !input.trim().match(/^([01]+)$/)) {
throw new Error('The input seems not to be a valid binary number.'); throw new Error('The input seems not to be a valid binary number.');
} }
return n.toString(10); return n.toString(10);

View file

@ -0,0 +1,27 @@
import {DecToBinConverter} from './dec-to-bin-converter';
describe('DecToBinConverter', () => {
let sut: DecToBinConverter;
beforeEach(() => sut = new DecToBinConverter());
it('should create an instance', () => {
expect(sut).toBeTruthy();
});
it('should have a display name', () => {
expect(sut.getDisplayname()).toBeTruthy();
});
it('should have the id "dectobin"', () => {
expect(sut.getId()).toEqual('dectobin');
});
it('should convert "22" to "10110"', () => {
expect(sut.convert('22')).toEqual('10110');
});
it('should raise an exception on invalid input', () => {
expect(() => sut.convert('foo bar')).toThrowError('The input seems not to be a valid integer.');
});
});

View file

@ -0,0 +1,27 @@
import {DecToHexConverter} from './dec-to-hex-converter';
describe('DecToHexConverter', () => {
let sut: DecToHexConverter;
beforeEach(() => sut = new DecToHexConverter());
it('should create an instance', () => {
expect(sut).toBeTruthy();
});
it('should have a display name', () => {
expect(sut.getDisplayname()).toBeTruthy();
});
it('should have the id "dectohex"', () => {
expect(sut.getId()).toEqual('dectohex');
});
it('should convert "22" to "16"', () => {
expect(sut.convert('22')).toEqual('16');
});
it('should raise an exception on invalid input', () => {
expect(() => sut.convert('foo bar')).toThrowError('The input seems not to be a valid integer.');
});
});

View file

@ -0,0 +1,27 @@
import {HexToDecConverter} from './hex-to-dec-converter';
describe('HexToDecConverter', () => {
let sut: HexToDecConverter;
beforeEach(() => sut = new HexToDecConverter());
it('should create an instance', () => {
expect(sut).toBeTruthy();
});
it('should have a display name', () => {
expect(sut.getDisplayname()).toBeTruthy();
});
it('should have the id "hextodec"', () => {
expect(sut.getId()).toEqual('hextodec');
});
it('should convert "ab" to "171"', () => {
expect(sut.convert('ab')).toEqual('171');
});
it('should raise an exception on invalid input', () => {
expect(() => sut.convert('foo bar')).toThrowError('The input seems not to be a valid hexadecimal number.');
});
});

View file

@ -11,7 +11,7 @@ export class HexToDecConverter implements Converter {
convert(input: string): string { convert(input: string): string {
const n: number = parseInt(input, 16); const n: number = parseInt(input, 16);
if (isNaN(n)) { if (isNaN(n) || !input.trim().match(/^((0x|0X)?[0-9a-fA-F]+)$/)) {
throw new Error('The input seems not to be a valid hexadecimal number.'); throw new Error('The input seems not to be a valid hexadecimal number.');
} }
return n.toString(10); return n.toString(10);

View file

@ -0,0 +1,24 @@
import {HTMLEntitiesDecoder} from './htmlentities-decoder';
describe('HTMLEntitiesDecoder', () => {
let sut: HTMLEntitiesDecoder;
beforeEach(() => sut = new HTMLEntitiesDecoder());
it('should create an instance', () => {
expect(sut).toBeTruthy();
});
it('should have a display name', () => {
expect(sut.getDisplayname()).toBeTruthy();
});
it('should have the id "decodehtmlentities"', () => {
expect(sut.getId()).toEqual('decodehtmlentities');
});
it('should decode "&lt;span&gt;&quot;Hi&quot; &amp; &quot;Lo&quot;&lt;/span&gt;" to "<span>"Hi" & "Lo"</span>"', () => {
expect(sut.convert('&lt;span&gt;&quot;Hi&quot; &amp; &quot;Lo&quot;&lt;/span&gt;'))
.toEqual('<span>"Hi" & "Lo"</span>');
});
});

View file

@ -0,0 +1,24 @@
import {HTMLEntitiesEncoder} from './htmlentities-encoder';
describe('HTMLEntitiesEncoder', () => {
let sut: HTMLEntitiesEncoder;
beforeEach(() => sut = new HTMLEntitiesEncoder());
it('should create an instance', () => {
expect(sut).toBeTruthy();
});
it('should have a display name', () => {
expect(sut.getDisplayname()).toBeTruthy();
});
it('should have the id "encodehtmlentities"', () => {
expect(sut.getId()).toEqual('encodehtmlentities');
});
it('should encode "<span>"Hi" & "Lo"</span>" to "&lt;span&gt;&quot;Hi&quot; &amp; &quot;Lo&quot;&lt;/span&gt;"', () => {
expect(sut.convert('<span>"Hi" & "Lo"</span>'))
.toEqual('&lt;span&gt;&quot;Hi&quot; &amp; &quot;Lo&quot;&lt;/span&gt;');
});
});

View file

@ -0,0 +1,37 @@
import {PunycodeDecoder} from './punycode-decoder';
import {NativeLibraryWrapperService} from '../native-library-wrapper.service';
import createSpyObj = jasmine.createSpyObj;
import Spy = jasmine.Spy;
describe('PunycodeDecoder', () => {
let sut: PunycodeDecoder;
let nativeWrapperSpy: Partial<NativeLibraryWrapperService>;
let decodeSpy: Spy;
beforeEach(() => {
nativeWrapperSpy = {punycode: createSpyObj(['decode'])};
decodeSpy = nativeWrapperSpy.punycode.decode as Spy;
sut = new PunycodeDecoder((nativeWrapperSpy as NativeLibraryWrapperService));
});
it('should create an instance', () => {
expect(sut).toBeTruthy();
});
it('should have a display name', () => {
expect(sut.getDisplayname()).toBeTruthy();
});
it('should have the id "decodepunycode"', () => {
expect(sut.getId()).toEqual('decodepunycode');
});
it('should call through to the native punycode decoder', () => {
const testInput = 'My input';
const expectedOutput = 'It worked';
decodeSpy.and.returnValue(expectedOutput);
const result: string = sut.convert(testInput);
expect(result).toEqual(expectedOutput);
expect(decodeSpy).toHaveBeenCalledWith(testInput);
});
});

View file

@ -1,5 +1,5 @@
import {Converter} from './converter'; import {Converter} from './converter';
import {NativeLibraryWrapperService} from '../nativelibrarywrapper.service'; import {NativeLibraryWrapperService} from '../native-library-wrapper.service';
export class PunycodeDecoder implements Converter { export class PunycodeDecoder implements Converter {

View file

@ -0,0 +1,37 @@
import {NativeLibraryWrapperService} from '../native-library-wrapper.service';
import {PunycodeEncoder} from './punycode-encoder';
import createSpyObj = jasmine.createSpyObj;
import Spy = jasmine.Spy;
describe('PunycodeEncoder', () => {
let sut: PunycodeEncoder;
let nativeWrapperSpy: Partial<NativeLibraryWrapperService>;
let encodeSpy: Spy;
beforeEach(() => {
nativeWrapperSpy = {punycode: createSpyObj(['encode'])};
encodeSpy = nativeWrapperSpy.punycode.encode as Spy;
sut = new PunycodeEncoder(nativeWrapperSpy as NativeLibraryWrapperService);
});
it('should create an instance', () => {
expect(sut).toBeTruthy();
});
it('should have a display name', () => {
expect(sut.getDisplayname()).toBeTruthy();
});
it('should have the id "encodepunycode"', () => {
expect(sut.getId()).toEqual('encodepunycode');
});
it('should call through to the native punycode encoder', () => {
const testInput = 'My input';
const expectedOutput = 'It worked';
encodeSpy.and.returnValue(expectedOutput);
const result: string = sut.convert(testInput);
expect(result).toEqual(expectedOutput);
expect(encodeSpy).toHaveBeenCalledWith(testInput);
});
});

View file

@ -1,5 +1,5 @@
import {Converter} from './converter'; import {Converter} from './converter';
import {NativeLibraryWrapperService} from '../nativelibrarywrapper.service'; import {NativeLibraryWrapperService} from '../native-library-wrapper.service';
export class PunycodeEncoder implements Converter { export class PunycodeEncoder implements Converter {

View file

@ -0,0 +1,37 @@
import {NativeLibraryWrapperService} from '../native-library-wrapper.service';
import {QuotedPrintableDecoder} from './quoted-printable-decoder';
import createSpyObj = jasmine.createSpyObj;
import Spy = jasmine.Spy;
describe('QuotedPrintableDecoder', () => {
let sut: QuotedPrintableDecoder;
let nativeWrapperSpy: Partial<NativeLibraryWrapperService>;
let decodeSpy: Spy;
beforeEach(() => {
nativeWrapperSpy = {quotedPrintable: createSpyObj(['decode'])};
decodeSpy = nativeWrapperSpy.quotedPrintable.decode as Spy;
sut = new QuotedPrintableDecoder((nativeWrapperSpy as NativeLibraryWrapperService));
});
it('should create an instance', () => {
expect(sut).toBeTruthy();
});
it('should have a display name', () => {
expect(sut.getDisplayname()).toBeTruthy();
});
it('should have the id "decodequotedprintable"', () => {
expect(sut.getId()).toEqual('decodequotedprintable');
});
it('should call through to the native quoted printable decoder', () => {
const testInput = 'My input';
const expectedOutput = 'It worked';
decodeSpy.and.returnValue(expectedOutput);
const result: string = sut.convert(testInput);
expect(result).toEqual(expectedOutput);
expect(decodeSpy).toHaveBeenCalledWith(testInput);
});
});

View file

@ -1,5 +1,5 @@
import {Converter} from './converter'; import {Converter} from './converter';
import {NativeLibraryWrapperService} from '../nativelibrarywrapper.service'; import {NativeLibraryWrapperService} from '../native-library-wrapper.service';
export class QuotedPrintableDecoder implements Converter { export class QuotedPrintableDecoder implements Converter {

View file

@ -0,0 +1,37 @@
import {NativeLibraryWrapperService} from '../native-library-wrapper.service';
import {QuotedPrintableEncoder} from './quoted-printable-encoder';
import createSpyObj = jasmine.createSpyObj;
import Spy = jasmine.Spy;
describe('QuotedPrintableEncoder', () => {
let sut: QuotedPrintableEncoder;
let nativeWrapperSpy: Partial<NativeLibraryWrapperService>;
let encodeSpy: Spy;
beforeEach(() => {
nativeWrapperSpy = {quotedPrintable: createSpyObj(['encode'])};
encodeSpy = nativeWrapperSpy.quotedPrintable.encode as Spy;
sut = new QuotedPrintableEncoder(nativeWrapperSpy as NativeLibraryWrapperService);
});
it('should create an instance', () => {
expect(sut).toBeTruthy();
});
it('should have a display name', () => {
expect(sut.getDisplayname()).toBeTruthy();
});
it('should have the id "encodequotedprintable"', () => {
expect(sut.getId()).toEqual('encodequotedprintable');
});
it('should call through to the native quoted printable encoder', () => {
const testInput = 'My input';
const expectedOutput = 'It worked';
encodeSpy.and.returnValue(expectedOutput);
const result: string = sut.convert(testInput);
expect(result).toEqual(expectedOutput);
expect(encodeSpy).toHaveBeenCalledWith(testInput);
});
});

View file

@ -1,5 +1,5 @@
import {Converter} from './converter'; import {Converter} from './converter';
import {NativeLibraryWrapperService} from '../nativelibrarywrapper.service'; import {NativeLibraryWrapperService} from '../native-library-wrapper.service';
export class QuotedPrintableEncoder implements Converter { export class QuotedPrintableEncoder implements Converter {

View file

@ -0,0 +1,28 @@
import {ROT13Converter} from './rot13-converter';
describe('ROT13Converter', () => {
let sut: ROT13Converter;
beforeEach(() => sut = new ROT13Converter());
it('should create an instance', () => {
expect(sut).toBeTruthy();
});
it('should have a display name', () => {
expect(sut.getDisplayname()).toBeTruthy();
});
it('should have the id "rot13"', () => {
expect(sut.getId()).toEqual('rot13');
});
it('should encode "Hello, World!" to "Uryyb, Jbeyq!"', () => {
expect(sut.convert('Hello, World!')).toEqual('Uryyb, Jbeyq!');
});
it('should return the original input after being applied twice', () => {
const input = 'Ok, so this string is just a bunch of letters. And numbers: 1, 2, 3. Ans others: /&%. Kthxbye!';
expect(sut.convert(sut.convert(input))).toEqual(input);
});
});

View file

@ -6,7 +6,7 @@ export class ROT13Converter implements Converter {
} }
getId(): string { getId(): string {
return 'rot13convert'; return 'rot13';
} }
convert(input: string): string { convert(input: string): string {

View file

@ -0,0 +1,25 @@
import {URIComponentDecoder} from './uricomponent-decoder';
describe('URIComponentDecoder', () => {
let sut: URIComponentDecoder;
beforeEach(() => sut = new URIComponentDecoder());
it('should create an instance', () => {
expect(sut).toBeTruthy();
});
it('should have a display name', () => {
expect(sut.getDisplayname()).toBeTruthy();
});
it('should have the id "uricomponentdecode"', () => {
expect(sut.getId()).toEqual('uricomponentdecode');
});
it('should decode "http%3A%2F%2Fm%C3%A4nu%3Agh%C3%ABim%40host%3Aport%2Fhi.there%3Foh%3Dwell%23ya" ' +
'to "http://mänu:ghëim@host:port/hi.there?oh=well#ya"', () => {
expect(sut.convert('http%3A%2F%2Fm%C3%A4nu%3Agh%C3%ABim%40host%3Aport%2Fhi.there%3Foh%3Dwell%23ya'))
.toEqual('http://mänu:ghëim@host:port/hi.there?oh=well#ya');
});
});

View file

@ -0,0 +1,25 @@
import {URIComponentEncoder} from './uricomponent-encoder';
describe('URIComponentEncoder', () => {
let sut: URIComponentEncoder;
beforeEach(() => sut = new URIComponentEncoder());
it('should create an instance', () => {
expect(sut).toBeTruthy();
});
it('should have a display name', () => {
expect(sut.getDisplayname()).toBeTruthy();
});
it('should have the id "uricomponentencode"', () => {
expect(sut.getId()).toEqual('uricomponentencode');
});
it('should encode "http://mänu:ghëim@host:port/hi.there?oh=well#ya" ' +
'to "http%3A%2F%2Fm%C3%A4nu%3Agh%C3%ABim%40host%3Aport%2Fhi.there%3Foh%3Dwell%23ya"', () => {
expect(sut.convert('http://mänu:ghëim@host:port/hi.there?oh=well#ya'))
.toEqual('http%3A%2F%2Fm%C3%A4nu%3Agh%C3%ABim%40host%3Aport%2Fhi.there%3Foh%3Dwell%23ya');
});
});

View file

@ -0,0 +1,25 @@
import {URIDecoder} from './uridecoder';
describe('URIDecoder', () => {
let sut: URIDecoder;
beforeEach(() => sut = new URIDecoder());
it('should create an instance', () => {
expect(sut).toBeTruthy();
});
it('should have a display name', () => {
expect(sut.getDisplayname()).toBeTruthy();
});
it('should have the id "uridecode"', () => {
expect(sut.getId()).toEqual('uridecode');
});
it('should decode "http://m%C3%A4nu:gh%C3%ABim@host:port/hi.there?oh=well#ya" ' +
'to "http://mänu:ghëim@host:port/hi.there?oh=well#ya"', () => {
expect(sut.convert('http://m%C3%A4nu:gh%C3%ABim@host:port/hi.there?oh=well#ya'))
.toEqual('http://mänu:ghëim@host:port/hi.there?oh=well#ya');
});
});

View file

@ -0,0 +1,25 @@
import {URIEncoder} from './uriencoder';
describe('URIEncoder', () => {
let sut: URIEncoder;
beforeEach(() => sut = new URIEncoder());
it('should create an instance', () => {
expect(sut).toBeTruthy();
});
it('should have a display name', () => {
expect(sut.getDisplayname()).toBeTruthy();
});
it('should have the id "uriencode"', () => {
expect(sut.getId()).toEqual('uriencode');
});
it('should encode "http://mänu:ghëim@host:port/hi.there?oh=well#ya" ' +
'to "http://m%C3%A4nu:gh%C3%ABim@host:port/hi.there?oh=well#ya"', () => {
expect(sut.convert('http://mänu:ghëim@host:port/hi.there?oh=well#ya'))
.toEqual('http://m%C3%A4nu:gh%C3%ABim@host:port/hi.there?oh=well#ya');
});
});

View file

@ -0,0 +1,37 @@
import {NativeLibraryWrapperService} from '../native-library-wrapper.service';
import {UTF8Decoder} from './utf8-decoder';
import createSpyObj = jasmine.createSpyObj;
import Spy = jasmine.Spy;
describe('UTF8Decoder', () => {
let sut: UTF8Decoder;
let nativeWrapperSpy: Partial<NativeLibraryWrapperService>;
let decodeSpy: Spy;
beforeEach(() => {
nativeWrapperSpy = {utf8: createSpyObj(['decode'])};
decodeSpy = nativeWrapperSpy.utf8.decode as Spy;
sut = new UTF8Decoder((nativeWrapperSpy as NativeLibraryWrapperService));
});
it('should create an instance', () => {
expect(sut).toBeTruthy();
});
it('should have a display name', () => {
expect(sut.getDisplayname()).toBeTruthy();
});
it('should have the id "decodeutf8"', () => {
expect(sut.getId()).toEqual('decodeutf8');
});
it('should call through to the native UTF-8 decoder', () => {
const testInput = 'My input';
const expectedOutput = 'It worked';
decodeSpy.and.returnValue(expectedOutput);
const result: string = sut.convert(testInput);
expect(result).toEqual(expectedOutput);
expect(decodeSpy).toHaveBeenCalledWith(testInput);
});
});

View file

@ -1,5 +1,5 @@
import {Converter} from './converter'; import {Converter} from './converter';
import {NativeLibraryWrapperService} from '../nativelibrarywrapper.service'; import {NativeLibraryWrapperService} from '../native-library-wrapper.service';
export class UTF8Decoder implements Converter { export class UTF8Decoder implements Converter {

View file

@ -0,0 +1,37 @@
import {NativeLibraryWrapperService} from '../native-library-wrapper.service';
import {UTF8Encoder} from './utf8-encoder';
import createSpyObj = jasmine.createSpyObj;
import Spy = jasmine.Spy;
describe('UTF8Encoder', () => {
let sut: UTF8Encoder;
let nativeWrapperSpy: Partial<NativeLibraryWrapperService>;
let encodeSpy: Spy;
beforeEach(() => {
nativeWrapperSpy = {utf8: createSpyObj(['encode'])};
encodeSpy = nativeWrapperSpy.utf8.encode as Spy;
sut = new UTF8Encoder(nativeWrapperSpy as NativeLibraryWrapperService);
});
it('should create an instance', () => {
expect(sut).toBeTruthy();
});
it('should have a display name', () => {
expect(sut.getDisplayname()).toBeTruthy();
});
it('should have the id "encodeutf8"', () => {
expect(sut.getId()).toEqual('encodeutf8');
});
it('should call through to the native UTF-8 encoder', () => {
const testInput = 'My input';
const expectedOutput = 'It worked';
encodeSpy.and.returnValue(expectedOutput);
const result: string = sut.convert(testInput);
expect(result).toEqual(expectedOutput);
expect(encodeSpy).toHaveBeenCalledWith(testInput);
});
});

View file

@ -1,5 +1,5 @@
import {Converter} from './converter'; import {Converter} from './converter';
import {NativeLibraryWrapperService} from '../nativelibrarywrapper.service'; import {NativeLibraryWrapperService} from '../native-library-wrapper.service';
export class UTF8Encoder implements Converter { export class UTF8Encoder implements Converter {

View file

@ -0,0 +1,15 @@
import { TestBed, inject } from '@angular/core/testing';
import { InputComponentManagerService } from './input-component-manager.service';
describe('InputComponentManagerService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [InputComponentManagerService]
});
});
it('should be created', inject([InputComponentManagerService], (service: InputComponentManagerService) => {
expect(service).toBeTruthy();
}));
});

View file

@ -1,7 +1,9 @@
import {Injectable} from '@angular/core'; import {Injectable} from '@angular/core';
import {Step} from './step'; import {Step} from './step';
@Injectable() @Injectable({
providedIn: 'root'
})
export class InputComponentManagerService { export class InputComponentManagerService {
private components: Step[] = []; private components: Step[] = [];

View file

@ -0,0 +1,15 @@
import { TestBed, inject } from '@angular/core/testing';
import { NativeLibraryWrapperService } from './native-library-wrapper.service';
describe('NativeLibraryWrapperService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [NativeLibraryWrapperService]
});
});
it('should be created', inject([NativeLibraryWrapperService], (service: NativeLibraryWrapperService) => {
expect(service).toBeTruthy();
}));
});

View file

@ -1,12 +1,11 @@
import {Injectable} from '@angular/core'; import {Injectable} from '@angular/core';
import {Punycode} from './punycode';
import {Utf8} from './utf8';
import {QuotedPrintable} from './quotedprintable';
import * as NativeUtf8 from 'utf8';
import * as NativeQuotedPrintable from 'quoted-printable';
import * as NativePunycode from 'punycode'; import * as NativePunycode from 'punycode';
import * as NativeQuotedPrintable from 'quoted-printable';
import * as NativeUtf8 from 'utf8';
@Injectable() @Injectable({
providedIn: 'root'
})
export class NativeLibraryWrapperService { export class NativeLibraryWrapperService {
public utf8: Utf8; public utf8: Utf8;
public quotedPrintable: QuotedPrintable; public quotedPrintable: QuotedPrintable;
@ -18,3 +17,21 @@ export class NativeLibraryWrapperService {
this.punycode = NativePunycode; this.punycode = NativePunycode;
} }
} }
interface Punycode {
encode(input: string): string;
decode(input: string): string;
}
interface QuotedPrintable {
encode(input: string): string;
decode(input: string): string;
}
interface Utf8 {
encode(input: any): string;
decode(input: string): any;
}

View file

@ -1,4 +0,0 @@
export interface Punycode {
encode(input: string): string;
decode(input: string): string;
}

View file

@ -1,4 +0,0 @@
export interface QuotedPrintable {
encode(input: string): string;
decode(input: string): string;
}

View file

@ -1,4 +0,0 @@
export interface Utf8 {
encode(input: any): string;
decode(input: string): any;
}

View file

@ -1,6 +1,7 @@
import {async, ComponentFixture, TestBed} from '@angular/core/testing'; import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {VersionComponent} from './version.component'; import {VersionComponent} from './version.component';
import {environment} from '../../environments/environment';
describe('VersionComponent', () => { describe('VersionComponent', () => {
let component: VersionComponent; let component: VersionComponent;
@ -22,4 +23,14 @@ describe('VersionComponent', () => {
it('should create', () => { it('should create', () => {
expect(component).toBeTruthy(); expect(component).toBeTruthy();
}); });
it('should contain the correct version', () => {
// when executing the test, we're always running with the dev environment
expect(component.VERSION).toEqual(`${environment.appVersion} (development build)`);
});
it('should have the correct value for the "production" property', () => {
// when executing the test, we're always running with the dev environment
expect(component.PROD).toBeFalsy();
});
}); });