Programming Languages
TypeScript Conditional Types Good Usage Part 1
Example 1
I try to understand eventType
field from Event
object. But in order to use createEventGridMessage
in other TypeScript file, you need to import StartEvent
, InfoEvent
and EndEvent
types. So next example of this case looks better to me 🙂
import {v4 as uuidv4} from 'uuid';
export type BaseEvent = {
timeStamp?: number,
componentName: string,
componentVersion: string,
operationId: string,
correlationId: string,
data: any,
}
export type StartEvent = Partial<BaseEvent> & {
eventType: 'LogStart',
source: string,
trigger: string,
};
export type EndEvent = Partial<BaseEvent> & {
eventType: 'LogEnd'
destination: 'Event Grid' | 'Http Response' | 'Database' | string,
};
export type InfoEvent = Pick<EndEvent, keyof Omit<EndEvent, 'eventType'>> & { eventType: 'LogInfo' };
export type Event = StartEvent | EndEvent | InfoEvent;
export type EventGridMessageParameters<T extends Event> = Pick<EventGridMessage<T>, 'data' | 'eventType' | 'subject' | 'topic'>;
export type EventType<T extends Event> = T extends StartEvent ? 'LogStart' : T extends EndEvent ? 'LogEnd' : T extends InfoEvent ? 'LogInfo' : 'UNKNOWN EVENT TYPE';
export interface EventGridMessage<T extends Event> {
id: string;
topic: string;
subject: string;
eventType: EventType<T>;
eventTime: Date;
data: T;
dataVersion: string;
metadataVersion: string;
}
export const createEventGridMessage = <T extends Event>({
data,
eventType,
subject = "New message from unknown source",
topic = ""
}: EventGridMessageParameters<T>): EventGridMessage<T> =>
({
id: uuidv4(),
topic,
subject,
eventType,
eventTime: new Date(),
data: {...data, timeStamp: data.timeStamp || new Date().getTime()},
dataVersion: "1.0",
metadataVersion: "1.0"
});
const startLogMessage = createEventGridMessage<StartEvent>({
eventType: 'LogStart',
data: {
eventType: 'LogStart',
trigger: '',
source: '',
correlationId: '',
componentVersion: '',
componentName: '',
operationId: ''
},
subject: '',
topic: ''
});
console.log(startLogMessage);
const infoLogMessage = createEventGridMessage<InfoEvent>({
eventType: 'LogInfo',
data: {
eventType: 'LogInfo',
correlationId: '',
componentVersion: '',
componentName: '',
operationId: '',
destination: '',
},
subject: '',
topic: ''
});
console.log(infoLogMessage);
const endLogMessage = createEventGridMessage<EndEvent>({
eventType: 'LogEnd',
data: {
eventType: 'LogEnd',
timeStamp: new Date().getTime(),
correlationId: '',
componentVersion: '',
componentName: '',
operationId: '',
destination: '',
},
subject: '',
topic: ''
});
console.log(endLogMessage);
Continue reading TypeScript Conditional Types
Conditional Type Expression
SomeType extends OtherType ? TrueType : FalseType;
Basic Usages
Example 1
type NumberOrNot<T> = T extends number ? string : never;
Example 2
type StringOrNot<T> = T extends string ? string : never;
Example 3
type BooleanOrNumberOnly<T> = T extends boolean | number ? T : never;
type NewType = StringOrNumberOnly<string | number | boolean>;
const a1: NewType = true; // boolean
const a2: NewType = 23; // number
Continue reading Jest Mocking Default Instance
Example 1
const mockedPutObject = jest.fn();
jest.mock('@aws-sdk/client-s3', () => {
return {
S3: jest.fn(() => ({
putObject: () => mockedPutObject()
}))
}
});
Example 2
jest.mock('uuid', () => ({ v4: () => '00000000-0000-0000-0000-000000000000' }));
Example 3
jest.mock('uuid');
const mockedUuidv4 = uuidv4 as jest.Mock;
mockedUuidv4.mockReturnValue('00000000-0000-0000-0000-000000000000');
Example 4
const mockedAjvValidate = jest.fn().mockReturnValue(true);
jest.mock('ajv', () => {
return jest.fn(() => ({
compile: () => () => mockedAjvValidate()
}))
});
Example 5
jest.mock('moment', () => () => ({ format: () => '30-12-2021' }));
Example 6
import { v4 as uuid } from 'uuid';
export interface IEvent {
id?: string;
eventType: string;
data: any;
}
export interface IEventRepository {
getEvent(id: string): IEvent | undefined;
setEvent(event: IEvent): IEvent;
}
const createEvent = (event: IEvent): IEvent => ({ id: uuid(), ...event });
export class EventRedisRepository implements IEventRepository {
constructor(private events: Array<IEvent> = []) { }
getEvent(id: string): IEvent | undefined {
return this.events.find(item => item.id === id);
}
setEvent(event: IEvent): IEvent {
const newEvent: IEvent = createEvent(event);
this.events.push(newEvent);
return newEvent;
}
}
export class EventCosmosDbRepository implements IEventRepository {
constructor(private events: Array<IEvent> = []) { }
getEvent(id: string): IEvent | undefined {
return this.events.find(item => item.id === id);
}
setEvent(event: IEvent): IEvent {
const newEvent: IEvent = createEvent(event);
this.events.push(newEvent);
return newEvent;
}
}
import { Persister } from '../src';
import { EventRedisRepository, EventCosmosDbRepository, IEventRepository, IEvent } from './sample';
const mockedRedisGetEvent = jest.fn();
const mockedRedisSetEvent = jest.fn();
const mockedCosmosdbGetEvent = jest.fn();
const mockedCosmosdbSetEvent = jest.fn();
jest.mock('./sample', () => {
return {
EventRedisRepository: jest.fn(() => ({
getEvent: () => mockedRedisGetEvent(),
setEvent: () => mockedRedisSetEvent(),
})),
EventCosmosDbRepository: jest.fn(() => ({
getEvent: () => mockedCosmosdbGetEvent(),
setEvent: () => mockedCosmosdbSetEvent(),
})),
}
});
const eventRedisRepository = new EventRedisRepository();
const eventCosmosdbRepository = new EventCosmosDbRepository();
const module_name = `${Persister.name}`;
describe(`${module_name} Test`, () => {
it('should call setEvent function in both persisters', () => {
const eventPersister = new Persister<IEventRepository>([eventRedisRepository, eventCosmosdbRepository]);
const eventId = '4e0c71bb-eedf-43dd-b9a1-911a7ed6d74f';
const newEvent: IEvent = { id: eventId, eventType: 'Submission', data: {} };
eventPersister.set('setEvent', op => op(newEvent));
expect(mockedRedisSetEvent).toHaveBeenCalledTimes(1);
expect(mockedCosmosdbSetEvent).toHaveBeenCalledTimes(1);
});
});
Example 6 – updated and short version
import { Persister } from '../src';
import { EventRedisRepository, EventCosmosDbRepository, IEventRepository, IEvent } from './sample';
import { mocked } from 'jest-mock'
jest.mock('./sample');
const eventRedisRepository = new EventRedisRepository();
const eventCosmosdbRepository = new EventCosmosDbRepository();
const mockedEventRedisRepository = mocked(eventRedisRepository, true);
const mockedEventCosmosdbRepository = mocked(eventRedisRepository, true);
const module_name = `${Persister.name}`;
describe(`${module_name} Test`, () => {
it('should call setEvent function in both persisters', () => {
const eventPersister = new Persister<IEventRepository>([eventRedisRepository, eventCosmosdbRepository]);
const eventId = '4e0c71bb-eedf-43dd-b9a1-911a7ed6d74f';
const newEvent: IEvent = { id: eventId, eventType: 'Submission', data: {} };
eventPersister.set('setEvent', op => op(newEvent));
expect(mockedEventRedisRepository.setEvent).toHaveBeenCalledTimes(1);
expect(mockedEventCosmosdbRepository.setEvent).toHaveBeenCalledTimes(1);
});
});
TypeScript Good Usages
TypeScript Object Oriented Programming
https://github.com/nodejs-projects-kenanhancer/typescript-object-oriented-programming
See the Pen TypeScriptOOPDemo1 by kenanhancer (@kenanhancer) on CodePen.
How to create and run TypeScript project
$ mkdir typescript-demo1
$ npm init -y
$ npm install --save-dev typescript @types/node rimraf
$ npx tsc --init --rootDir src --outDir build \
--esModuleInterop --resolveJsonModule --lib es6 \
--module commonjs --allowJs true --noImplicitAny true
$ mkdir src
$ echo "console.log('Hello world');" > src/index.ts
$ npx tsc
$ node dist/index.js
Continue reading TypeScript Interface Function Types and Indexable Types
Interface as Type
Implementing Interface
Demo1:
See the Pen TypeScriptInterfaceDemo1 by kenanhancer (@kenanhancer) on CodePen.
Continue readingHow to create and run C# project
This post is just a reminder for me. So in order to find more details about dotnet CLI, follow the below link
https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet
$ dotnet new console -h
Console App (C#)
Author: Microsoft
Description: A project for creating a command-line application that can run on .NET on Windows, Linux and macOS
Usage:
dotnet new console [options] [template options]
Options:
-n, --name <name> The name for the output being created. If no name is specified, the name of the output directory is used.
-o, --output <output> Location to place the generated output.
--dry-run Displays a summary of what would happen if the given command line were run if it would result in a template creation.
--force Forces content to be generated even if it would change existing files.
--no-update-check Disables checking for the template package updates when instantiating a template.
--project <project> The project that should be used for context evaluation.
-lang, --language <C#> Specifies the template language to instantiate.
--type <project> Specifies the template type to instantiate.
Template options:
-f, --framework <net5.0|net6.0|net7.0> The target framework for the project.
Type: choice
net7.0 Target net7.0
net6.0 Target net6.0
net5.0 Target net5.0
Default: net7.0
--langVersion <langVersion> Sets the LangVersion property in the created project file
Type: text
--no-restore If specified, skips the automatic restore of the project on create.
Type: bool
Default: false
--use-program-main Whether to generate an explicit Program class and Main method instead of top-level statements.
Type: bool
Default: false
To see help for other template languages (F#, VB), use --language option:
dotnet new console -h --language F#
Creating a C# Project
$ dotnet new --list
These templates matched your input:
Template Name Short Name Language Tags
-------------------------------------------- ------------------ ---------- --------------------------------
ASP.NET Core Empty web [C#],F# Web/Empty
ASP.NET Core gRPC Service grpc [C#] Web/gRPC
ASP.NET Core Web API webapi [C#],F# Web/WebAPI
ASP.NET Core Web App webapp,razor [C#] Web/MVC/Razor Pages
ASP.NET Core Web App (Model-View-Controller) mvc [C#],F# Web/MVC
ASP.NET Core with Angular angular [C#] Web/MVC/SPA
ASP.NET Core with React.js react [C#] Web/MVC/SPA
ASP.NET Core with React.js and Redux reactredux [C#] Web/MVC/SPA
Blazor Server App blazorserver [C#] Web/Blazor
Blazor Server App Empty blazorserver-empty [C#] Web/Blazor/Empty
Blazor WebAssembly App blazorwasm [C#] Web/Blazor/WebAssembly/PWA
Blazor WebAssembly App Empty blazorwasm-empty [C#] Web/Blazor/WebAssembly/PWA/Empty
Class Library classlib [C#],F#,VB Common/Library
Console App console [C#],F#,VB Common/Console
dotnet gitignore file gitignore Config
Dotnet local tool manifest file tool-manifest Config
EditorConfig file editorconfig Config
global.json file globaljson Config
MSBuild Directory.Build.props file buildprops MSBuild/props
MSBuild Directory.Build.targets file buildtargets MSBuild/props
MSTest Test Project mstest [C#],F#,VB Test/MSTest
MVC ViewImports viewimports [C#] Web/ASP.NET
MVC ViewStart viewstart [C#] Web/ASP.NET
NuGet Config nugetconfig Config
NUnit 3 Test Item nunit-test [C#],F#,VB Test/NUnit
NUnit 3 Test Project nunit [C#],F#,VB Test/NUnit
Protocol Buffer File proto Web/gRPC
Razor Class Library razorclasslib [C#] Web/Razor/Library
Razor Component razorcomponent [C#] Web/ASP.NET
Razor Page page [C#] Web/ASP.NET
Solution File sln,solution Solution
Web Config webconfig Config
Worker Service worker [C#],F# Common/Worker/Web
xUnit Test Project xunit [C#],F#,VB Test/xUnit
$ dotnet --list-sdks
5.0.408 [/Users/kenanhancer/.dotnet/sdk]
6.0.411 [/Users/kenanhancer/.dotnet/sdk]
7.0.305 [/Users/kenanhancer/.dotnet/sdk]
Creating a Console Project
Use any template short name
after dotnet net
and .NET SDK version after --framework
option.
$ dotnet new console --framework net6.0 -o console-demo1
Creating a WebApi Project
$ dotnet new webapi --framework net6.0 -o webapi-todo-demo1
Specify .NET version in project folder
If you have multiple versions of the .NET Core SDK installed, the version that's used can be controlled using a global.json
file. This file allows you to specify which version of the .NET Core SDK should be used.
$ dotnet new globaljson --sdk-version 6.0.411 --force
1. Creating a C# Console Project
-o or –output is location to place for new generated project.
$ dotnet new console --framework net6.0 --output enum_demo4
# OR
$ dotnet new console --framework net6.0 -o enum_demo4
# OR
$ dotnet new console --framework net6.0 --name enum_demo4
Folder Structure
Generated Project
Continue readingHow to compile and run Java Projects with java and javac commands
Compiling
-d is output directory for new generated class files.
How to compile single Java source file
javac -d ./target/classes src/main/java/com/extuni/enum_demo4/App.java
How to compile multiple Java source files
javac -d ./target/classes
./src/main/java/com/extuni/enum_demo4/App.java
./src/main/java/com/extuni/enum_demo4/Greeting.java
./src/main/java/com/extuni/enum_demo4/Helper.java
How to compile multiple Java source files using wildcard
javac -d ./target/classes ./src/main/**/*.java
How to specify dependency jar file when compiling
Trying to compile ./src folder completely will throw exception due to junit.jar file dependency. So, it should be specified using -cp option which means –classpath as below.
javac -d ./target/classes -cp /Users/kenanhancer/.m2/repository/junit/junit/4.11/junit-4.11.jar ./src/**/*.java
Continue reading