Podsumowanie 2023 roku

Opublikowano: 30.12.2023 - tagi: Blog Podsumowanie 2023

Poniżej krótkie podsumowanie 2023 roku:

Opublikowałem: 64 wpisy.

Narysowałem: 9 komiksów.

Wpisy:


Inne:

  1. 6 sposobów na lepszą koncentrację
  2. Blog: Podsumowanie drugiego roku

TypeScript:

  1. Jak stworzyć pustą liczbę?
  2. Partial

React:

  1. Do czego służy useState?
  2. Do czego służy useEffect?
  3. Warunkowe renderowanie komponentów
  4. Jak używać async i await w useEffect?
  5. Typescript i komponenty
  6. Do czego służy useRef?
  7. Do czego służy useReducer?
  8. Obsługa formularzy
  9. Do czego służy memo?
  10. React Testing Library: Jak pobrać referencję do elementu w komponencie?
  11. React Testing Library: Jak zasymulować kliknięcie w element?
  12. Material UI: Jak ustawić kontrolkę na pełną szerokość?
  13. React Testing Library: Jak wyczyścić dane z kontrolki?
  14. React Testing Library: Jak zasymulować wybór opcji z listy?
  15. React Testing Library: Jak zasymulować wpisanie danych do kontrolki?
  16. React Testing Library: Jak mockować requesty?
  17. React Testing Library: Within
  18. React Testing Library: Jak sprawdzić kolejność wyświetlanych elementów na liście?
  19. React Testing Library: Jak pisać łatwe w utrzymaniu testy?
  20. React Testing Library: Klawiatura

JavaScript:

  1. Operator ??
  2. Jak pobrać strefę czasową użytkownika?
  3. Ścieżki absolutne
  4. Jak rzutować string na wartość typu boolean?
  5. Parcel praca z kodem przy minimalnej konfiguracji
  6. Canvas: Obracanie obiektu wokół jego środka
  7. Canvas: Jak pobrać pozycję kursora myszy?
  8. Canvas: Obracanie obiektu za pomocą myszki
  9. Jak sprawdzić, z jakiego motywu graficznego korzysta użytkownik?
  10. Jak pobrać n pierwszych elementów tablicy?

Git:

  1. Jak pobrać informacje o zdalnym repozytorium?

Webstorm:

  1. Jak skonfigurować ścieżki absolutne?

NodeJS:

  1. Skąd pobrać wersję dla CHROMIUM_REVISION?
  2. Jak pobrać dane w postaci zwykłych obiektów w Mongoose?

Blog

  1. Motyw graficzny
  2. Nowe responsywne menu
  3. Podsumowanie 2023 roku

MongoDB

  1. Jak skasować kolekcję?
  2. Jak sprawdzić status?

Swift

  1. Optional
  2. Funkcje
  3. Range
  4. Closure
  5. Struktury
  6. Computed property
  7. Property Observers
  8. Klasy
  9. Protokoły
  10. Kontrola dostępu
  11. Extension
  12. Swift: Enumeracje

Komiksy:

  1. Code smells
  2. Go live rule
  3. Big picture
  4. Recursion
  5. Eat that frog!
  6. Hate and Love
  7. The Comfort Zone
  8. Coding rules
  9. Face the problem

Swift: Enumeracje

Opublikowano: 28.12.2023 - tagi: Swift Typ Enumeracja

Enumeracja

Enumeracja to zbiór wartości zgrupowanych w typie zdefiniowanym przez użytkownika. W Swift enumerację tworzy się za pomocą słowa kluczowego: enum:

enum TimerState {
	case start, pause, stop
}

Przy pomocy case określasz jakie wartości będzie mieć Twoja enumeracja.

Przykład:

enum TimerState {
	case start, pause, stop
}

var timerState: TimerState = .start

print("timer state: \(timerState)") // start

Zauważ, że opcja start ma wartość... start. Jest to domyślne zachowanie.

Możesz jednak nadać opcji inną wartość niż ta domyślna. To tzw.: surowe wartości (ang.: raw values)

Surowe wartości

enum ClothesSize: String {
	case S = "Small"
	case M = "Medium"
	case L = "Large"
}

var size: ClothesSize = .M

print(size) // M
print(size.rawValue) // Medium

Dla enumeracji ClothesSize zostały zdefiniowane trzy opcje. Do każdej opcji przypisane są wartości: Small, Medium, Large. To są właśnie wartości surowe.

Żeby się do nich dostać, użyj właściwości rawValue.

Opcjom enumeracji możesz nadać typ:

enum ClothesSize: Int {
	case S, M, L
}

Jaką surową wartość będzie mieć opcja S? Będzie to 0, a kolejne 1 i 2.

Możesz też napisać tak:

enum ClothesSize: Int {
	case S = 1, M, L
}

print(ClothesSize.S.rawValue) // 1

Swift "domyśli" się, że kolejne wartości będą to 2 i 3.

Iteracja po enum

Możesz także iterować po wszystkich opcjach enumeracji. Żeby to zrobić, musisz rozszerzyć enumerację za pomocą protokołu: CaseIterable:

enum TimerState: CaseIterable {
	case start, pause, stop
}

for current in TimerState.allCases {
  print(current)
}
// start
// pause
// stop

Żeby iterować po enumeracji, użyj właściwości allCases.

Możesz także iterować po surowych wartościach:

enum ClothesSize: String, CaseIterable {
	case S = "Small"
	case M = "Medium"
	case L = "Large"
}

for current in ClothesSize.allCases {
  print(current.rawValue)
}
// Small
// Medium
// Large

Switch i enum

Do obsługi opcji możesz użyć instrukcji switch:

enum TimerState {
	case start, pause, stop
}

var timerState: TimerState = .pause

