Swift: Range

Opublikowano: 29.08.2023 - tagi: Swift Zakres

Do czego służy Range?

Swift pozwala na tworzenie zakresu liczbowego od...do za pomocą operatora: ....

Przykład:

var range = 1...10

W tym przypadku stworzony został zakres od 1 do 10.

Zakres można wykorzystać na przykład w pętli:

for i in 1...10 {
	print(i)
}

Swift daje do ręki programiście trzy typy zakresu:

  1. Zamknięty
  2. Półotwarty
  3. Jednostronny

Zakres zamknięty

Ten typ zakresu określa jego początek i koniec. Wystarczy podać te dwie wartości:

a...b

Za pomocą first i last możesz dostać informację odpowiednio o początku i końcu zakresu:

var range = 1...10
print(range.first!) // 1
print(range.last!) // 10

Dzięki zakresowi możesz pobrać część danych ze zbioru danych:

let users = ["Greg", "Jane", "Spox", "Blue"]
let range  = 0...2
print(users[range]) // ["Greg", "Jane", "Spox"]

Zakres półotwarty

Zakres półotwarty określa zakres, który zawiera dane od a do b, ale bez b.

Składnia:

a..<b

Przykład:

var range = 1..<10
print(range.first!) // 1
print(range.last!) // 9

Zakres jednostronny

Jednostronny zakres definiuje wartość tylko z jednej strony zakresu:

a... lub ...b

Jeśli zdefiniujesz zakres tak:

let range = 10...

To zaczyna się od 10 i kończy na... plus nieskończoności (+∞)

Z kolei:

let range = ...10

Zaczyna się na minus nieskończoności (-∞) do 10.

Gdzie można taki zakres wykorzystać?

Na przykład w tablicach.

Załóżmy, że potrzebujesz pobrać wszystkie elementy tablicy, zaczynając od drugiego elementu:

let users = ["Greg", "Jane", "Spox", "Blue"]
print(users[1...]) // ["Jane", "Spox", "Blue"]

Albo, tylko pierwsze dwa elementy tablicy:

let users = ["Greg", "Jane", "Spox", "Blue"]
print(users[...1]) // ["Greg", "Jane"]

Swift: Funkcje

Opublikowano: 24.08.2023 - tagi: Swift Funkcje

Funkcje w Swift

Składania funkcji w Swift wygląda następująco:

func name() {
	...
}

Najpierw słowo kluczowe func, a następnie podajesz jej nazwę.

Wywołanie funkcji:

