From 81640d24ed325c6a7122687bd390678b6fa42a3b Mon Sep 17 00:00:00 2001 From: Oliver Davies <339813+opdavies@users.noreply.github.com> Date: Sat, 14 Mar 2020 23:39:56 +0000 Subject: [PATCH] Run prettier --- dist/getting-your-data-into-drupal-8/todo.md | 3 +- .../slides.md | 200 +++++++-------- src/drupal-testing-workshop/slides.md | 107 ++++---- .../notes.md | 50 ++-- .../taking-flight-tailwind-css.md | 170 ++++++------ src/test-driven-drupal/slides.md | 241 ++++++++---------- src/test-driven-drupal/todo.md | 1 - .../slides.md | 63 ++--- 8 files changed, 398 insertions(+), 437 deletions(-) diff --git a/dist/getting-your-data-into-drupal-8/todo.md b/dist/getting-your-data-into-drupal-8/todo.md index 7e48d68..c4dead5 100644 --- a/dist/getting-your-data-into-drupal-8/todo.md +++ b/dist/getting-your-data-into-drupal-8/todo.md @@ -1,4 +1,5 @@ - Demonstrate plugins - Writing own source/process plugins - Core source plugins (Drupal to Drupal) -- Demo `hook_migrate_prepare_row()` and `hook_migrate_MIGRATION_ID_prepare_row()` +- Demo `hook_migrate_prepare_row()` and + `hook_migrate_MIGRATION_ID_prepare_row()` diff --git a/src/deploying-drupal-ansible-ansistrano/slides.md b/src/deploying-drupal-ansible-ansistrano/slides.md index af5c57b..e256545 100644 --- a/src/deploying-drupal-ansible-ansistrano/slides.md +++ b/src/deploying-drupal-ansible-ansistrano/slides.md @@ -1,14 +1,11 @@ -autoscale: true -build-lists: true -code: line-height(1.2) -header-emphasis: #53B0EB -text: alignment(left) -theme: simple, 8 +autoscale: true build-lists: true code: line-height(1.2) header-emphasis: +#53B0EB text: alignment(left) theme: simple, 8 # [fit] **Deploying PHP applications**
using Ansible, Ansible Vault
and Ansistrano -^ I work primarily with PHP, and there will be some PHP-isms in this talk (LAMP stack, Composer). -Will be using a Drupal 8 application as the example, but the tools are tool and language agnostic. +^ I work primarily with PHP, and there will be some PHP-isms in this talk (LAMP +stack, Composer). Will be using a Drupal 8 application as the example, but the +tools are tool and language agnostic. --- @@ -18,14 +15,13 @@ Will be using a Drupal 8 application as the example, but the tools are tool and ## **What we'll be looking at** -* **Ansible** crash course -* Keeping secrets with **Ansible Vault** -* Deployments with **Ansistrano** +- **Ansible** crash course +- Keeping secrets with **Ansible Vault** +- Deployments with **Ansistrano** --- -[.build-lists: false] -[.header: #111111] +[.build-lists: false][.header: #111111] ![right 500%](../images/me-phpnw-inviqa.jpg) @@ -37,31 +33,28 @@ Will be using a Drupal 8 application as the example, but the tools are tool and - @opdavies - www.oliverdavies.uk -^ Maintain Drupal modules, PHP CLI tools and libraries, Ansible roles -Blog on my website -I work primarily with Drupal and Symfony -I work for Inviqa, but this based on my personal and side projects. -I've been using Ansible for a number of years, initially only for provisioning and setting up my laptop, and later for application deployments +^ Maintain Drupal modules, PHP CLI tools and libraries, Ansible roles Blog on my +website I work primarily with Drupal and Symfony I work for Inviqa, but this +based on my personal and side projects. I've been using Ansible for a number of +years, initially only for provisioning and setting up my laptop, and later for +application deployments --- ![350% inline](images/logo-platformsh.png) -![150% inline](images/logo-acquia.png) -![130% inline](images/logo-pantheon.png) +![150% inline](images/logo-acquia.png) ![130% inline](images/logo-pantheon.png) -^ Large, well-known managed hosting companies -Optimised servers for PHP/Drupal applications -Include some sort of deployment system -This workflow doesn't apply to this scenario +^ Large, well-known managed hosting companies Optimised servers for PHP/Drupal +applications Include some sort of deployment system This workflow doesn't apply +to this scenario --- -![100%](images/logo-digital-ocean.png) -![30%](images/logo-linode.png) +![100%](images/logo-digital-ocean.png) ![30%](images/logo-linode.png) ![30%](images/logo-vultr.png) -^ More applicable to virtual or dedicated servers with no existing deployment process -Not enough budget for fully-managed, or using internal infrastructure +^ More applicable to virtual or dedicated servers with no existing deployment +process Not enough budget for fully-managed, or using internal infrastructure This is where the this workflow would be useful --- @@ -82,17 +75,18 @@ This is where the this workflow would be useful ### **What is Ansible?** -* CLI tool -* Written in Python -* Configured with YAML -* Executes ad-hoc remote commands -* Installs software packages -* Performs deployment steps -* Batteries included +- CLI tool +- Written in Python +- Configured with YAML +- Executes ad-hoc remote commands +- Installs software packages +- Performs deployment steps +- Batteries included -^ Written in Python but you don't need to write or know Python to use it -Drupal, Symfony and a lot of other projects use YAML -First-party modules (SSH keys, file and directory management, package repositories, stopping/starting/restarting services, DO/Linode/AWS integration) +^ Written in Python but you don't need to write or know Python to use it Drupal, +Symfony and a lot of other projects use YAML First-party modules (SSH keys, file +and directory management, package repositories, stopping/starting/restarting +services, DO/Linode/AWS integration) --- @@ -100,15 +94,15 @@ First-party modules (SSH keys, file and directory management, package repositori ### **What is Ansible?** -* Hosts/Inventories -* Commands -* Playbooks -* Tasks -* Roles +- Hosts/Inventories +- Commands +- Playbooks +- Tasks +- Roles -^ Hosts: where your managed nodes/hosts are. Can be static or dynamic. -Commands: run from a control node onto managed nodes -Playbooks and Tasks: YAML representation of a series of commands/steps +^ Hosts: where your managed nodes/hosts are. Can be static or dynamic. Commands: +run from a control node onto managed nodes Playbooks and Tasks: YAML +representation of a series of commands/steps --- @@ -116,17 +110,16 @@ Playbooks and Tasks: YAML representation of a series of commands/steps ### **Why Ansible?** -* Familiar syntax -* Easily readable -* No server dependencies -* Easy to add to an existing project -* Includes relevant modules (e.g. Composer) -* Idempotency +- Familiar syntax +- Easily readable +- No server dependencies +- Easy to add to an existing project +- Includes relevant modules (e.g. Composer) +- Idempotency -^ Drupal 8, Symfony, Ansible all use YAML -Runs on any server with Python -Plugins into Drupal via CLI apps like Drush and Drupal Console -Changes are only made when needed (once) +^ Drupal 8, Symfony, Ansible all use YAML Runs on any server with Python Plugins +into Drupal via CLI apps like Drush and Drupal Console Changes are only made +when needed (once) --- @@ -175,7 +168,7 @@ webservers | SUCCESS => { --- -# `ansible all `
`-i hosts.yml `
`-m command `
`-a 'git pull `
`--chdir=/app'` +# `ansible all`
`-i hosts.yml`
`-m command`
`-a 'git pull`
`--chdir=/app'` --- @@ -206,7 +199,7 @@ webservers | SUCCESS => { --- -# `ansible-playbook `
`playbook.yml -i hosts.yml` +# `ansible-playbook`
`playbook.yml -i hosts.yml` --- @@ -313,7 +306,7 @@ ok: [webservers] TASK [geerlingguy.apache : Include OS-specific variables.] ************************************************************* ok: [webservers] -TASK [geerlingguy.apache : Include variables for Amazon Linux.] +TASK [geerlingguy.apache : Include variables for Amazon Linux.] skipping: [webservers] TASK [geerlingguy.apache : Define apache_packages.] ******************************************************************** @@ -444,9 +437,9 @@ $ANSIBLE_VAULT;1.1;AES256 ```yaml # vars/vars.yml --- -database_name: "{{ vault_database_name }}" -database_user: "{{ vault_database_user }}" -database_password: "{{ vault_database_password }}" +database_name: '{{ vault_database_name }}' +database_user: '{{ vault_database_user }}' +database_password: '{{ vault_database_password }}' ``` --- @@ -488,7 +481,7 @@ tasks: - name: Uploading application synchronize: - src: "{{ playbook_dir }}/../" + src: '{{ playbook_dir }}/../' dest: /app - name: Installing Composer dependencies @@ -501,9 +494,9 @@ tasks: # Disadvantages -* Single point of failure -* No ability to roll back -* Sensitive data stored in plain text +- Single point of failure +- No ability to roll back +- Sensitive data stored in plain text --- @@ -513,20 +506,19 @@ tasks: ![full inline](images/ansistrano.png) -^ Just another role, specifically for deployments -Ansible port of Capistrano +^ Just another role, specifically for deployments Ansible port of Capistrano --- # Features -* Multiple release directories -* Shared paths and files -* Customisable -* Multiple deployment strategies -* Multi-stage environments -* Prune old releases -* Rollbacks +- Multiple release directories +- Shared paths and files +- Customisable +- Multiple deployment strategies +- Multi-stage environments +- Prune old releases +- Rollbacks ^ rsync, Git, SVN etc @@ -544,7 +536,6 @@ Ansible port of Capistrano ```yaml # deploy.yml - --- - hosts: all @@ -557,14 +548,14 @@ Ansible port of Capistrano ```yaml # deploy.yml --- - # ... - vars: - project_deploy_dir: /app +# ... +vars: + project_deploy_dir: /app - ansistrano_deploy_to: '{{ project_deploy_dir }}' - ansistrano_deploy_via: git - ansistrano_git_branch: master - ansistrano_git_repo: 'git@github.com:opdavies/dransible' + ansistrano_deploy_to: '{{ project_deploy_dir }}' + ansistrano_deploy_via: git + ansistrano_git_branch: master + ansistrano_git_repo: 'git@github.com:opdavies/dransible' ``` --- @@ -673,10 +664,9 @@ drwxr-xr-x 9 4096 Jul 22 20:30 20190722203038Z ![inline 140%](images/ansistrano-flow.png) -^ Shared = files directory, logs -Before/after symlink shared = run tests -Symlink = 'current' symlink, site is live -Clean up = remove node_modules, database export, sqlite testing DB +^ Shared = files directory, logs Before/after symlink shared = run tests Symlink += 'current' symlink, site is live Clean up = remove node_modules, database +export, sqlite testing DB --- @@ -685,16 +675,19 @@ Clean up = remove node_modules, database export, sqlite testing DB --- # ... -ansistrano_after_symlink_shared_tasks_file: '{{ playbook_dir }}/deploy/after-symlink-shared.yml' -ansistrano_after_symlink_tasks_file: '{{ playbook_dir }}/deploy/after-symlink.yml' -ansistrano_after_update_code_tasks_file: '{{ playbook_dir }}/deploy/after-update-code.yml' +ansistrano_after_symlink_shared_tasks_file: + '{{ playbook_dir }}/deploy/after-symlink-shared.yml' +ansistrano_after_symlink_tasks_file: + '{{ playbook_dir }}/deploy/after-symlink.yml' +ansistrano_after_update_code_tasks_file: + '{{ playbook_dir }}/deploy/after-update-code.yml' release_web_path: '{{ ansistrano_release_path.stdout }}/web' release_drush_path: '{{ ansistrano_release_path.stdout }}/vendor/bin/drush' ``` -^ Each step has a 'before' and 'after' step -Ansistrano allows us to add more things by providing a path to a playbook and adding additional steps. +^ Each step has a 'before' and 'after' step Ansistrano allows us to add more +things by providing a path to a playbook and adding additional steps. --- @@ -722,7 +715,8 @@ Ansistrano allows us to add more things by providing a path to a playbook and ad # deploy/after-symlink.yml --- - name: Clear Drupal cache - command: '{{ release_drush_path }} --root {{ release_web_path }} cache-rebuild' + command: + '{{ release_drush_path }} --root {{ release_web_path }} cache-rebuild' ``` --- @@ -741,7 +735,7 @@ Ansistrano allows us to add more things by providing a path to a playbook and ad vars: # ... ansistrano_shared_paths: - - "{{ drupal_root }}/sites/default/files" + - '{{ drupal_root }}/sites/default/files' ``` --- @@ -786,15 +780,16 @@ vault_database_user: user vault_database_password: secret vault_hash_salt: dfgiy$fd2!34gsf2*34g74 ``` + --- ```yaml # vars/vars.yml --- -database_name: "{{ vault_database_name }}" -database_password: "{{ vault_database_password }}" -database_user: "{{ vault_database_user }}" -hash_salt: "{{ vault_hash_salt }}" +database_name: '{{ vault_database_name }}' +database_password: '{{ vault_database_password }}' +database_user: '{{ vault_database_user }}' +hash_salt: '{{ vault_hash_salt }}' ``` --- @@ -864,7 +859,9 @@ $base_url = '{{ item.1.settings.base_url }}'; - name: Create settings files template: src: settings.php.j2 - dest: '{{ item.0.drupal_root }}/sites/{{ item.1.name|default("default") }}/{{ item.1.filename|default("settings.php") }}' + dest: + '{{ item.0.drupal_root }}/sites/{{ item.1.name|default("default") }}/{{ + item.1.filename|default("settings.php") }}' with_subelements: - '{{ drupal_settings }}' - sites @@ -874,6 +871,7 @@ $base_url = '{{ item.1.settings.base_url }}'; --- # **Multiple environments** + ## Dev, test, production --- @@ -907,7 +905,7 @@ all: project_deploy_path: /app git_branch: master - drupal_hash_salt: "{{ vault_drupal_hash_salt }}" + drupal_hash_salt: '{{ vault_drupal_hash_salt }}' drupal_install: true drupal_settings: @@ -928,7 +926,7 @@ all: project_deploy_path: /app-test git_branch: develop - drupal_hash_salt: "{{ vault_drupal_hash_salt }}" + drupal_hash_salt: '{{ vault_drupal_hash_salt }}' drupal_install: true drupal_settings: diff --git a/src/drupal-testing-workshop/slides.md b/src/drupal-testing-workshop/slides.md index 7f23a21..ba0adcf 100644 --- a/src/drupal-testing-workshop/slides.md +++ b/src/drupal-testing-workshop/slides.md @@ -1,10 +1,5 @@ -autoscale: true -build-lists: true -header-emphasis: #3D85C6 -header: alignment(left) -text: alignment(left) -text-emphasis: #3D85C6 -theme: poster, 8 +autoscale: true build-lists: true header-emphasis: #3D85C6 header: +alignment(left) text: alignment(left) text-emphasis: #3D85C6 theme: poster, 8 code: Monaco, #6699FF, #999999, #6666FF, #66FF66, #66FF66, line-height(1.5) [.header: alignment(center)] @@ -12,6 +7,7 @@ code: Monaco, #6699FF, #999999, #6666FF, #66FF66, #66FF66, line-height(1.5) ![](../images/title.png) # [fit] Drupal Testing Workshop + ### _September 2018_ --- @@ -32,15 +28,16 @@ code: Monaco, #6699FF, #999999, #6666FF, #66FF66, #66FF66, line-height(1.5) - Drupal core requirement - __ - More important with regular D8 releases -^ Dave Liddament talk - better and cheaper to catch bugs earlier (e.g. whilst developing rather than after it's been released) -Refer to tests when writing implementation code -ONO merge conflict +^ Dave Liddament talk - better and cheaper to catch bugs earlier (e.g. whilst +developing rather than after it's been released) Refer to tests when writing +implementation code ONO merge conflict --- [.header: alignment(center)] ## [fit] _Having tests does not mean_ + ## [fit] there will be no bugs --- @@ -48,6 +45,7 @@ ONO merge conflict [.header: alignment(center)] ## [fit] _Testing may add time now_ + ## [fit] but save more time in the future --- @@ -68,7 +66,7 @@ ONO merge conflict - PHP class with _.php_ extension - _tests/src_ directory within each module -- Within the *Drupal\Tests\module_name* namespace +- Within the _Drupal\Tests\module_name_ namespace - Class name must match the filename - Namespace must match the directory structure - One test class per feature @@ -79,6 +77,7 @@ ONO merge conflict --- ### _Exercise 1_ + ## Local site setup --- @@ -109,11 +108,13 @@ ONO merge conflict --- ### _Exercise 2_ + ## Running Tests --- ### _Option 1_ + ## Simpletest module (UI) --- @@ -147,6 +148,7 @@ ONO merge conflict --- ### _Option 2_ + ## Command line --- @@ -181,7 +183,7 @@ cd web/core --- -## Pro-tip: Add paths to _$PATH_ +## Pro-tip: Add paths to _\$PATH_ ```bash # ~/.zshrc @@ -196,6 +198,7 @@ export PATH=node_modules/.bin:$PATH --- ### _Option 2_ + ## CLI with Docksal --- @@ -223,6 +226,7 @@ cd web/core --- ### _Option 3_ + ## Docksal PHPUnit addon --- @@ -234,8 +238,7 @@ cd web/core - Copies a stub phpunit.xml file if exists, or duplicates phpunit.xml.dist - Shorter command, combines two actions -^ Checks for core/phpunit.xml on each test run -Will create one if is not present +^ Checks for core/phpunit.xml on each test run Will create one if is not present --- @@ -271,6 +274,7 @@ fin phpunit web/modules/contrib/examples/phpunit_example Copying /var/www/web/core/phpunit.xml.dist to /var/www/web/core/phpunit.xml. Please edit it's values as needed and re-run 'fin phpunit'. ``` + --- ``` @@ -290,6 +294,7 @@ OK (34 tests, 41 assertions) --- ### _Option 4_ + ## IDE/text editor integration --- @@ -317,8 +322,6 @@ OK (34 tests, 41 assertions) --- - - [.header: #3D85C6] ## Functional tests @@ -327,12 +330,12 @@ OK (34 tests, 41 assertions) - Easiest to start with - Provide most value -^ Less setup steps -No mocking etc. +^ Less setup steps No mocking etc. --- ### _Exercise_ + ## Let's write a
functional test --- @@ -357,7 +360,6 @@ type: module --- - ```php // ExampleFunctionalTest.php @@ -393,10 +395,8 @@ public function test_example_page_exists() { } ``` -^ Snake case test method names -Still works because it has the 'test' prefix -More readable than camel case? -Works with Simpletest/D7 +^ Snake case test method names Still works because it has the 'test' prefix More +readable than camel case? Works with Simpletest/D7 --- @@ -410,8 +410,7 @@ public function example_page_exists() { } ``` -^ Remove the prefix, use annotation -PHPUnit only +^ Remove the prefix, use annotation PHPUnit only --- @@ -541,6 +540,7 @@ OK (1 test, 3 assertions) --- ### _Exercise_ + ## Let's write a
kernel test --- @@ -692,6 +692,7 @@ OK (1 test, 5 assertions) --- ### _Exercise_ + ## Let's write a
unit test --- @@ -775,7 +776,6 @@ OK (1 test, 1 assertion) --- - ## _Test Driven Development_ - Write a failing test @@ -785,8 +785,8 @@ OK (1 test, 1 assertion) --- -[.background-color: #FFFFFF] -[.footer: https://github.com/foundersandcoders/testing-tdd-intro] +[.background-color: +#FFFFFF][.footer: https://github.com/foundersandcoders/testing-tdd-intro] [.footer-style: #2F2F2F] ![100%](../images/tdd-loop.png) @@ -804,8 +804,8 @@ OK (1 test, 1 assertion) --- ### _Exercise_ -## Let's build a blog using test driven development +## Let's build a blog using test driven development --- @@ -828,12 +828,14 @@ OK (1 test, 1 assertion) ## _Implementation_ - Use views module -- Do the mininum amount at each step, make no assumptions, let the tests guide us +- Do the mininum amount at each step, make no assumptions, let the tests guide + us - Start with functional test --- ### _Step 1_ + ## Create the module --- @@ -849,6 +851,7 @@ type: 'module' --- ### _Step 2_ + ## Ensure the blog page exists --- @@ -869,7 +872,6 @@ class BlogPageTest extends BrowserTestBase { --- - ```php public function testBlogPageExists() { $this->drupalGet('/blog'); @@ -880,7 +882,6 @@ public function testBlogPageExists() { --- - ``` There was 1 error: @@ -937,7 +938,7 @@ id: blog ``` 1) Drupal\Tests\tdd_blog\Functional\BlogPageTest::testBlogPageExists -Drupal\Core\Config\UnmetDependenciesException: Configuration objects provided +Drupal\Core\Config\UnmetDependenciesException: Configuration objects provided by tdd_blog have unmet dependencies: views.view.blog (node.type.article, node, views) @@ -945,7 +946,6 @@ have unmet dependencies: views.view.blog --- - ```yml,[.highlight: 1, 7-10] # tdd_blog.info.yml @@ -961,10 +961,9 @@ dependencies: --- - ``` 1) Drupal\Tests\tdd_blog\Functional\BlogPageTest::testBlogPageExists -Drupal\Core\Config\UnmetDependenciesException: Configuration objects provided +Drupal\Core\Config\UnmetDependenciesException: Configuration objects provided by tdd_blog have unmet dependencies: views.view.blog (node.type.article) ``` @@ -975,7 +974,6 @@ by tdd_blog have unmet dependencies: --- - ``` OK (1 test, 3 assertions) ``` @@ -993,11 +991,11 @@ OK (1 test, 3 assertions) --- ### _Step 3_ + ## Ensure only published articles are shown --- - ```php public function testOnlyPublishedArticlesAreShown() { // Given I have a mixture of published and unpublished articles, @@ -1012,11 +1010,11 @@ public function testOnlyPublishedArticlesAreShown() { --- ### _Option 1_ + ## Functional tests --- - ```php // modules/custom/tdd_blog/tests/src/Functional/BlogPageTest.php @@ -1043,11 +1041,11 @@ public function testOnlyPublishedArticlesAreShown() { --- ### _Option 2_ + ## Kernel tests --- - ```php namespace Drupal\Tests\tdd_blog\Kernel; @@ -1074,10 +1072,8 @@ public function testOnlyPublishedArticlesAreShown() { } ``` -^ Kernel test approach -Dropping down a level -No need for the brower, not asserting against HTML -Faster to run +^ Kernel test approach Dropping down a level No need for the brower, not +asserting against HTML Faster to run --- @@ -1156,7 +1152,8 @@ Failed asserting that actual size 2 matches expected size 1. --- ->- _There is no content type filter on the view_ +> - _There is no content type filter on the view_ + - Add the filter - Re-export and save the view @@ -1183,11 +1180,11 @@ OK (1 test, 6 assertions) --- ### _Step 4_ + ## Ensure the articles are ordered by date --- - ```php // modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php @@ -1202,7 +1199,6 @@ public function testArticlesAreOrderedByDate() { --- - ```php // modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php @@ -1232,7 +1228,6 @@ $this->createNode([ --- - ```php // modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php @@ -1267,7 +1262,6 @@ public function testArticlesAreOrderedByDate() { --- - ```php // modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php @@ -1281,7 +1275,6 @@ public function testArticlesAreOrderedByDate() { --- - ``` There was 1 failure: @@ -1346,14 +1339,14 @@ OK (1 test, 5 assertions) - Writing tests is an _investment_ - OK to _start small_, introduce tests gradually - Easier to _refactor_ -- Tests can pass, but things can _still be broken_. Tests only report on what they cover. +- Tests can pass, but things can _still be broken_. Tests only report on what + they cover. -^ Made me think about how I'm going to do something more starting to do it -Less cruft, only write code that serves a purpose -Spending time writing tests pays dividends later on -Start by introducing tests for new features or regression tests when fixing bugs -If you know things pass, then you can refactor code knowing if something is broken -Manual testing is still important +^ Made me think about how I'm going to do something more starting to do it Less +cruft, only write code that serves a purpose Spending time writing tests pays +dividends later on Start by introducing tests for new features or regression +tests when fixing bugs If you know things pass, then you can refactor code +knowing if something is broken Manual testing is still important --- diff --git a/src/having-fun-drupal-8-drupalorg-api/notes.md b/src/having-fun-drupal-8-drupalorg-api/notes.md index 19a5e2d..8f219ef 100644 --- a/src/having-fun-drupal-8-drupalorg-api/notes.md +++ b/src/having-fun-drupal-8-drupalorg-api/notes.md @@ -1,10 +1,10 @@ -# Having fun with Drupal 8, PHP libraries Drupal.org API +# Having fun with Drupal 8, PHP libraries Drupal.org API - Open slides - Open Chrome tabs - Open PhpStorm for all projects - Open Sequel Pro for both DBs - + Clear cache tables + - Clear cache tables - Start PHP server for each site - Start recording @@ -12,13 +12,13 @@ - Show in PhpStorm - Show readme with examples - + Run test.php + - Run test.php - Show query classes - + Not drupal coding standards (PSR-2) - + Explain laravel collections + - Not drupal coding standards (PSR-2) + - Explain laravel collections - Show entity classes - Show tests - + Show fake query classes + - Show fake query classes - Run tests ## Project statistics @@ -26,18 +26,18 @@ - Show /projects page - Show routing - Show ProjectController - + Using PHP 7 return types - + Explain dependency injection - + Explain about collection - + Explain render array - + Show how to change ordering + - Using PHP 7 return types + - Explain dependency injection + - Explain about collection + - Explain render array + - Show how to change ordering - Show ProjectRetriever - + More dependency injection - + Show services file + - More dependency injection + - Show services file - Show settings form - Add another module (Sophie's simple integrations?) - + See it loading on projects page - + See it cached + - See it loading on projects page + - See it cached ## Drupalversary @@ -45,18 +45,18 @@ - Show block - Show block form - Show accountretriever - + Highlight caching - + Services file - + Show cached items in the DB + - Highlight caching + - Services file + - Show cached items in the DB - Show routing - Show UserController - + More dependency injection - + Services file + - More dependency injection + - Services file - Show date parser - + Show drupalversary model + - Show drupalversary model - Show adding own username via form - + See it cached - + Show adding uid via form - + See it cached + - See it cached + - Show adding uid via form + - See it cached - Show Dries' because this year drupalversary has passed -- Try with attendee ID \ No newline at end of file +- Try with attendee ID diff --git a/src/taking-flight-with-tailwind-css/taking-flight-tailwind-css.md b/src/taking-flight-with-tailwind-css/taking-flight-tailwind-css.md index fe4b516..be435a3 100644 --- a/src/taking-flight-with-tailwind-css/taking-flight-tailwind-css.md +++ b/src/taking-flight-with-tailwind-css/taking-flight-tailwind-css.md @@ -1,5 +1,4 @@ -autoscale: true -theme: Plain Jane, 1 +autoscale: true theme: Plain Jane, 1 # **Taking Flight with
Tailwind CSS** @@ -36,10 +35,8 @@ Going to be using Tailwind 1.0 which was released recently (May 13th) # A **utility-first** CSS framework for rapidly building **custom designs**. -^ CSS utility class generator -PostCSS -Make different looking sites using the same class names -No "Tailwind looking site" like there is with Bootstrap +^ CSS utility class generator PostCSS Make different looking sites using the +same class names No "Tailwind looking site" like there is with Bootstrap --- @@ -47,11 +44,9 @@ No "Tailwind looking site" like there is with Bootstrap # Tailwind CSS is a **highly customizable**, **low-level** CSS framework -^ No components like Bootstrap or Bulma -Configure it per project -Extendable if needed via additional plugins -Avoids the need to name things prematurely -Can extract components if needed (reusability) +^ No components like Bootstrap or Bulma Configure it per project Extendable if +needed via additional plugins Avoids the need to name things prematurely Can +extract components if needed (reusability) --- @@ -59,8 +54,10 @@ Can extract components if needed (reusability) # Tailwind is more than a CSS framework, it's an engine for
**creating design systems**. -^ Good default values provided - colours, fonts, padding, widths -Designing with constraints. Using inline styles, every value is a magic number. With utilities, you're choosing styles from a predefined design system, which makes it much easier to build visually consistent UIs. +^ Good default values provided - colours, fonts, padding, widths Designing with +constraints. Using inline styles, every value is a magic number. With utilities, +you're choosing styles from a predefined design system, which makes it much +easier to build visually consistent UIs. --- @@ -106,15 +103,22 @@ Designing with constraints. Using inline styles, every value is a magic number. --- ## **Benefits** + - You aren't wasting time and energy inventing class names - Your CSS stops growing - Making changes feels safer -^ No more adding silly class names like sidebar-inner-wrapper just to be able to style something, and no more agonizing over the perfect abstract name for something that's really just a flex container. +^ No more adding silly class names like sidebar-inner-wrapper just to be able to +style something, and no more agonizing over the perfect abstract name for +something that's really just a flex container. -^ Using a traditional approach, your CSS files get bigger every time you add a new feature. With utilities, everything is reusable so you rarely need to write new CSS. +^ Using a traditional approach, your CSS files get bigger every time you add a +new feature. With utilities, everything is reusable so you rarely need to write +new CSS. -^ CSS is global and you never know what you're breaking when you make a change. Classes in your HTML are local, so you can change them without worrying about something else breaking. +^ CSS is global and you never know what you're breaking when you make a change. +Classes in your HTML are local, so you can change them without worrying about +something else breaking. --- @@ -219,8 +223,9 @@ Designing with constraints. Using inline styles, every value is a magic number. ## **To get the most out of Tailwind,
you really should install it via npm.** ^ - You can't customize Tailwind's default theme -- You can't use any directives like *@apply*, *@variants*, etc. -- You can't enable features like *group-hover* + +- You can't use any directives like _@apply_, _@variants_, etc. +- You can't enable features like _group-hover_ - You can't install third-party plugins --- @@ -244,9 +249,7 @@ Designing with constraints. Using inline styles, every value is a magic number. [.code-highlight: 2-7] ```css -# src/css/style.css - -@tailwind base; +#src/css/style.css @tailwind base; @tailwind components; @@ -277,8 +280,7 @@ Designing with constraints. Using inline styles, every value is a magic number. ## **Processing your CSS with Tailwind
with the build command** -^ Compile the generated CSS -Pass through PostCSS and Tailwind +^ Compile the generated CSS Pass through PostCSS and Tailwind --- @@ -288,19 +290,19 @@ Pass through PostCSS and Tailwind ```css .text-left { - text-align: left; + text-align: left; } .text-center { - text-align: center; + text-align: center; } .text-right { - text-align: right; + text-align: right; } .text-justify { - text-align: justify; + text-align: justify; } ``` @@ -317,9 +319,7 @@ Pass through PostCSS and Tailwind ```js const mix = require('laravel-mix') -mix.postCss('src/css/app.css', 'dist/css', [ - require('tailwindcss')() -]) +mix.postCss('src/css/app.css', 'dist/css', [require('tailwindcss')()]) ``` ^ PostCSS - useful if you're including other PostCSS plugins like PostCSS Nested @@ -331,8 +331,7 @@ const mix = require('laravel-mix') require('laravel-mix-tailwind') -mix.postCss('src/css/app.css', 'dist/css') - .tailwind() +mix.postCss('src/css/app.css', 'dist/css').tailwind() ``` --- @@ -341,13 +340,11 @@ mix.postCss('src/css/app.css', 'dist/css') - + My new website - + - - - + ``` @@ -359,10 +356,10 @@ mix.postCss('src/css/app.css', 'dist/css') # `npm run prod` - --- # **Interaction states** + ## hover, focus, group-hover, focus-within ^ Start to differ from inline styles @@ -371,9 +368,9 @@ mix.postCss('src/css/app.css', 'dist/css') # `.[state][separator][class]` -^ State = hover, focus, group focus, focus within -Separator = configurable, colon by default -Class = the same utility class that you would have used normally +^ State = hover, focus, group focus, focus within Separator = configurable, +colon by default Class = the same utility class that you would have used +normally --- @@ -594,11 +591,10 @@ colors: { ```js const mix = require('laravel-mix') -mix.postCss('src/css/site.css', 'dist/css') - .purgeCss({ - folders: ['templates'], - extensions: ['html', 'php', 'twig'] - }) +mix.postCss('src/css/site.css', 'dist/css').purgeCss({ + folders: ['templates'], + extensions: ['html', 'php', 'twig'], +}) ``` --- @@ -610,14 +606,14 @@ const mix = require('laravel-mix') require('laravel-mix-purgecss') -mix.postCss('src/css/site.css', 'dist/css') - .purgeCss({ - folders: ['templates'], - extensions: ['html', 'php', 'twig'] - }) +mix.postCss('src/css/site.css', 'dist/css').purgeCss({ + folders: ['templates'], + extensions: ['html', 'php', 'twig'], +}) ``` -^ Can be tricky using Drupal/WordPress as you don't know where the classes could be coming from, no generated output directory +^ Can be tricky using Drupal/WordPress as you don't know where the classes could +be coming from, no generated output directory --- @@ -631,9 +627,7 @@ mix.postCss('src/css/site.css', 'dist/css') # Could the duplication
**be moved elsewhere**? -^ Twig partials -Vue components -WordPress template parts +^ Twig partials Vue components WordPress template parts --- @@ -672,8 +666,8 @@ WordPress template parts } %} ``` -^ Move the duplicate markup into a partial, so there's only one version -Pass data in. +^ Move the duplicate markup into a partial, so there's only one version Pass +data in. --- @@ -689,9 +683,8 @@ a.btn:hover { } ``` -^ Use utilities as mixins -Copy classes from markup -Still re-using the same design system and constraints as before +^ Use utilities as mixins Copy classes from markup Still re-using the same +design system and constraints as before --- @@ -730,12 +723,13 @@ a.btn:hover { module.exports = { theme: { - extend: {} + extend: {}, }, plugins: [], - variants: {} + variants: {}, } ``` + --- [.code-highlight: 5-7] @@ -746,12 +740,12 @@ module.exports = { module.exports = { theme: { colors: { - inherit: 'inherit' + inherit: 'inherit', }, - extend: {} + extend: {}, }, plugins: [], - variants: {} + variants: {}, } ``` @@ -768,12 +762,12 @@ module.exports = { theme: { extend: { colors: { - inherit: 'inherit' - } - } + inherit: 'inherit', + }, + }, }, plugins: [], - variants: {} + variants: {}, } ``` @@ -790,10 +784,10 @@ module.exports = { prefix: '', important: false, theme: { - extend: {} + extend: {}, }, plugins: [], - variants: {} + variants: {}, } ``` @@ -818,12 +812,10 @@ module.exports = { module.exports = { theme: { - extend: {} + extend: {}, }, - plugins: [ - require('tailwindcss-list-reset')() - ], - variants: {} + plugins: [require('tailwindcss-list-reset')()], + variants: {}, } ``` @@ -841,13 +833,16 @@ module.exports = { ```js // index.js -module.exports = (variants) => ({ addUtilities }) => { - addUtilities({ - '.list-reset': { - listStyle: 'none', - padding: 0 - } - }, variants) +module.exports = variants => ({addUtilities}) => { + addUtilities( + { + '.list-reset': { + listStyle: 'none', + padding: 0, + }, + }, + variants, + ) } ``` @@ -874,10 +869,11 @@ module.exports = (variants) => ({ addUtilities }) => { --- # **Thanks!** + # opdavi.es/talks/tailwind + ## _@opdavies_
_oliverdavies.uk_ -^ Find this talk at opdavi.es/talks/tailwind -Follow me on Twitter -oliverdavies.uk where I blog about PHP, Drupal, Symfony, automated testing, Tailwind etc. -Subscribe to the RSS feed +^ Find this talk at opdavi.es/talks/tailwind Follow me on Twitter +oliverdavies.uk where I blog about PHP, Drupal, Symfony, automated testing, +Tailwind etc. Subscribe to the RSS feed diff --git a/src/test-driven-drupal/slides.md b/src/test-driven-drupal/slides.md index c47b447..036209d 100644 --- a/src/test-driven-drupal/slides.md +++ b/src/test-driven-drupal/slides.md @@ -1,11 +1,6 @@ -theme: poster, 8 -autoscale: true -build-lists: true -header-emphasis: #53B0EB -header: alignment(left) -text: alignment(left) -text-emphasis: #53B0EB -code: Monaco, #6699FF, #999999, #6666FF, #66FF66, #66FF66, line-height(1.3) +theme: poster, 8 autoscale: true build-lists: true header-emphasis: #53B0EB +header: alignment(left) text: alignment(left) text-emphasis: #53B0EB code: +Monaco, #6699FF, #999999, #6666FF, #66FF66, #66FF66, line-height(1.3) [.header: alignment(center)] @@ -41,10 +36,8 @@ code: Monaco, #6699FF, #999999, #6666FF, #66FF66, #66FF66, line-height(1.3) --- -[.background-color: #FFFFFF] -[.build-lists: false] -[.header: #111111] -[.text: #111111, alignment(left)] +[.background-color: #FFFFFF][.build-lists: false] [.header: +#111111][.text: #111111, alignment(left)] ![right 800%](../images/me-phpnw.png) @@ -57,9 +50,8 @@ code: Monaco, #6699FF, #999999, #6666FF, #66FF66, #66FF66, line-height(1.3) - @opdavies - www.oliverdavies.uk -^ Work at Microserve. -Maintain Drupal modules, PHP CLI tools and libraries -Blog on my website +^ Work at Microserve. Maintain Drupal modules, PHP CLI tools and libraries Blog +on my website --- @@ -74,8 +66,7 @@ Blog on my website --- -[.background-color: #FFFFFF] -[.text: #111111, alignment(left)] +[.background-color: #FFFFFF][.text: #111111, alignment(left)] ![right 100%](../images/microserve-light.png) @@ -89,10 +80,9 @@ Blog on my website [.header: alignment(center)] -## test_driven_drupal_.com_ +## test*driven_drupal*.com\_ -^ Book on automated testing in Drupal 8 -Building a conference website +^ Book on automated testing in Drupal 8 Building a conference website --- @@ -129,12 +119,13 @@ Building a conference website - Become maintainer in 2012 - Had some existing tests - Used on _11,046 sites_ in October 2012 (_84_ D5, _7,094_ D6, _3,868_ D7) -- Used on _30,572 sites_ in March 2019 (_10_ D5, _1,180_ D6, _24,057_ D7, _5,335_ D8) +- Used on _30,572 sites_ in March 2019 (_10_ D5, _1,180_ D6, _24,057_ D7, + _5,335_ D8) - _#230_ most used module on Drupal.org - Crucial to preventing regressions -^ Preventing regressions when adding new features or fixing bugs, but also user submitted patches -First module I ported to Drupal 8, aided by tests +^ Preventing regressions when adding new features or fixing bugs, but also user +submitted patches First module I ported to Drupal 8, aided by tests --- @@ -154,9 +145,9 @@ First module I ported to Drupal 8, aided by tests - Drupal core requirement - __ - More important with regular D8 releases -^ Dave Liddament talk - better and cheaper to catch bugs earlier (e.g. whilst developing rather than after it's been released) -Refer to tests when writing implementation code -ONO merge conflict +^ Dave Liddament talk - better and cheaper to catch bugs earlier (e.g. whilst +developing rather than after it's been released) Refer to tests when writing +implementation code ONO merge conflict --- @@ -164,7 +155,8 @@ ONO merge conflict - New features should be accompanied by automated tests. - If the feature does not have an implementation, provide a test implementation. -- Bug fixes should be accompanied by changes to a test (either modifying an existing test case or adding a new one) that demonstrate the bug. +- Bug fixes should be accompanied by changes to a test (either modifying an + existing test case or adding a new one) that demonstrate the bug. [.footer: https://opdavi.es/drupal-core-testing-gate] @@ -194,7 +186,7 @@ ONO merge conflict - PHP class with _.php_ extension - _tests/src_ directory within each module -- Within the *Drupal\Tests\module_name* namespace +- Within the _Drupal\Tests\module_name_ namespace - Class name must match the filename - Namespace must match the directory structure - One test class per feature @@ -206,7 +198,9 @@ ONO merge conflict [.header: alignment(center)] ## _1._ Arrange + ## _2._ Act + ## _3._ Assert --- @@ -214,7 +208,9 @@ ONO merge conflict [.header: alignment(center)] ## _3._ Assert + ## _2._ Act + ## _1._ Arrange --- @@ -239,11 +235,8 @@ class ExampleTest extends BrowserTestBase { } ``` -^ PHP class -Filename matches class name -Namespace matches directory structure -Extend BrowserTestBase -Add test method +^ PHP class Filename matches class name Namespace matches directory structure +Extend BrowserTestBase Add test method --- @@ -282,8 +275,8 @@ public function it_does_something() {} - What provides the most value to the client? - What would you not like to be fixing on a Friday afternoon or after hours? -^ Payments! Anything related to money. -What would provide the largest negative impact to the client if it were to fail? +^ Payments! Anything related to money. What would provide the largest negative +impact to the client if it were to fail? --- @@ -293,7 +286,6 @@ What would provide the largest negative impact to the client if it were to fail? --- - [.header: #53B0EB] ## What to test first? @@ -301,10 +293,9 @@ What would provide the largest negative impact to the client if it were to fail? - Write a _new test_ when adding any _new functionality_ - Write a _regression test_ when _fixing a bug_ -^ Use tests to replicate the bug -Could be a new test, or adding to an existing test -Test passes when the bug is fixed -That issue cannot be re-added without the test failing again +^ Use tests to replicate the bug Could be a new test, or adding to an existing +test Test passes when the bug is fixed That issue cannot be re-added without the +test failing again --- @@ -352,9 +343,8 @@ class JobTest extends UnitTestCase { } ``` -^ Within a Unit directory and namespace -Called JobTest because it's testing the Job class -Called testCreate because it's testing the create method +^ Within a Unit directory and namespace Called JobTest because it's testing the +Job class Called testCreate because it's testing the create method --- @@ -404,8 +394,7 @@ class JobTest extends UnitTestCase { } ``` -^ Retrieve data from the object with getters -Asssert that the data is correct. +^ Retrieve data from the object with getters Asssert that the data is correct. --- @@ -539,8 +528,8 @@ protected function setUp() { } ``` -^ Because it's a kernel test, we have access to the container -to get the AdvancedQueue processor service. +^ Because it's a kernel test, we have access to the container to get the +AdvancedQueue processor service. --- @@ -627,9 +616,7 @@ public function testProcessor() { - Slower to run - With/without JavaScript -^ testing profile -Functional/FunctionalJavascript -Nightwatch +^ testing profile Functional/FunctionalJavascript Nightwatch --- @@ -666,8 +653,8 @@ protected function setUp() { } ``` -^ We have the ability to place blocks -And create users with permissions and log them in +^ We have the ability to place blocks And create users with permissions and log +them in --- @@ -710,6 +697,7 @@ public function testQueueDeletion() { ``` --- + ```php, [.highlight: 12-14] // tests/src/Functional/QueueTest.php @@ -761,21 +749,25 @@ public function testQueueDeletion() { [.header: #FFFFFF, alignment(left)] ### _How do I know_ + ## Which type of test to use? --- ### _Need a browser?_ + ## Use a functional test --- ### _Interact with other services?_ + ## Use a kernel test --- ### _Isolated PHP code?_ + ## Use a unit test --- @@ -786,9 +778,9 @@ public function testQueueDeletion() { ## _Or should you test_
your render array to generate the block? -^ The answer might be 'both'. -The right type of test to use might not be that obvious. -You may be able to use a different type of test if you take a different approach. +^ The answer might be 'both'. The right type of test to use might not be that +obvious. You may be able to use a different type of test if you take a different +approach. --- @@ -876,8 +868,7 @@ statusCodeNotEquals() --- -[.background-color: #FFFFFF] -[.footer-style: #2F2F2F] +[.background-color: #FFFFFF][.footer-style: #2f2f2f] ![inline 150%](images/broadbean.png) @@ -892,7 +883,8 @@ statusCodeNotEquals() - Jobs need to be linked to offices - Job length specified in number of days - Path is specified as a field in the API -- Application URL constructed from domain, includes role ID as a GET parameter and optionally UTM parameters +- Application URL constructed from domain, includes role ID as a GET parameter + and optionally UTM parameters --- @@ -941,9 +933,10 @@ $data = [ - Added route to accept data from API as XML - Added system user with API role to authenticate -- *active_for* converted from number of days to UNIX timestamp -- *branch_name* and *locations* converted from plain text to entity reference (job node to office node) -- *url_alias* property mapped to *path* +- _active_for_ converted from number of days to UNIX timestamp +- _branch_name_ and _locations_ converted from plain text to entity reference + (job node to office node) +- _url_alias_ property mapped to _path_ --- @@ -954,8 +947,7 @@ $data = [ - If no error, create the job node, return OK response to Broadbean - If an Exception is thrown, return an error code and message -^ Required field missing -Incorrect branch name +^ Required field missing Incorrect branch name --- @@ -975,9 +967,12 @@ Incorrect branch name ## Types of tests - _Unit:_ ensure number of days are converted to timestamps correctly -- _Kernel:_ job nodes can be added and deleted, expired job nodes are deleted, application URL is generated correctly -- _Functional:_ job nodes are created with the correct URL and the correct response code is returned -- _FunctionalJavaScript:_ application URL is updated with JavaScript based on UTM parameters (hosting) +- _Kernel:_ job nodes can be added and deleted, expired job nodes are deleted, + application URL is generated correctly +- _Functional:_ job nodes are created with the correct URL and the correct + response code is returned +- _FunctionalJavaScript:_ application URL is updated with JavaScript based on + UTM parameters (hosting) --- @@ -998,6 +993,7 @@ Incorrect branch name --- ### _Option 1_ + ## SimpleTest module (UI) --- @@ -1031,6 +1027,7 @@ Incorrect branch name --- ### _Option 2_ + ## Core script --- @@ -1046,6 +1043,7 @@ $ php core/scripts/run-tests.sh --class ExampleTest --- ### _Option 3_ + ## PHPUnit --- @@ -1103,8 +1101,8 @@ fin addon install phpunit fin phpunit modules/custom ``` -^ Copies a stub phpunit.xml file or copies phpunit.xml.dist -Runs the phpunit command within the correct directory +^ Copies a stub phpunit.xml file or copies phpunit.xml.dist Runs the phpunit +command within the correct directory --- @@ -1133,8 +1131,8 @@ Runs the phpunit command within the correct directory --- -[.background-color: #FFFFFF] -[.footer: https://github.com/foundersandcoders/testing-tdd-intro] +[.background-color: +#FFFFFF][.footer: https://github.com/foundersandcoders/testing-tdd-intro] [.footer-style: #2F2F2F] ![100%](images/tdd-loop.png) @@ -1174,6 +1172,7 @@ Runs the phpunit command within the correct directory [.header: alignment(center)] ## [fit] _Building a new Drupal 8 Module with_ + ## [fit] test driven development --- @@ -1203,12 +1202,14 @@ Runs the phpunit command within the correct directory ## Implementation - Use views module -- Do the mininum amount at each step, make no assumptions, let the tests guide us +- Do the mininum amount at each step, make no assumptions, let the tests guide + us - Start with functional test --- ### _Step 1_ + ## Create the module --- @@ -1224,6 +1225,7 @@ type: 'module' --- ### _Step 2_ + ## Ensure the blog page exists --- @@ -1250,7 +1252,6 @@ class BlogPageTest extends BrowserTestBase { --- - ```php, [.highlight: 3] // tests/src/Functional/BlogPageTest.php @@ -1273,7 +1274,6 @@ class BlogPageTest extends BrowserTestBase { --- - ```php, [.highlight: 5-7] // tests/src/Functional/BlogPageTest.php @@ -1296,7 +1296,6 @@ class BlogPageTest extends BrowserTestBase { --- - ```php, [.highlight: 9] // tests/src/Functional/BlogPageTest.php @@ -1319,7 +1318,6 @@ class BlogPageTest extends BrowserTestBase { --- - ```php, [.highlight: 11-15] // tests/src/Functional/BlogPageTest.php @@ -1342,7 +1340,6 @@ class BlogPageTest extends BrowserTestBase { --- - ```bash, [.highlight: 1] docker@cli:/var/www/web$ ../vendor/bin/phpunit -c core modules/custom/tdd_blog PHPUnit 6.5.8 by Sebastian Bergmann and contributors. @@ -1367,7 +1364,6 @@ Tests: 1, Assertions: 3, Errors: 1. --- - ```bash, [.highlight: 4] docker@cli:/var/www/web$ ../vendor/bin/phpunit -c core modules/custom/tdd_blog PHPUnit 6.5.8 by Sebastian Bergmann and contributors. @@ -1392,7 +1388,6 @@ Tests: 1, Assertions: 3, Errors: 1. --- - ```bash, [.highlight: 5-13] docker@cli:/var/www/web$ ../vendor/bin/phpunit -c core modules/custom/tdd_blog PHPUnit 6.5.8 by Sebastian Bergmann and contributors. @@ -1417,7 +1412,6 @@ Tests: 1, Assertions: 3, Errors: 1. --- - ```bash, [.highlight: 14-16] docker@cli:/var/www/web$ ../vendor/bin/phpunit -c core modules/custom/tdd_blog PHPUnit 6.5.8 by Sebastian Bergmann and contributors. @@ -1442,7 +1436,6 @@ Tests: 1, Assertions: 3, Errors: 1. --- - ```bash, [.highlight: 18-19] docker@cli:/var/www/web$ ../vendor/bin/phpunit -c core modules/custom/tdd_blog PHPUnit 6.5.8 by Sebastian Bergmann and contributors. @@ -1542,7 +1535,6 @@ Tests: 1, Assertions: 0, Errors: 1. --- - ```yml,[.highlight: 1, 7-10] # tdd_blog.info.yml @@ -1558,7 +1550,6 @@ dependencies: --- - ```[.highlight: 10-13] docker@cli:/var/www/web$ ../vendor/bin/phpunit -c core modules/custom/tdd_blog PHPUnit 6.5.8 by Sebastian Bergmann and contributors. @@ -1593,7 +1584,6 @@ Tests: 1, Assertions: 0, Errors: 1. --- - ```[.highlight: 5, 9] docker@cli:/var/www/web$ ../vendor/bin/phpunit -c core modules/custom/tdd_blog PHPUnit 6.5.8 by Sebastian Bergmann and contributors. @@ -1619,11 +1609,11 @@ OK (1 test, 3 assertions) --- ### _Step 3_ + ## Ensure only published articles are shown --- - ```php public function testOnlyPublishedArticlesAreShown() { // Given I have a mixture of published and unpublished articles, @@ -1638,11 +1628,11 @@ public function testOnlyPublishedArticlesAreShown() { --- ### _Option 1_ + ## Functional tests --- - ```php,[.highlight: 1, 4-8] // modules/custom/tdd_blog/tests/src/Functional/BlogPageTest.php @@ -1668,7 +1658,6 @@ public function testOnlyPublishedArticlesAreShown() { --- - ```php,[.highlight: 10-12] // modules/custom/tdd_blog/tests/src/Functional/BlogPageTest.php @@ -1692,7 +1681,6 @@ public function testOnlyPublishedArticlesAreShown() { --- - ```php, [.highlight: 13-17] // modules/custom/tdd_blog/tests/src/Functional/BlogPageTest.php @@ -1717,11 +1705,11 @@ public function testOnlyPublishedArticlesAreShown() { --- ### _Option 2_ + ## Kernel tests --- - ```php namespace Drupal\Tests\tdd_blog\Kernel; @@ -1743,10 +1731,8 @@ class BlogPageTest extends EntityKernelTestBase { } ``` -^ Kernel test approach -Dropping down a level -No need for the brower, not asserting against HTML -Faster to run +^ Kernel test approach Dropping down a level No need for the brower, not +asserting against HTML Faster to run --- @@ -1819,7 +1805,6 @@ class BlogPageTest extends EntityKernelTestBase { --- - ```[.highlight: 9-16] docker@cli:/var/www/web$ ../vendor/bin/phpunit -c core modules/custom/tdd_blog/tests/src/Kernel/ PHPUnit 6.5.8 by Sebastian Bergmann and contributors. @@ -1844,7 +1829,6 @@ Tests: 1, Assertions: 2, Errors: 1. --- - ```php, [.highlight: 2] public function testOnlyPublishedArticlesAreShown() { $this->installConfig(['filter']); @@ -1857,7 +1841,6 @@ public function testOnlyPublishedArticlesAreShown() { --- - ```php, [.highlight: 8] public function testOnlyPublishedArticlesAreShown() { $this->installConfig(['filter']); @@ -1872,7 +1855,6 @@ public function testOnlyPublishedArticlesAreShown() { --- - ```php, [.highlight: 3] ... @@ -1894,7 +1876,6 @@ public function testOnlyPublishedArticlesAreShown() { --- - ```php, [.highlight: 6] ... @@ -1916,7 +1897,6 @@ public function testOnlyPublishedArticlesAreShown() { --- - ```php, [.highlight: 8-15] ... @@ -1936,13 +1916,11 @@ public function testOnlyPublishedArticlesAreShown() { } ``` -^ Assert -Should only be one result, should be node 2 -Node IDs are reset on each test method +^ Assert Should only be one result, should be node 2 Node IDs are reset on each +test method --- - ``` PHPUnit 6.5.8 by Sebastian Bergmann and contributors. @@ -1964,7 +1942,6 @@ Tests: 1, Assertions: 4, Failures: 1. --- - ```[.highlight: 8-13] PHPUnit 6.5.8 by Sebastian Bergmann and contributors. @@ -1990,7 +1967,8 @@ Tests: 1, Assertions: 4, Failures: 1. --- ->- _There is no content type filter on the view_ +> - _There is no content type filter on the view_ + - Add the filter - Re-export and save the view @@ -2024,11 +2002,11 @@ OK (1 test, 6 assertions) --- ### _Step 4_ + ## Ensure the articles are ordered by date --- - ```php // modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php @@ -2043,7 +2021,6 @@ public function testArticlesAreOrderedByDate() { --- - ```php, [.highlight: 4-9] // modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php @@ -2073,7 +2050,6 @@ $this->createNode([ --- - ```php, [.highlight: 10-11] // modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php @@ -2116,7 +2092,6 @@ public function testArticlesAreOrderedByDate() { --- - ```php, [.highlight: 5-9, 17-18] // modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php @@ -2141,7 +2116,6 @@ public function testArticlesAreOrderedByDate() { --- - ``` PHPUnit 6.5.8 by Sebastian Bergmann and contributors. @@ -2255,8 +2229,7 @@ OK (1 test, 5 assertions) ![fit](images/tdd-blog-installed.png) -^ Using the minimal installation profile -Post 3 is unpublished +^ Using the minimal installation profile Post 3 is unpublished --- @@ -2277,45 +2250,49 @@ Post 3 is unpublished - Writing tests is an _investment_ - OK to _start small_, introduce tests gradually - Easier to _refactor_ -- Tests can pass, but things can _still be broken_. Tests only report on what they cover. +- Tests can pass, but things can _still be broken_. Tests only report on what + they cover. -^ Made me think about how I'm going to do something more starting to do it -Less cruft, only write code that serves a purpose -Spending time writing tests pays dividends later on -Start by introducing tests for new features or regression tests when fixing bugs -If you know things pass, then you can refactor code knowing if something is broken -Manual testing is still important +^ Made me think about how I'm going to do something more starting to do it Less +cruft, only write code that serves a purpose Spending time writing tests pays +dividends later on Start by introducing tests for new features or regression +tests when fixing bugs If you know things pass, then you can refactor code +knowing if something is broken Manual testing is still important --- [.header: alignment(center)] ## [fit] _Having tests does not mean_ + ## [fit] there will be no bugs -^ Only means that the tests you wrote are passing -You may not have included a certain use case -Be sure to test in the UI! -We can test what happens in a test when a user has a permission, but in our site we still need to assign the permission to a role and the role to a user. +^ Only means that the tests you wrote are passing You may not have included a +certain use case Be sure to test in the UI! We can test what happens in a test +when a user has a permission, but in our site we still need to assign the +permission to a role and the role to a user. --- ### _You might be testing the wrong thing_ + ## Maybe it doesn't work the way you think it does --- ### _Have you written enough assertions?_ + ## Have you only covered the 'happy path' scenarios? -^ If your tests are passing but there is an issue, maybe you haven't written enough assertions -Be sure to check for the negative use cases too -Check that something is not included as well as what should be included -What if you pass in an incorrect value? +^ If your tests are passing but there is an issue, maybe you haven't written +enough assertions Be sure to check for the negative use cases too Check that +something is not included as well as what should be included What if you pass in +an incorrect value? --- ### _Other modules can affect things_ + ## Tests may pass, but fail when other modules are enabled --- @@ -2323,6 +2300,7 @@ What if you pass in an incorrect value? [.header: alignment(center)] ## [fit] _Testing may add time now_ + ## [fit] but save more time in the future --- @@ -2330,20 +2308,21 @@ What if you pass in an incorrect value? [.header: alignment(center)] ## [fit] _How do you get quicker at writing tests?_ + # [fit] By writing more tests -^ Practice makes perfect -Become more familar with and knowledge of recurring errors -Find better practices and approaches. Different base classes? Less setup steps. Less time, more productive. +^ Practice makes perfect Become more familar with and knowledge of recurring +errors Find better practices and approaches. Different base classes? Less setup +steps. Less time, more productive. --- ## _Start small_ + ## Some tests are better than no tests --- - [.background-color: #FFFFFF] ![140%](images/tawny-tweet-1.png) @@ -2371,5 +2350,7 @@ Find better practices and approaches. Different base classes? Less setup steps. [.header: alignment(center)] # Thanks + ### _@opdavies_ + ### _oliverdavies.uk_ diff --git a/src/test-driven-drupal/todo.md b/src/test-driven-drupal/todo.md index da818b0..b8c0252 100644 --- a/src/test-driven-drupal/todo.md +++ b/src/test-driven-drupal/todo.md @@ -1,3 +1,2 @@ - Show composer.json setup - Add "things you can test" and "things you shouldn't test" - diff --git a/src/using-laravel-collections-outside-laravel/slides.md b/src/using-laravel-collections-outside-laravel/slides.md index 3a522cf..9940e26 100644 --- a/src/using-laravel-collections-outside-laravel/slides.md +++ b/src/using-laravel-collections-outside-laravel/slides.md @@ -1,15 +1,8 @@ -theme: poster, 8 -autoscale: true -build-lists: true -header-emphasis: #53B0EB -header: alignment(left) -text: alignment(left) -text-emphasis: #53B0EB -code: Operator Mono, line-height(1.5) +theme: poster, 8 autoscale: true build-lists: true header-emphasis: #53B0EB +header: alignment(left) text: alignment(left) text-emphasis: #53B0EB code: +Operator Mono, line-height(1.5) -[.background-color: #FFFFFF] -[.hide-footer] -[.header: #111111, alignment(center)] +[.background-color: #FFFFFF][.hide-footer] [.header: #111111, alignment(center)] ## Using Laravel Collections...
Outside Laravel @@ -21,12 +14,11 @@ code: Operator Mono, line-height(1.5) ## Collections :thumbsup: -^ Became a fan of Collections whilst learning Laravel -Powerful object orientated way to interact with arrays -Store items within the collection, run methods, chainable -More readable, less temporary variables -Video on Laracasts, Adam Wathan's refactoring to Collections -Wanted to use them with different PHP projects e.g. Drupal +^ Became a fan of Collections whilst learning Laravel Powerful object orientated +way to interact with arrays Store items within the collection, run methods, +chainable More readable, less temporary variables Video on Laracasts, Adam +Wathan's refactoring to Collections Wanted to use them with different PHP +projects e.g. Drupal --- @@ -36,15 +28,13 @@ collect(['foo', 'bar']); // ['foo', 'bar'] collect('foobar'); // ['foobar'] $object = new stdClass(); -$object->foo = 'bar'; +$object->foo = 'bar'; collect($object); // ['foo' => 'bar'] collect($object)->get('foo'); // bar ``` -^ How do you make a collection? -collect function is provided -String, array or object -Stored as items within the Collection object +^ How do you make a collection? collect function is provided String, array or +object Stored as items within the Collection object --- @@ -68,10 +58,9 @@ $collection->filter(function ($item) { }); // [3, 4] ``` -^ Once you have a collection, what can you do with it? -"contains" - no more needle/haystack, haystack/needle -"filter" - filters false, null values -Can pass callbacks to `first` and `filter`, return true or false as needed. +^ Once you have a collection, what can you do with it? "contains" - no more +needle/haystack, haystack/needle "filter" - filters false, null values Can pass +callbacks to `first` and `filter`, return true or false as needed. --- @@ -96,12 +85,12 @@ $collection->filter(function ($person) { ![100%](images/druplicon.png) -^ This is great, but how can I do that in my Drupal code? -How can I do that? +^ This is great, but how can I do that in my Drupal code? How can I do that? --- ## There’s a module for that! + ### _- Drupalers_ --- @@ -109,6 +98,7 @@ How can I do that? [.text: alignment(center)] ## [fit] There's not a module for that. :disappointed: + ### _- Me_ --- @@ -119,12 +109,11 @@ How can I do that? --- - ### _Version 1.0_ + ## Write my own Collection class -^ Wrote my own Collection class -Wrote my own tests +^ Wrote my own Collection class Wrote my own tests --- @@ -140,13 +129,14 @@ Wrote my own tests --- - ### Collect - Illuminate Collections as a separate package. + #### _https://packagist.org/packages/tightenco/collect_ --- ### Import Laravel's Collections into non-Laravel packages easily, without needing to require the entire Illuminate\Support package. + #### _https://packagist.org/packages/tightenco/collect_ --- @@ -162,6 +152,7 @@ Wrote my own tests ## _composer require_
tightenco/collect --- + ![](images/drupal-issue-2.png) --- @@ -171,6 +162,7 @@ Wrote my own tests --- ### _Version 2.0_ + ## Use someone else’s Collection class ^ More fully featured, less code to maintain @@ -215,9 +207,8 @@ $collection->each(function ($item) { }); ``` -^ Require/include autoload.php -Start using Collections! -`collect` function is autoloaded +^ Require/include autoload.php Start using Collections! `collect` function is +autoloaded --- @@ -242,5 +233,7 @@ Start using Collections! [.header: alignment(center)] # Thanks! + ### _@opdavies_ + ### _oliverdavies.uk_