switch timerState {
	case .start:
		print("Start timer")
	
	case .pause:
		print("Pause timer")

	case .stop:
		print("Stop timer")
}

// Pause timer

Właściwości w enum

W enumeracji możesz użyć computed property:

enum TimerState {
	case start, pause, stop
	
	var label: String {
		switch self {
			case .start:
				return "Timer s running"
				
			case .pause:
				return "Timer is paused"
				
			case .stop:
				return "Timer is stopped"
		}
	}
}

var timerState: TimerState = .start

print(timerState.label) // Timer is running

Za pomocą słowa kluczowego self pobierasz wartość, która przechowuje zmienna przy wywołaniu label.

Metody w enum

Swift umożliwia także używanie metod w enum:

enum TimerState {
	case start, pause, stop
	
	func getLabel() -> String {
		switch self {
			case .start:
				return "Timer s running"
				
			case .pause:
				return "Timer is paused"
				
			case .stop:
				return "Timer is stopped"
		}
	}
}

var timerState: TimerState = .stop

print(timerState.getLabel()) // Timer is stopped

Powiązane wartości

Enumeracja pozwala dołączyć do każdej opcji dodatkowe informacje. Nazywa się to: powiązane wartości (ang.: associated values).

Składnia wygląda następująco:

case someOption(Int)

Po podaniu nazwy opcji w nawiasach określasz dodatkową informację. Możesz dodać wiele opcji:

case someOption(Int, Int, String)

Dla jednego parametru możesz określić jakiś typ danych, a dla następnego użyć innego typu. Dodatkowo opcje mogą mieć różną liczbę parametrów:

case someOption(Int)
case otherOption(String, Double)

Przykład:

enum TimerState {
	case start(String)
	case pause(String)
	case stop(String)
}

var timerState: TimerState = .start("Timer is starting")

switch timerState {
	case .start(let label): 
		print("Label for start: \(label)")
		
	case .pause(let label): 
		print("Label for pause: \(label)")
		
	case .stop(let label): 
		print("Label for stop: \(label)")	
}

Możesz także nadać etykiety powiązanym wartościom:

case someOption(value: Int)

Kolejny przykład:

enum ClothesSize {
	case S(height: Int)
	case M(height: Int)
	case L(height: Int)
}

var size: ClothesSize = .S(height: 165)

switch size {
 case .S(let height):
   print("Height for S:", height)
   
 case .M(let height):
   print("Height for M:", height)
   
 case .L(let height):
   print("Height for L:", height)  
}

Nie możesz używać powiązanych wartości wraz z surowymi wartościami, w tym samym czasie.


React Testing Library: Klawiatura

Opublikowano: 14.12.2023 - tagi: JavaScript React Testowanie Test Klawiatura

Testowanie klawiatury

Do symulacji obsługi klawiatury posłuży nam niezawodna biblioteka user-event.

Załóżmy, że mam zwykłe pole tekstowe. Po wpisaniu danych i wciśnięciu przycisku Enter wartość powinna zostać dodana do listy.

Przykład:

import { useState } from "react";

export function MyComponent() {
    const [tasks, setTasks] = useState([]);
    const [task, setTask] = useState('');

    const onChangeTask = (e) => {
        setTask(e.target.value)
    };

    const onAddTask = (e) => {
        if (e.code == 'Enter' && task) {
            setTasks([task, ...tasks]);
            setTask('');
        }
    }

    return (
        <>
            <div>
                <label htmlFor="newTask">Task title:</label>
                <input
                    type="text"
                    id="newTask"
                    value={task}
                    onChange={onChangeTask}
                    onKeyDown={onAddTask}
                />
            </div>
            <ul>
                {
                    tasks.map((task, index) => (
                        <li key={index}>
                            {task}
                        </li>
                    ))
                }
            </ul>
        </>
    )
}

Test:

import {render, screen, within} from '@testing-library/react';
const { getByLabelText, getByTestId } = screen;

const renderComponent = () => {
    render(<MyComponent />);

    const addTaskField = getByLabelText('Task title:');
    const taskList = within(getByTestId('task-list'));
    const addTask = async (newTask) => {
        await userEvent.clear(addTaskField)
        await userEvent.type(addTaskField, newTask);
        await userEvent.keyboard('[Enter]');
    }

    return {
        addTaskField,
        taskList,
        addTask
    }
}

test('should add new task to the list', async () => {
    // given
    const { taskList, addTask } = renderComponent();

    // when
    await addTask('My task');

    // then
    expect(taskList.getByText('My task'));
});

Za dodanie zadania do listy odpowiedzialna jest w tym teście funkcja addTask. Wywołana jest tam funkcja keyboard z biblioteki user event, która w tym przypadku symuluje wciśnięcie przycisku Enter na klawiaturze.


Podsumowanie: Listopad 2023

Opublikowano: 30.11.2023 - tagi: Blog Podsumowanie Listopad 2023

We listopadzie opublikowałem 6 wpisów:


Swfit

  1. Klasy
  2. Protokoły
  3. Kontrola dostępu
  4. Extension

Narysowałem dwa komiksy:

  1. Coding rules
  2. Face the problem

Przeczytałem dwie książki:

  1. Outpost 2 — Dmitry Glukhovsky
  2. Dawno temu w Warszawie — Jakub Żulczyk

Przesłuchałem pięć audiobooki:

  1. Rozjemca — Brandon Sanderson
  2. Powróceni — Abdulrazak Gurnah
  3. Zło ze wschodu — Andrzej Pilipiuk
  4. Legion — Elżbieta Cherezińska
  5. Ziemiomorze. Czarnoksiężnik z Archipelagu — Ursula K. Le Guin

Comics: Face the problem

Opublikowano: 23.11.2023 - tagi: Komiks Rysowanie

Face the problem