func helloWorld() {
	print("Hello World!)
}

helloWorld() // Hello World!

Parametry

Parametry funkcji są stałymi. To znaczy, że jeśli spróbujesz zmienić ich wartość, zostanie zgłoszony błąd.

Możesz zdefiniować parametry funkcji na różne sposoby:

Parametry z etykietą

func sayHello(name) {
	print("Hello \(name)!")
}

Jeśli tak deklarujesz parametry funkcji, musisz podać nazwę etykiety argumentu przy wywołaniu:

sayHello(name: "Anna")

Nie możesz napisać tak:

sayHello("Anna")

Parametry i typ danych

Możesz określić typ danych parametrów:

func calculate(a: Int, b: Int) {
	print(a + b)
}

Parametry bez etykiet

Jeśli nie chcesz używać etykiet dla argumentów, to przed nazwą parametru użyj _:

func sayHello(_ name: String) {
	print("Hello \(name)!")
}

sayHello("Anna") // Hello Anna!

Domyślne wartości parametrów

Do funkcji można przekazywać domyślne wartości:

func calculate(a: Int = 1, b: Int = 2) {
	print(a + b)
}

Wywołanie:

calculate() // 3

calculate(a: 9, b: 3) // 12

calculate(a: 8) // 10

Parametry typu in-out

Jak już wyżej wspomniałem: nie można zmieniać wartości parametrów w ciele funkcji. Jeśli spróbujesz to zrobić, zostanie zgłoszony błąd.

Jeśli jednak koniecznie potrzebujesz zmienić wartość parametru, oznacz go jako: inout. Dodatkowo w momencie wywołania funkcji przed nazwą argumentu należy użyć: &.

Przykład:

func increment(_ counter: inout Int) {
	counter += 1
}

var counter = 0

print(counter) // 0

increment(&counter)

print(counter) // 1

Parametr funkcja

Możesz do funkcji przekazać inną funkcję

func sum(_ a: Int, _ b: Int) {
	print(a + b)
}

func substract(_ a: Int, _ b: Int) {
	print(a - b)
}

func calculate(_ operation: (Int, Int) -> Void, _ a: Int, _ b: Int) {
	operation(a, b)
}

calculate(sum, 1, 1) // 2
calculate(substract, 1, 1) // 0

Zwracanie danych

Możesz określić typ danych, jaki zwraca funkcja za pomocą: return. Dzięki -> określasz typ zwracanych danych.

Zwracania jednej wartości

func calculate(a: Int, b: Int) -> Int {
	return a + b
}

let result: Int = calculate(a: 5, b: 7)

print(result) // 12

Zwracanie wielu wartości

Swift pozwala na zwrócenie wielu wartości. Taka funkcja zwróci krotkę (ang.: Tuple).

func prepare(_ name: String) -> (greet: String, goodbye: String) {
	let greet: String = "Hello \(name)!"
	let goodbye: String = "Bye \(name)!"
	
	return (greet, goodbye)
}

let result = prepare("Marcin")

print(result.greet) // Hello Marcin!
print(result.goodbye) // Bye Marcin!

Zwracanie funkcji

Możesz zwrócić funkcję jako wynik działania innej funkcji.

func sum(_ a: Int, _ b: Int) -> Int {
	return a + b
}

func substract(_ a: Int, _ b: Int) -> Int {
	return a - b
}
	
func defaultOperate(_ a: Int, _ b: Int) -> Int {
	return 0
}
	
func prepare(_ op: String) -> (Int, Int) -> Int {
	if op == "+" {
	    return sum
	} else if op == "-" {
	    return substract
	}
	
	return defaultOperate
}

let sumOperate = prepare("+")
print(sumOperate(0, 1)) // 1

let substractOperate = prepare("-")
print(substractOperate(0, 1)) // -1

Zagnieżdżone funkcje

Swift pozwala także na zagnieżdżone funkcje:

func calculate(_ a: Int, _ b: Int, _ op: String) -> Int {
  func sum(_ a: Int, _ b: Int) -> Int {
	  return a + b
  }

  func substract(_ a: Int, _ b: Int) -> Int {
	  return a - b
  }
	
  if op == "+" {
   return sum(a, b)
  } else if op == "-" {
    return substract(a, b)
  }
	
  return 0
}

print(calculate(0, 1, "+")) // 1

print(calculate(0, 1, "-")) // -1

MongoDB: Jak sprawdzić status?

Opublikowano: 19.08.2023 - tagi: MongoDB Baza danych Komenda Status Stan

Czy Mongo działa?

Żeby sprawdzić status MongoDB, wystarczy uruchomić komendę:

Dla wersji Mongo < 2.6:

sudo service mongodb status

lub:

Dla wersji Mongo >= 2.6:

sudo service mongod status

Status

Jeśli działa w odpowiedzi dostaniesz:

● mongod.service - MongoDB Database Server
   Loaded: loaded (/lib/systemd/system/mongod.service; disabled; vendor preset: enabled)
   Active: active (running) since Fri 2023-08-18 01:50:08 EDT; 18s ago
     Docs: https://docs.mongodb.org/manual
 Main PID: 4585 (mongod)
   CGroup: /system.slice/mongod.service
           └─4585 /usr/bin/mongod --config /etc/mongod.conf

A jeśli nie działa to:

● mongod.service - MongoDB Database Server
     Loaded: loaded (/lib/systemd/system/mongod.service; disabled; vendor preset: enabled)
     Active: inactive (dead)
       Docs: https://docs.mongodb.org/manual

Swift: Optional

Opublikowano: 17.08.2023 - tagi: Swift Optional

Czym jest Optional?

Swift daje programiście do ręki typ danych o nazwie Optional, który służy do przechowania jakiejś wartości lub nic (nil). Ten typ można porównać do pudełka, które może coś posiadać lub będzie puste.

Jest to przydatne szczególnie wtedy, gdy nie jesteśmy pewni, czy do zmiennej przypisana zostania jakaś wartość.

Domyślną wartością dla Optional jest nil — co oznacza brak wartości.

Jeśli zmienna oznaczona jako Optional ma wartość, jest ona opakowana przez typ Optional.

Jak stworzyć Optional?

Typ Optional można stworzyć na kilka sposobów:

var a: Optional<String> = "Test 1"
var b: String? = "Test 2"
var c: String! = "Test 3"
var d: String?
var e: String!

print(a) // Optional("Test 1")
print(b) // Optional("Test 2")
print(c) // Optional("Test 3")
print(d) // nil
print(e) // nil

Jak widać każda zmienna, która nie jest nil — która ma wartość, jest opakowana w Optional. Jak dostać się do tej wartości?

Jak pobrać wartość z Optional?

String i Optional (lub: String?) to dwa różne typy danych! Na Optional powinieneś patrzeć, jak na kontener, który może coś zawierać bądź nie (nil).

Dostęp do wartości Optional

Jeśli zmienna/stała przechowuje nil dostęp do niej łatwy. Żeby wyłuskać wartość z Optional, możesz napisać:

var a: String? = "Test 1"
print(a!) // Test 1

Zauważ, że jeśli napiszesz:

var a: String? = "Test 1"
print(a) // Optional<Test 1>

masz dostęp do Optional, które zawiera wartość.

Optional rozpakowany

Taki zapis:

var a: String! = "Test 1"
print(a) // Test 1

sprawia, że Optional zostanie stworzony. Ale zauważ, żeby pobrać wartość, nie musisz już użyć !.

Z takim zapisem należy uważać:

var a: String!
print(a.count)

W tym przypadku program się wysypie. Ponieważ a jest nil. Dlatego, zanim to użyjesz, warto mieć pewność, że zmienna posiada wartość.

Inny przykład:

var a: String!
var b: String = a

W momencie przypisania a do b program także przestanie działać. Dzieje się tak dlatego, bo a jest nil. Przy próbie przypisania tego do b powoduje błąd. Próba przypisania nil do zmiennej, która nie jest Optional spowoduje błąd.

Jak poradzić sobie z takimi sytuacjami?

Czy Optional ma wartość?

Istnieje kilka sposób na sprawdzenie, czy Optional posiada wartość. Poniżej lista:

Instrukcja if

var a: String?

if a != nil {
  print(a)
}

Instrukcja if-let

var a: String?

if let tempA = a {
  print(tempA)
}

Tutaj tworzona jest zmienna tymczasowa: tempA. Jeśli a nie jest nil do tempA przypisana jest wartość i warunek jest spełniony.

Instrukcja guard

var a: String?

guard a {
  return
}

print(a!)

Operator ??

var a: String?

print(a ?? '')

Operator ?? spróbuje pobrać wartość z a. Jeśli jest to nil, zwróci to co podałeś po prawej stronie operatora. W tym przypadku pusty ciąg znaków.


React Testing Library: Jak zasymulować kliknięcie w element?

Opublikowano: 10.08.2023 - tagi: JavaScript React Testowanie Komponent Mysz Zdarzenie

Biblioteka

W tym wpisie podam przykład symulacji kliknięcia za pomocą biblioteki user-event.

Zanim zaczniemy, upewnij się, że masz ją zainstalowaną.

Instalacja

Żeby zainstalować, wywołaj:

npm install --save-dev @testing-library/user-event

Podstawy

Aby zacząć korzystać z user-event, musisz spełnić dwa warunki.

Pierwszy warunek: oznacz test jako asynchroniczny za pomocą async:

test('should ...', async () => {
    ...
});

Drugi warunek: wywołaj metodę setup:

import userEvent from '@testing-library/user-event';

test('should ...', async () => {
    const user = userEvent.setup();
});

Przykład

Komponent:

import {useState} from "react";

export function MyComponent() {
    const [state, setState] = useState(0);

    return (
        <>
            <div>
                {state}
            </div>
            <div>
                <button onClick={() => setState((prevState: number) => prevState + 1)}>Increment</button>
                <button onClick={() => setState((prevState: number) => prevState - 1)}>Decrement</button>
            </div>
        </>
    )
}

Testy:

import {render, screen} from '@testing-library/react'
import userEvent from '@testing-library/user-event';
import {MyComponent} from "./MyComponent";

const { getByRole, getByText } = screen;

test('should increment counter', async () => {
    // given
    const user = userEvent.setup();
    render(<MyComponent />);
    const btnIncrement = getByRole('button', { name: "Increment"});

    // when
    await user.click(btnIncrement);

    // then
    expect(getByText('1')).toBeInTheDocument();
});

test('should decrement counter', async () => {
    // given
    const user = userEvent.setup();
    render(<MyComponent />);
    const btnDecrement = getByRole('button', { name: "Decrement"});

    // when
    await user.click(btnDecrement);

    // then
    expect(getByText('-1')).toBeInTheDocument();
});