diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index a82fbf1..36d8222 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -1,36 +1,27 @@ import {AppComponent} from './app.component'; import {async, ComponentFixture, TestBed} from '@angular/core/testing'; import {FormsModule} from '@angular/forms'; -import {InputComponentManagerService} from './inputcomponentmanager.service'; +import {InputComponentManagerService} from './input-component-manager.service'; import {Step} from './step'; -import {ConverterRegistryService} from './converterregistry.service'; -import {Converter} from './converter/converter'; +import {ConverterRegistryService} from './converter-registry.service'; +import {VersionComponent} from './version/version.component'; +import createSpyObj = jasmine.createSpyObj; describe('AppComponent', () => { let sut: AppComponent; let fixture: ComponentFixture; const firstStep: Step = new Step(0); - const inputComponentManagerServiceStub = { - getFirst: () => { - return firstStep; - } - }; + const inputComponentManagerServiceStub = createSpyObj(['getFirst']); + inputComponentManagerServiceStub.getFirst.and.returnValue(firstStep); - const converterRegistryServiceStub = { - getAllConverters: (): Converter[] => { - return []; - }, - - getConverter: (id: string): Converter => { - return undefined; - } - }; + const converterRegistryServiceStub = createSpyObj(['getAllConverters', 'getConverter']); + converterRegistryServiceStub.getAllConverters.and.returnValue([]); + converterRegistryServiceStub.getConverter.and.returnValue(undefined); beforeEach(async(() => { - /*return */ TestBed.configureTestingModule({ - declarations: [AppComponent], + declarations: [AppComponent, VersionComponent], imports: [FormsModule], providers: [ {provide: InputComponentManagerService, useValue: inputComponentManagerServiceStub}, diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 1ec7c84..820811b 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,6 +1,6 @@ import {Component, OnInit} from '@angular/core'; -import {ConverterRegistryService} from './converterregistry.service'; -import {InputComponentManagerService} from './inputcomponentmanager.service'; +import {ConverterRegistryService} from './converter-registry.service'; +import {InputComponentManagerService} from './input-component-manager.service'; import {Step} from './step'; import {Converter} from './converter/converter'; diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 7ef864d..5e40ab8 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,9 +1,9 @@ import {BrowserModule} from '@angular/platform-browser'; import {NgModule} from '@angular/core'; import {AppComponent} from './app.component'; -import {ConverterRegistryService} from './converterregistry.service'; -import {InputComponentManagerService} from './inputcomponentmanager.service'; -import {NativeLibraryWrapperService} from './nativelibrarywrapper.service'; +import {ConverterRegistryService} from './converter-registry.service'; +import {InputComponentManagerService} from './input-component-manager.service'; +import {NativeLibraryWrapperService} from './native-library-wrapper.service'; import {FormsModule} from '@angular/forms'; import {VersionComponent} from './version/version.component'; diff --git a/src/app/converter-registry.service.spec.ts b/src/app/converter-registry.service.spec.ts new file mode 100644 index 0000000..2b97a17 --- /dev/null +++ b/src/app/converter-registry.service.spec.ts @@ -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(); + })); +}); diff --git a/src/app/converterregistry.service.ts b/src/app/converter-registry.service.ts similarity index 62% rename from src/app/converterregistry.service.ts rename to src/app/converter-registry.service.ts index 4d66673..d84733b 100644 --- a/src/app/converterregistry.service.ts +++ b/src/app/converter-registry.service.ts @@ -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 {Base64Encoder} from './converter/base64encoder'; -import {Base64Decoder} from './converter/base64decoder'; -import {URIEncoder} from './converter/uriencoder'; +import {DecToBinConverter} from './converter/dec-to-bin-converter'; +import {DecToHexConverter} from './converter/dec-to-hex-converter'; +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 {URIComponentEncoder} from './converter/uricomponentencoder'; -import {URIComponentDecoder} from './converter/uricomponentdecoder'; -import {HTMLEntitiesEncoder} from './converter/htmlentitiesencoder'; -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'; +import {URIEncoder} from './converter/uriencoder'; +import {UTF8Decoder} from './converter/utf8-decoder'; +import {UTF8Encoder} from './converter/utf8-encoder'; -@Injectable() +@Injectable({ + providedIn: 'root' +}) export class ConverterRegistryService { private converters: Converter[] = []; diff --git a/src/app/converter/base64-decoder.spec.ts b/src/app/converter/base64-decoder.spec.ts new file mode 100644 index 0000000..5e6aefa --- /dev/null +++ b/src/app/converter/base64-decoder.spec.ts @@ -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?'); + }); +}); diff --git a/src/app/converter/base64decoder.ts b/src/app/converter/base64-decoder.ts similarity index 100% rename from src/app/converter/base64decoder.ts rename to src/app/converter/base64-decoder.ts diff --git a/src/app/converter/base64-encoder.spec.ts b/src/app/converter/base64-encoder.spec.ts new file mode 100644 index 0000000..99e486a --- /dev/null +++ b/src/app/converter/base64-encoder.spec.ts @@ -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./); + }); +}); diff --git a/src/app/converter/base64encoder.ts b/src/app/converter/base64-encoder.ts similarity index 79% rename from src/app/converter/base64encoder.ts rename to src/app/converter/base64-encoder.ts index c9e3513..6853180 100644 --- a/src/app/converter/base64encoder.ts +++ b/src/app/converter/base64-encoder.ts @@ -14,7 +14,7 @@ export class Base64Encoder implements Converter { return btoa(input); } catch (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 ' + 'enjoy some kittens meanwhile?'); } diff --git a/src/app/converter/bin-to-dec-converter.spec.ts b/src/app/converter/bin-to-dec-converter.spec.ts new file mode 100644 index 0000000..1439482 --- /dev/null +++ b/src/app/converter/bin-to-dec-converter.spec.ts @@ -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.'); + }); +}); diff --git a/src/app/converter/bintodecconverter.ts b/src/app/converter/bin-to-dec-converter.ts similarity index 87% rename from src/app/converter/bintodecconverter.ts rename to src/app/converter/bin-to-dec-converter.ts index 3315882..fe95bff 100644 --- a/src/app/converter/bintodecconverter.ts +++ b/src/app/converter/bin-to-dec-converter.ts @@ -11,7 +11,7 @@ export class BinToDecConverter implements Converter { convert(input: string): string { 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.'); } return n.toString(10); diff --git a/src/app/converter/dec-to-bin-converter.spec.ts b/src/app/converter/dec-to-bin-converter.spec.ts new file mode 100644 index 0000000..0b9a971 --- /dev/null +++ b/src/app/converter/dec-to-bin-converter.spec.ts @@ -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.'); + }); +}); diff --git a/src/app/converter/dectobinconverter.ts b/src/app/converter/dec-to-bin-converter.ts similarity index 100% rename from src/app/converter/dectobinconverter.ts rename to src/app/converter/dec-to-bin-converter.ts diff --git a/src/app/converter/dec-to-hex-converter.spec.ts b/src/app/converter/dec-to-hex-converter.spec.ts new file mode 100644 index 0000000..4eecac4 --- /dev/null +++ b/src/app/converter/dec-to-hex-converter.spec.ts @@ -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.'); + }); +}); diff --git a/src/app/converter/dectohexconverter.ts b/src/app/converter/dec-to-hex-converter.ts similarity index 100% rename from src/app/converter/dectohexconverter.ts rename to src/app/converter/dec-to-hex-converter.ts diff --git a/src/app/converter/hex-to-dec-converter.spec.ts b/src/app/converter/hex-to-dec-converter.spec.ts new file mode 100644 index 0000000..07003ed --- /dev/null +++ b/src/app/converter/hex-to-dec-converter.spec.ts @@ -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.'); + }); +}); diff --git a/src/app/converter/hextodecconverter.ts b/src/app/converter/hex-to-dec-converter.ts similarity index 85% rename from src/app/converter/hextodecconverter.ts rename to src/app/converter/hex-to-dec-converter.ts index 4b78345..7ac803e 100644 --- a/src/app/converter/hextodecconverter.ts +++ b/src/app/converter/hex-to-dec-converter.ts @@ -11,7 +11,7 @@ export class HexToDecConverter implements Converter { convert(input: string): string { 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.'); } return n.toString(10); diff --git a/src/app/converter/htmlentities-decoder.spec.ts b/src/app/converter/htmlentities-decoder.spec.ts new file mode 100644 index 0000000..a1555ad --- /dev/null +++ b/src/app/converter/htmlentities-decoder.spec.ts @@ -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 "<span>"Hi" & "Lo"</span>" to ""Hi" & "Lo""', () => { + expect(sut.convert('<span>"Hi" & "Lo"</span>')) + .toEqual('"Hi" & "Lo"'); + }); +}); diff --git a/src/app/converter/htmlentitiesdecoder.ts b/src/app/converter/htmlentities-decoder.ts similarity index 100% rename from src/app/converter/htmlentitiesdecoder.ts rename to src/app/converter/htmlentities-decoder.ts diff --git a/src/app/converter/htmlentities-encoder.spec.ts b/src/app/converter/htmlentities-encoder.spec.ts new file mode 100644 index 0000000..1408d0d --- /dev/null +++ b/src/app/converter/htmlentities-encoder.spec.ts @@ -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 ""Hi" & "Lo"" to "<span>"Hi" & "Lo"</span>"', () => { + expect(sut.convert('"Hi" & "Lo"')) + .toEqual('<span>"Hi" & "Lo"</span>'); + }); +}); diff --git a/src/app/converter/htmlentitiesencoder.ts b/src/app/converter/htmlentities-encoder.ts similarity index 100% rename from src/app/converter/htmlentitiesencoder.ts rename to src/app/converter/htmlentities-encoder.ts diff --git a/src/app/converter/punycode-decoder.spec.ts b/src/app/converter/punycode-decoder.spec.ts new file mode 100644 index 0000000..3895c3e --- /dev/null +++ b/src/app/converter/punycode-decoder.spec.ts @@ -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; + 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); + }); +}); diff --git a/src/app/converter/punycodedecoder.ts b/src/app/converter/punycode-decoder.ts similarity index 83% rename from src/app/converter/punycodedecoder.ts rename to src/app/converter/punycode-decoder.ts index 5f68ec6..c850e2b 100644 --- a/src/app/converter/punycodedecoder.ts +++ b/src/app/converter/punycode-decoder.ts @@ -1,5 +1,5 @@ import {Converter} from './converter'; -import {NativeLibraryWrapperService} from '../nativelibrarywrapper.service'; +import {NativeLibraryWrapperService} from '../native-library-wrapper.service'; export class PunycodeDecoder implements Converter { diff --git a/src/app/converter/punycode-encoder.spec.ts b/src/app/converter/punycode-encoder.spec.ts new file mode 100644 index 0000000..1bd8669 --- /dev/null +++ b/src/app/converter/punycode-encoder.spec.ts @@ -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; + 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); + }); +}); diff --git a/src/app/converter/punycodeencoder.ts b/src/app/converter/punycode-encoder.ts similarity index 83% rename from src/app/converter/punycodeencoder.ts rename to src/app/converter/punycode-encoder.ts index ebf8b67..05523d6 100644 --- a/src/app/converter/punycodeencoder.ts +++ b/src/app/converter/punycode-encoder.ts @@ -1,5 +1,5 @@ import {Converter} from './converter'; -import {NativeLibraryWrapperService} from '../nativelibrarywrapper.service'; +import {NativeLibraryWrapperService} from '../native-library-wrapper.service'; export class PunycodeEncoder implements Converter { diff --git a/src/app/converter/quoted-printable-decoder.spec.ts b/src/app/converter/quoted-printable-decoder.spec.ts new file mode 100644 index 0000000..a74cb50 --- /dev/null +++ b/src/app/converter/quoted-printable-decoder.spec.ts @@ -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; + 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); + }); +}); diff --git a/src/app/converter/quotedprintabledecoder.ts b/src/app/converter/quoted-printable-decoder.ts similarity index 87% rename from src/app/converter/quotedprintabledecoder.ts rename to src/app/converter/quoted-printable-decoder.ts index 9c43014..d1992c5 100644 --- a/src/app/converter/quotedprintabledecoder.ts +++ b/src/app/converter/quoted-printable-decoder.ts @@ -1,5 +1,5 @@ import {Converter} from './converter'; -import {NativeLibraryWrapperService} from '../nativelibrarywrapper.service'; +import {NativeLibraryWrapperService} from '../native-library-wrapper.service'; export class QuotedPrintableDecoder implements Converter { diff --git a/src/app/converter/quoted-printable-encoder.spec.ts b/src/app/converter/quoted-printable-encoder.spec.ts new file mode 100644 index 0000000..da4191f --- /dev/null +++ b/src/app/converter/quoted-printable-encoder.spec.ts @@ -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; + 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); + }); +}); diff --git a/src/app/converter/quotedprintableencoder.ts b/src/app/converter/quoted-printable-encoder.ts similarity index 84% rename from src/app/converter/quotedprintableencoder.ts rename to src/app/converter/quoted-printable-encoder.ts index 17cbb32..b6d07b8 100644 --- a/src/app/converter/quotedprintableencoder.ts +++ b/src/app/converter/quoted-printable-encoder.ts @@ -1,5 +1,5 @@ import {Converter} from './converter'; -import {NativeLibraryWrapperService} from '../nativelibrarywrapper.service'; +import {NativeLibraryWrapperService} from '../native-library-wrapper.service'; export class QuotedPrintableEncoder implements Converter { diff --git a/src/app/converter/rot13-converter.spec.ts b/src/app/converter/rot13-converter.spec.ts new file mode 100644 index 0000000..dc4bd47 --- /dev/null +++ b/src/app/converter/rot13-converter.spec.ts @@ -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); + }); +}); diff --git a/src/app/converter/rot13converter.ts b/src/app/converter/rot13-converter.ts similarity index 96% rename from src/app/converter/rot13converter.ts rename to src/app/converter/rot13-converter.ts index ed51b5d..0bc9df5 100644 --- a/src/app/converter/rot13converter.ts +++ b/src/app/converter/rot13-converter.ts @@ -6,7 +6,7 @@ export class ROT13Converter implements Converter { } getId(): string { - return 'rot13convert'; + return 'rot13'; } convert(input: string): string { diff --git a/src/app/converter/uricomponent-decoder.spec.ts b/src/app/converter/uricomponent-decoder.spec.ts new file mode 100644 index 0000000..9125d74 --- /dev/null +++ b/src/app/converter/uricomponent-decoder.spec.ts @@ -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'); + }); +}); diff --git a/src/app/converter/uricomponentdecoder.ts b/src/app/converter/uricomponent-decoder.ts similarity index 100% rename from src/app/converter/uricomponentdecoder.ts rename to src/app/converter/uricomponent-decoder.ts diff --git a/src/app/converter/uricomponent-encoder.spec.ts b/src/app/converter/uricomponent-encoder.spec.ts new file mode 100644 index 0000000..832f0fa --- /dev/null +++ b/src/app/converter/uricomponent-encoder.spec.ts @@ -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'); + }); +}); diff --git a/src/app/converter/uricomponentencoder.ts b/src/app/converter/uricomponent-encoder.ts similarity index 100% rename from src/app/converter/uricomponentencoder.ts rename to src/app/converter/uricomponent-encoder.ts diff --git a/src/app/converter/uridecoder.spec.ts b/src/app/converter/uridecoder.spec.ts new file mode 100644 index 0000000..158862c --- /dev/null +++ b/src/app/converter/uridecoder.spec.ts @@ -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'); + }); +}); diff --git a/src/app/converter/uriencoder.spec.ts b/src/app/converter/uriencoder.spec.ts new file mode 100644 index 0000000..dbbbaec --- /dev/null +++ b/src/app/converter/uriencoder.spec.ts @@ -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'); + }); +}); diff --git a/src/app/converter/utf8-decoder.spec.ts b/src/app/converter/utf8-decoder.spec.ts new file mode 100644 index 0000000..919092e --- /dev/null +++ b/src/app/converter/utf8-decoder.spec.ts @@ -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; + 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); + }); +}); diff --git a/src/app/converter/utf8decoder.ts b/src/app/converter/utf8-decoder.ts similarity index 87% rename from src/app/converter/utf8decoder.ts rename to src/app/converter/utf8-decoder.ts index 7f19a76..a17f502 100644 --- a/src/app/converter/utf8decoder.ts +++ b/src/app/converter/utf8-decoder.ts @@ -1,5 +1,5 @@ import {Converter} from './converter'; -import {NativeLibraryWrapperService} from '../nativelibrarywrapper.service'; +import {NativeLibraryWrapperService} from '../native-library-wrapper.service'; export class UTF8Decoder implements Converter { diff --git a/src/app/converter/utf8-encoder.spec.ts b/src/app/converter/utf8-encoder.spec.ts new file mode 100644 index 0000000..4e92288 --- /dev/null +++ b/src/app/converter/utf8-encoder.spec.ts @@ -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; + 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); + }); +}); diff --git a/src/app/converter/utf8encoder.ts b/src/app/converter/utf8-encoder.ts similarity index 86% rename from src/app/converter/utf8encoder.ts rename to src/app/converter/utf8-encoder.ts index 7e911d4..9d47879 100644 --- a/src/app/converter/utf8encoder.ts +++ b/src/app/converter/utf8-encoder.ts @@ -1,5 +1,5 @@ import {Converter} from './converter'; -import {NativeLibraryWrapperService} from '../nativelibrarywrapper.service'; +import {NativeLibraryWrapperService} from '../native-library-wrapper.service'; export class UTF8Encoder implements Converter { diff --git a/src/app/input-component-manager.service.spec.ts b/src/app/input-component-manager.service.spec.ts new file mode 100644 index 0000000..b15c3bc --- /dev/null +++ b/src/app/input-component-manager.service.spec.ts @@ -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(); + })); +}); diff --git a/src/app/inputcomponentmanager.service.ts b/src/app/input-component-manager.service.ts similarity index 95% rename from src/app/inputcomponentmanager.service.ts rename to src/app/input-component-manager.service.ts index 136d1b6..45e8d02 100644 --- a/src/app/inputcomponentmanager.service.ts +++ b/src/app/input-component-manager.service.ts @@ -1,7 +1,9 @@ import {Injectable} from '@angular/core'; import {Step} from './step'; -@Injectable() +@Injectable({ + providedIn: 'root' +}) export class InputComponentManagerService { private components: Step[] = []; diff --git a/src/app/native-library-wrapper.service.spec.ts b/src/app/native-library-wrapper.service.spec.ts new file mode 100644 index 0000000..35f2936 --- /dev/null +++ b/src/app/native-library-wrapper.service.spec.ts @@ -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(); + })); +}); diff --git a/src/app/nativelibrarywrapper.service.ts b/src/app/native-library-wrapper.service.ts similarity index 59% rename from src/app/nativelibrarywrapper.service.ts rename to src/app/native-library-wrapper.service.ts index f3ce6af..308a14f 100644 --- a/src/app/nativelibrarywrapper.service.ts +++ b/src/app/native-library-wrapper.service.ts @@ -1,12 +1,11 @@ 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 NativeQuotedPrintable from 'quoted-printable'; +import * as NativeUtf8 from 'utf8'; -@Injectable() +@Injectable({ + providedIn: 'root' +}) export class NativeLibraryWrapperService { public utf8: Utf8; public quotedPrintable: QuotedPrintable; @@ -18,3 +17,21 @@ export class NativeLibraryWrapperService { 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; +} diff --git a/src/app/punycode.ts b/src/app/punycode.ts deleted file mode 100644 index 1368326..0000000 --- a/src/app/punycode.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface Punycode { - encode(input: string): string; - decode(input: string): string; -} diff --git a/src/app/quotedprintable.ts b/src/app/quotedprintable.ts deleted file mode 100644 index 59bdfba..0000000 --- a/src/app/quotedprintable.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface QuotedPrintable { - encode(input: string): string; - decode(input: string): string; -} diff --git a/src/app/utf8.ts b/src/app/utf8.ts deleted file mode 100644 index 86706f5..0000000 --- a/src/app/utf8.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface Utf8 { - encode(input: any): string; - decode(input: string): any; -} diff --git a/src/app/version/version.component.spec.ts b/src/app/version/version.component.spec.ts index fcd0475..fb1ae45 100644 --- a/src/app/version/version.component.spec.ts +++ b/src/app/version/version.component.spec.ts @@ -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', () => { let component: VersionComponent; @@ -8,9 +9,9 @@ describe('VersionComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ VersionComponent ] + declarations: [VersionComponent] }) - .compileComponents(); + .compileComponents(); })); beforeEach(() => { @@ -22,4 +23,14 @@ describe('VersionComponent', () => { it('should create', () => { 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(); + }); });