```
---
-## __Configuration__
+
+
+---
+
+[.header: alignment(center)]
+
+# Configuration
---
@@ -329,9 +404,10 @@ options: {
---
-## __States__
+[.header: alignment(center)]
-### Hover, Focus, Active
+# States
+### _Hover, Focus, Active, Group hover_
---
@@ -347,9 +423,30 @@ options: {
```
+^ Hover, focus
+
---
-## __Responsive__
+```twig
+
+```
+
+^ Group hover
+
+---
+
+[.header: alignment(center)]
+
+# Responsive
---
@@ -360,14 +457,23 @@ options: {
---
```html
-
+
```
---
-## __Extracting
Components__
+[.header: alignment(center)]
+
+# Extracting
Components
+
+---
+
+[.header: alignment(center)]
+
+
+## _Do you need to_ extract
a component?
---
@@ -379,6 +485,29 @@ options: {
{% endfor %}
```
+^ Use a loop
+
+---
+
+```twig
+
Adults
+
+{% include 'class-list' with {
+ classes: page.classes,
+ type: 'adults',
+} %}
+
+
Kids
+
+{% include 'class-list' with {
+ classes: page.classes,
+ type: 'kids',
+} %}
+```
+
+^ Move the duplicate markup into a partial, so there's only one version
+Pass data in.
+
---
```html
@@ -393,21 +522,6 @@ options: {
---
-```less
-// main.less
-
-.button {
- .inline-block;
- .rounded;
- .text-sm;
- .py-2;
- .px-3;
- .text-white;
-}
-```
-
----
-
```css
# main.css
@@ -467,13 +581,17 @@ options: {
---
-## Advantages
+[.header: #53B0EB]
+
+# Advantages
- Quick to prototype and make changes
- Write less CSS
- More consistency
- Easy to customise, promote to components
- Mix and match with normal CSS
+- Easy to write reusable plugins
+- Use PurgeCSS to remove unused classes
^ Do more with browser dev tools
Only picking from pre-defined colours, widths. No magic numbers.
@@ -482,7 +600,9 @@ Same classes, but no visual similarities like with other frameworks like Bootstr
---
-## Disadvantages
+[.header: #53B0EB]
+
+# Disadvantages
- Extra build tools and steps
- Lots of classes in markup
@@ -490,19 +610,29 @@ Same classes, but no visual similarities like with other frameworks like Bootstr
^ - Need a build tool (Gulp, Grunt, Webpack) to build CSS
+---
+
+
---
-## For Drupal
-
-- Add a prefix to avoid clashing
-- Enable `important` setting to override existing styles
-- Add classes in templates where possible
-- Use `@apply` to limit the number of templates, to avoid adding classes in PHP code or config (e.g. Views), to style hard-to-reach elements
+
---
-## Resources
+
+
+
+---
+
+
+
+---
+
+[.build-lists: false]
+[.header: #53B0EB]
+
+# Resources
- tailwindcss.com
- tailwindcomponents.com
@@ -513,6 +643,9 @@ Same classes, but no visual similarities like with other frameworks like Bootstr
---
-## __Thank you__
+[.header: alignment(center)]
+
+# Thanks!
+### _@opdavies_
+### _oliverdavies.uk_
-### @opdavies
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides.pdf b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides.pdf
new file mode 100644
index 0000000..72a71d9
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides.pdf differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/1.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/1.png
new file mode 100644
index 0000000..27ac156
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/1.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/10.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/10.png
new file mode 100644
index 0000000..c1f0364
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/10.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/11.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/11.png
new file mode 100644
index 0000000..b941238
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/11.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/12.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/12.png
new file mode 100644
index 0000000..a91d7c8
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/12.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/13.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/13.png
new file mode 100644
index 0000000..a9c33d4
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/13.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/14.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/14.png
new file mode 100644
index 0000000..768084c
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/14.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/15.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/15.png
new file mode 100644
index 0000000..bac10ec
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/15.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/16.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/16.png
new file mode 100644
index 0000000..982d550
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/16.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/17.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/17.png
new file mode 100644
index 0000000..06459bc
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/17.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/18.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/18.png
new file mode 100644
index 0000000..bf14ffd
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/18.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/19.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/19.png
new file mode 100644
index 0000000..52bb006
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/19.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/2.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/2.png
new file mode 100644
index 0000000..8f85564
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/2.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/20.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/20.png
new file mode 100644
index 0000000..94737da
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/20.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/21.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/21.png
new file mode 100644
index 0000000..4dcf719
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/21.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/22.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/22.png
new file mode 100644
index 0000000..c1f0364
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/22.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/23.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/23.png
new file mode 100644
index 0000000..c59007f
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/23.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/24.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/24.png
new file mode 100644
index 0000000..a0aa06c
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/24.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/25.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/25.png
new file mode 100644
index 0000000..e8c2d77
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/25.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/26.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/26.png
new file mode 100644
index 0000000..c31712e
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/26.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/27.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/27.png
new file mode 100644
index 0000000..50ee2c7
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/27.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/28.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/28.png
new file mode 100644
index 0000000..27103c6
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/28.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/29.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/29.png
new file mode 100644
index 0000000..59d954c
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/29.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/3.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/3.png
new file mode 100644
index 0000000..ecc669c
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/3.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/30.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/30.png
new file mode 100644
index 0000000..6fdf3a0
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/30.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/31.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/31.png
new file mode 100644
index 0000000..e651792
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/31.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/32.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/32.png
new file mode 100644
index 0000000..4c15a6f
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/32.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/33.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/33.png
new file mode 100644
index 0000000..760b2e2
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/33.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/34.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/34.png
new file mode 100644
index 0000000..7565860
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/34.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/35.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/35.png
new file mode 100644
index 0000000..7be12f6
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/35.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/36.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/36.png
new file mode 100644
index 0000000..b63b523
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/36.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/37.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/37.png
new file mode 100644
index 0000000..a71070c
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/37.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/38.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/38.png
new file mode 100644
index 0000000..1f6ccc0
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/38.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/39.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/39.png
new file mode 100644
index 0000000..693ebec
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/39.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/4.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/4.png
new file mode 100644
index 0000000..52d6197
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/4.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/40.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/40.png
new file mode 100644
index 0000000..f4674f2
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/40.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/41.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/41.png
new file mode 100644
index 0000000..46f1b58
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/41.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/42.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/42.png
new file mode 100644
index 0000000..8377f42
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/42.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/43.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/43.png
new file mode 100644
index 0000000..c20bacb
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/43.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/44.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/44.png
new file mode 100644
index 0000000..431f2e2
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/44.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/45.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/45.png
new file mode 100644
index 0000000..66b8728
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/45.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/46.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/46.png
new file mode 100644
index 0000000..c3a1c33
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/46.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/47.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/47.png
new file mode 100644
index 0000000..9792224
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/47.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/48.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/48.png
new file mode 100644
index 0000000..eb26ef0
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/48.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/49.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/49.png
new file mode 100644
index 0000000..c4b19da
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/49.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/5.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/5.png
new file mode 100644
index 0000000..612b630
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/5.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/50.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/50.png
new file mode 100644
index 0000000..1052a89
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/50.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/51.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/51.png
new file mode 100644
index 0000000..f35568a
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/51.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/52.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/52.png
new file mode 100644
index 0000000..201d344
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/52.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/53.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/53.png
new file mode 100644
index 0000000..f362d4c
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/53.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/54.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/54.png
new file mode 100644
index 0000000..f71d5ac
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/54.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/6.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/6.png
new file mode 100644
index 0000000..57fa577
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/6.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/7.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/7.png
new file mode 100644
index 0000000..8c30ba6
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/7.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/8.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/8.png
new file mode 100644
index 0000000..781840a
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/8.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/9.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/9.png
new file mode 100644
index 0000000..c0ef4bb
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/9.png differ
diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides3.pdf b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides3.pdf
new file mode 100644
index 0000000..474d827
Binary files /dev/null and b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides3.pdf differ
diff --git a/taking-flight-with-tailwind-css/abstract.md b/taking-flight-with-tailwind-css/abstract.md
deleted file mode 100644
index d0b6df6..0000000
--- a/taking-flight-with-tailwind-css/abstract.md
+++ /dev/null
@@ -1,10 +0,0 @@
-# Taking Flight with Tailwind CSS
-
-An introduction to utility class and component based styling, and how to soar with Tailwind CSS.
-
-Things we’ll cover:
-
-- Advantages and disadvantages to utility based styling and Tailwind.
-- How to install Tailwind and add it to your build process.
-- How to customise Tailwind.
-- How to promote repeating classes into re-usable components.-
diff --git a/tdd-test-driven-drupal/2018-06-14-drupal-somerset/slides2.pdf b/tdd-test-driven-drupal/2018-06-14-drupal-somerset/slides2.pdf
new file mode 100644
index 0000000..c6c4eaf
Binary files /dev/null and b/tdd-test-driven-drupal/2018-06-14-drupal-somerset/slides2.pdf differ
diff --git a/tdd-test-driven-drupal/2018-07-05-drupal-dev-days/slides.pdf b/tdd-test-driven-drupal/2018-07-05-drupal-dev-days/slides.pdf
new file mode 100644
index 0000000..70a1135
Binary files /dev/null and b/tdd-test-driven-drupal/2018-07-05-drupal-dev-days/slides.pdf differ
diff --git a/tdd-test-driven-drupal/2018-07-05-drupal-dev-days/tdd-test-driven-drupal.pdf b/tdd-test-driven-drupal/2018-07-05-drupal-dev-days/tdd-test-driven-drupal.pdf
new file mode 100644
index 0000000..77964ee
Binary files /dev/null and b/tdd-test-driven-drupal/2018-07-05-drupal-dev-days/tdd-test-driven-drupal.pdf differ
diff --git a/tdd-test-driven-drupal/abstract.md b/tdd-test-driven-drupal/abstract.md
deleted file mode 100644
index 5eb4afc..0000000
--- a/tdd-test-driven-drupal/abstract.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# TDD - Test Driven Drupal
-
-Testing is important. Why? It allows developers to add new features and edit and refactor existing code without the worry of adding regressions, reduces the reliance on manual testing to discover bugs, and by taking a test driven approach, your implementation code is leaner as you only write what is needed for your tests to pass.
-
-Drupal 7 includes the SimpleTest module for unit and functional testing, whilst Drupal 8 also includes and supports PHPUnit - the defacto PHP testing framework, used by other PHP projects including Symfony and Laravel - making it easier for people to test their code. Also, with testing being one of the Drupal core gates with tests needing to be included with every new feature or bug fix, and core’s 100% pass rate policy, testing has become an essential skill when contributing to core, or when working on your own projects.
-
-In this talk, we’ll cover the methodology and terminology involved with automated testing, and then take a test driven approach to creating a new Drupal module.
-
-**Note:**
-
-Currently updating this talk with more Drupal 8 content and examples.
diff --git a/tdd-test-driven-drupal/images/broadbean-drupal-flow-1.png b/tdd-test-driven-drupal/images/broadbean-drupal-flow-1.png
new file mode 100644
index 0000000..860c6c3
Binary files /dev/null and b/tdd-test-driven-drupal/images/broadbean-drupal-flow-1.png differ
diff --git a/tdd-test-driven-drupal/images/broadbean-drupal-flow-2.png b/tdd-test-driven-drupal/images/broadbean-drupal-flow-2.png
new file mode 100644
index 0000000..da80f78
Binary files /dev/null and b/tdd-test-driven-drupal/images/broadbean-drupal-flow-2.png differ
diff --git a/tdd-test-driven-drupal/images/d8-simpletest-1.png b/tdd-test-driven-drupal/images/d8-simpletest-1.png
new file mode 100644
index 0000000..5ef734a
Binary files /dev/null and b/tdd-test-driven-drupal/images/d8-simpletest-1.png differ
diff --git a/tdd-test-driven-drupal/images/d8-simpletest-2.png b/tdd-test-driven-drupal/images/d8-simpletest-2.png
new file mode 100644
index 0000000..6a86356
Binary files /dev/null and b/tdd-test-driven-drupal/images/d8-simpletest-2.png differ
diff --git a/tdd-test-driven-drupal/images/d8-simpletest-3.png b/tdd-test-driven-drupal/images/d8-simpletest-3.png
new file mode 100644
index 0000000..9f2e423
Binary files /dev/null and b/tdd-test-driven-drupal/images/d8-simpletest-3.png differ
diff --git a/tdd-test-driven-drupal/images/d8-simpletest-4.png b/tdd-test-driven-drupal/images/d8-simpletest-4.png
new file mode 100644
index 0000000..162c867
Binary files /dev/null and b/tdd-test-driven-drupal/images/d8-simpletest-4.png differ
diff --git a/tdd-test-driven-drupal/images/d8-simpletest-5.png b/tdd-test-driven-drupal/images/d8-simpletest-5.png
new file mode 100644
index 0000000..2e1e4fe
Binary files /dev/null and b/tdd-test-driven-drupal/images/d8-simpletest-5.png differ
diff --git a/tdd-test-driven-drupal/images/d8-simpletest-6.png b/tdd-test-driven-drupal/images/d8-simpletest-6.png
new file mode 100644
index 0000000..33e29f6
Binary files /dev/null and b/tdd-test-driven-drupal/images/d8-simpletest-6.png differ
diff --git a/tdd-test-driven-drupal/images/d8-simpletest-7.png b/tdd-test-driven-drupal/images/d8-simpletest-7.png
new file mode 100644
index 0000000..9b5463d
Binary files /dev/null and b/tdd-test-driven-drupal/images/d8-simpletest-7.png differ
diff --git a/tdd-test-driven-drupal/images/ddd-1.jpeg b/tdd-test-driven-drupal/images/ddd-1.jpeg
new file mode 100644
index 0000000..6f49fc8
Binary files /dev/null and b/tdd-test-driven-drupal/images/ddd-1.jpeg differ
diff --git a/tdd-test-driven-drupal/images/ddd-2.jpeg b/tdd-test-driven-drupal/images/ddd-2.jpeg
new file mode 100644
index 0000000..9f5261d
Binary files /dev/null and b/tdd-test-driven-drupal/images/ddd-2.jpeg differ
diff --git a/tdd-test-driven-drupal/images/ddd-3.jpeg b/tdd-test-driven-drupal/images/ddd-3.jpeg
new file mode 100644
index 0000000..a09ca7d
Binary files /dev/null and b/tdd-test-driven-drupal/images/ddd-3.jpeg differ
diff --git a/tdd-test-driven-drupal/images/ddd-4.jpeg b/tdd-test-driven-drupal/images/ddd-4.jpeg
new file mode 100644
index 0000000..bbfce47
Binary files /dev/null and b/tdd-test-driven-drupal/images/ddd-4.jpeg differ
diff --git a/tdd-test-driven-drupal/images/ddd-5.jpg b/tdd-test-driven-drupal/images/ddd-5.jpg
new file mode 100644
index 0000000..7d575a3
Binary files /dev/null and b/tdd-test-driven-drupal/images/ddd-5.jpg differ
diff --git a/tdd-test-driven-drupal/images/ddd-5.png b/tdd-test-driven-drupal/images/ddd-5.png
new file mode 100644
index 0000000..a75093a
Binary files /dev/null and b/tdd-test-driven-drupal/images/ddd-5.png differ
diff --git a/tdd-test-driven-drupal/images/phpstorm-integration.png b/tdd-test-driven-drupal/images/phpstorm-integration.png
new file mode 100644
index 0000000..c0d12c7
Binary files /dev/null and b/tdd-test-driven-drupal/images/phpstorm-integration.png differ
diff --git a/tdd-test-driven-drupal/images/tada.png b/tdd-test-driven-drupal/images/tada.png
new file mode 100644
index 0000000..4978ad7
Binary files /dev/null and b/tdd-test-driven-drupal/images/tada.png differ
diff --git a/tdd-test-driven-drupal/images/tawny-tweet-1.png b/tdd-test-driven-drupal/images/tawny-tweet-1.png
new file mode 100644
index 0000000..bf954fa
Binary files /dev/null and b/tdd-test-driven-drupal/images/tawny-tweet-1.png differ
diff --git a/tdd-test-driven-drupal/images/tawny-tweet-2.png b/tdd-test-driven-drupal/images/tawny-tweet-2.png
new file mode 100644
index 0000000..ea425d4
Binary files /dev/null and b/tdd-test-driven-drupal/images/tawny-tweet-2.png differ
diff --git a/tdd-test-driven-drupal/images/tdd-blog-1.png b/tdd-test-driven-drupal/images/tdd-blog-1.png
new file mode 100644
index 0000000..ea4fdc0
Binary files /dev/null and b/tdd-test-driven-drupal/images/tdd-blog-1.png differ
diff --git a/tdd-test-driven-drupal/images/tdd-blog-2.png b/tdd-test-driven-drupal/images/tdd-blog-2.png
new file mode 100644
index 0000000..3bce812
Binary files /dev/null and b/tdd-test-driven-drupal/images/tdd-blog-2.png differ
diff --git a/tdd-test-driven-drupal/images/tdd-blog-3.png b/tdd-test-driven-drupal/images/tdd-blog-3.png
new file mode 100644
index 0000000..3b20e02
Binary files /dev/null and b/tdd-test-driven-drupal/images/tdd-blog-3.png differ
diff --git a/tdd-test-driven-drupal/images/tdd-blog-4.png b/tdd-test-driven-drupal/images/tdd-blog-4.png
new file mode 100644
index 0000000..66a0b80
Binary files /dev/null and b/tdd-test-driven-drupal/images/tdd-blog-4.png differ
diff --git a/tdd-test-driven-drupal/images/tdd-blog-5.png b/tdd-test-driven-drupal/images/tdd-blog-5.png
new file mode 100644
index 0000000..b50dd8a
Binary files /dev/null and b/tdd-test-driven-drupal/images/tdd-blog-5.png differ
diff --git a/tdd-test-driven-drupal/images/tdd-blog-directories.png b/tdd-test-driven-drupal/images/tdd-blog-directories.png
new file mode 100644
index 0000000..17eb9fa
Binary files /dev/null and b/tdd-test-driven-drupal/images/tdd-blog-directories.png differ
diff --git a/tdd-test-driven-drupal/images/tdd-blog-installed.png b/tdd-test-driven-drupal/images/tdd-blog-installed.png
new file mode 100644
index 0000000..e40926b
Binary files /dev/null and b/tdd-test-driven-drupal/images/tdd-blog-installed.png differ
diff --git a/tdd-test-driven-drupal/slides.md b/tdd-test-driven-drupal/slides.md
index ff1be34..b0cba79 100644
--- a/tdd-test-driven-drupal/slides.md
+++ b/tdd-test-driven-drupal/slides.md
@@ -1,12 +1,11 @@
+theme: poster, 8
autoscale: true
build-lists: true
-footer-style: alignment(left)
-footer: @opdavies | oliverdavies.uk
header-emphasis: #53B0EB
header: alignment(left)
text: alignment(left)
text-emphasis: #53B0EB
-theme: poster, 8
+code: Monaco, #6699FF, #999999, #6666FF, #66FF66, #66FF66, line-height(1.3)
[.header: alignment(center)]
@@ -16,19 +15,77 @@ theme: poster, 8
---
+[.header: alignment(center)]
+
+## [fit] opdavi.es/_tdd-test-driven-drupal_
+
+^ View on the website or click through to Speakerdeck
+
+---
+
+[.background-color: #FFFFFF]
+[.header: #111111, alignment(left)]
+
+## Diamond sponsor
+
+
+
+---
+
+[.background-color: #FFFFFF]
+[.header: #111111, alignment(left)]
+
+## Platinum sponsors
+
+
+
+---
+
+[.background-color: #FFFFFF]
+[.header: #111111, alignment(left)]
+
+## Gold sponsors
+
+
+
+---
+
+
+
+---
+
+[.build-lists: false]
+
+- Module and theme developers
+- Want to know more about automated testing
+- Looking to start writing your first tests
+- Drupal 8
+- PHPUnit
+
+---
+
+- Why write tests, and what to test
+- Types of tests
+- How to run tests
+- Real life example
+- Building a new module with TDD
+
+---
+
[.background-color: #FFFFFF]
[.build-lists: false]
[.header: #111111]
[.text: #111111, alignment(left)]
-
+
-- Full stack Web Developer & System Administrator
+- Full Stack Web Developer & System Administrator
- Senior Developer at Microserve
- Part-time freelancer
- Acquia certified Drupal 8 Grand Master
- Drupal 7 & 8 core contributor
-- opdavies (Drupal.org, GitHub, Twitter)
+- Symfony, Laravel, ~~Silex,~~ Sculpin
+- @opdavies
- www.oliverdavies.uk
^ Work at Microserve.
@@ -37,6 +94,30 @@ Blog on my website
---
+[.build-lists: false]
+
+- oliverdavies.uk/_talks_
+- oliverdavies.uk/_twitter_
+- oliverdavies.uk/_drupal_
+- oliverdavies.uk/_github_
+
+^ Example code on GitHub
+
+---
+
+[.background-color: #FFFFFF]
+[.text: #111111, alignment(left)]
+
+
+
+- https://microserve.io
+- https://www.drupal.org/microserve
+- https://github.com/microserve-io
+- https://twitter.com/microserveltd
+- https://www.linkedin.com/company/microserve-ltd
+
+---
+
[.header: alignment(center)]
## test_driven_drupal_.com_
@@ -45,21 +126,19 @@ Blog on my website
[.header: alignment(center)]
-## Why?
-## _What?_
-## How?
+## Write custom modules and themes _for clients_
---
[.header: alignment(center)]
-## I write _contrib modules_ for the community
+## Occassionally
contribute _to core_
---
[.header: alignment(center)]
-## I write _custom modules_ for client projects
+## Maintain and contribute to _contrib projects_
---
@@ -73,13 +152,13 @@ Blog on my website
- Become maintainer in 2012
- Had some existing tests
-- First experience of testing with a real module
- Used on _11,046 sites_ in October 2012 (_84_ D5, _7,094_ D6, _3,868_ D7)
- Used on _29,023 sites_ in June 2018 (_9_ D5, _1,853_ D6, _23,602_ D7, _3,559_ D8)
+- _#236_ most used module on Drupal.org
- Crucial to preventing regressions when adding new features or fixing bugs
-- Ensured consistency when porting to Drupal 8
^ Preventing regressions in my additions but also user submitted patches
+First module I ported to Drupal 8, aided by tests
---
@@ -92,7 +171,7 @@ Blog on my website
## _Why write tests?_
- Catch bugs earlier
-- Piece of mind
+- Peace of mind
- Prevent regressions
- Write less code
- Documentation
@@ -107,56 +186,33 @@ ONO merge conflict
## _Core Testing Gate_
-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.
+- 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.
[.footer: https://www.drupal.org/core/gates#testing]
---
-[.header: alignment(center)]
-
-## _Testing may add time now,_ but save more
time in the future
-
----
-
-[.header: alignment(center)]
-
-## [fit] _How do you get quicker at writing tests?_
-# [fit] By writing more tests
-
----
-
## _Testing in Drupal_
-- _Drupal 7_ - Simpletest (testing) module provided as part of core
+- _Drupal 7_ - SimpleTest (testing) module provided as part of core
- _Drupal 8_ - PHPUnit added as a core dependency
-- _PHPUnit Initiative_ - Simpletest to be deprecated and removed in Drupal 9
+- _PHPUnit Initiative_ - SimpleTest to be deprecated and removed in Drupal 9
---
-## _Setting up your environment_
+[.header: #53B0EB]
-- Drupal includes `core/phpunit.xml.dist`
-- Copy to `core/phpunit.xml`
-- Amend values as needed
- + Add base URL, database credentials
-- Docksal - `fin addon install phpunit`
+## Writing Tests (Drupal 8)
----
-
-## _Writing Tests (Drupal 8)_
-
-- PHP class with `.php` extension
-- `tests/src` directory within each module
-- Within the `Drupal\Tests\module_name` namespace
+- PHP class with _.php_ extension
+- _tests/src_ directory within each module
+- Within the *Drupal\Tests\module_name* namespace
- Class name must match the filename
- Namespace must match the directory structure
- One test class per feature
-- Each method must start with `test`
+- Each method must start with _test_
^ Different to D7
@@ -170,11 +226,8 @@ Bug fixes should be accompanied by changes to a test (either modifying an existi
---
-[.hide-footer]
```php
- 'data']);
- public static $modules = ['phpunit_example'];
-
- public function testPhpUnitExampleMenu() {
- $this->drupalGet('/examples/phpunit-example');
-
- $this->assertSession()->statusCodeEquals(200);
+ $this->assertEquals('test', $job->getType());
+ $this->assertEquals(['my' => 'data'], $job->getPayload());
+ $this->assertEquals(Job::STATE_QUEUED, $job->getState());
}
+
}
```
----
-
-[.hide-footer]
-
-```php, [.highlight: 5]
-drupalGet('/examples/phpunit-example');
-
- $this->assertSession()->statusCodeEquals(200);
- }
-}
-```
+^ Within a Unit directory and namespace
+Called JobTest because it's testing the Job class
+Called testCreate because it's testing the create method
+Create a job with the create method
+Retrieve data from the object with getters
---
-[.hide-footer]
-
-```php, [.highlight: 7-9]
-drupalGet('/examples/phpunit-example');
-
- $this->assertSession()->statusCodeEquals(200);
- }
-}
-```
-
----
-
-[.hide-footer]
-
```php, [.highlight: 11]
- 'data']);
- public static $modules = ['phpunit_example'];
-
- public function testPhpUnitExampleMenu() {
- $this->drupalGet('/examples/phpunit-example');
-
- $this->assertSession()->statusCodeEquals(200);
+ $this->assertEquals('test', $job->getType());
+ $this->assertEquals(['my' => 'data'], $job->getPayload());
+ $this->assertEquals(Job::STATE_QUEUED, $job->getState());
}
+
}
```
---
-[.hide-footer]
+```php, [.highlight: 13-15]
+// tests/src/Unit/JobTest.php
-```php, [.highlight: 13-17]
- 'data']);
-class PHPUnitExampleMenuTest extends BrowserTestBase {
-
- public static $modules = ['phpunit_example'];
-
- public function testPhpUnitExampleMenu() {
- $this->drupalGet('/examples/phpunit-example');
-
- $this->assertSession()->statusCodeEquals(200);
+ $this->assertEquals('test', $job->getType());
+ $this->assertEquals(['my' => 'data'], $job->getPayload());
+ $this->assertEquals(Job::STATE_QUEUED, $job->getState());
}
+
}
```
---
+[.header: #53B0EB]
-## _Kernel Tests_
+## Kernel Tests
- Integration tests
- Can install modules, interact with services, container, database
@@ -366,80 +415,315 @@ class PHPUnitExampleMenuTest extends BrowserTestBase {
---
-## _Unit Tests_
-
-- Tests PHP logic
-- No database interaction
-- Fast to run
-- Tightly coupled
-- Complicated mocking
-
----
-
-[.hide-footer]
-
```php
-namespace Drupal\collection_class;
+// tests/src/Kernel/ProcessorTest.php
-class Collection implements \Countable, \IteratorAggregate {
- private $items;
+namespace Drupal\Tests\advancedqueue\Kernel;
- public function __construct($items = array()) {
- $this->items = is_array($items) ? $items
- : $this->getArrayableItems($items);
- }
+use Drupal\advancedqueue\Entity\Queue;
+use Drupal\advancedqueue\Job;
+use Drupal\KernelTests\KernelTestBase;
- public function __toString() {
- return $this->toJson();
- }
+class ProcessorTest extends KernelTestBase {
- public function all() {
- return $this->items;
- }
+ ...
- public function count() {
- return count($this->items);
- }
-
-
- public function isEmpty() {
- return empty($this->items);
- }
-
- public function first() {
- return array_shift($this->items);
- }
}
```
---
-[.hide-footer]
-
```php
-$collection = new Collection([1, 2, 3, 4, 5]);
+// tests/src/Kernel/ProcessorTest.php
-// Returns all items.
-$collection->all();
+protected function setUp() {
+ parent::setUp();
-// Counts the number of items.
-$collection->count();
+ $this->installSchema('advancedqueue', ['advancedqueue']);
-// Returns the array keys.
-$collection->keys();
+ $this->queue = Queue::create([
+ 'id' => 'test',
+ 'label' => 'Test queue',
+ 'backend' => 'database',
+ 'backend_configuration' => [
+ 'lease_time' => 5,
+ ],
+ ]);
+ $this->queue->save();
+
+ $this->processor = $this->container->get('advancedqueue.processor');
+}
```
---
-[.hide-footer]
+```php, [.highlight: 6]
+// tests/src/Kernel/ProcessorTest.php
+
+protected function setUp() {
+ parent::setUp();
+
+ $this->installSchema('advancedqueue', ['advancedqueue']);
+
+ $this->queue = Queue::create([
+ 'id' => 'test',
+ 'label' => 'Test queue',
+ 'backend' => 'database',
+ 'backend_configuration' => [
+ 'lease_time' => 5,
+ ],
+ ]);
+ $this->queue->save();
+
+ $this->processor = $this->container->get('advancedqueue.processor');
+}
+```
+
+---
+
+```php, [.highlight: 8-16]
+// tests/src/Kernel/ProcessorTest.php
+
+protected function setUp() {
+ parent::setUp();
+
+ $this->installSchema('advancedqueue', ['advancedqueue']);
+
+ $this->queue = Queue::create([
+ 'id' => 'test',
+ 'label' => 'Test queue',
+ 'backend' => 'database',
+ 'backend_configuration' => [
+ 'lease_time' => 5,
+ ],
+ ]);
+ $this->queue->save();
+
+ $this->processor = $this->container->get('advancedqueue.processor');
+}
+```
+
+---
+
+```php, [.highlight: 18]
+// tests/src/Kernel/ProcessorTest.php
+
+protected function setUp() {
+ parent::setUp();
+
+ $this->installSchema('advancedqueue', ['advancedqueue']);
+
+ $this->queue = Queue::create([
+ 'id' => 'test',
+ 'label' => 'Test queue',
+ 'backend' => 'database',
+ 'backend_configuration' => [
+ 'lease_time' => 5,
+ ],
+ ]);
+ $this->queue->save();
+
+ $this->processor = $this->container->get('advancedqueue.processor');
+}
+```
+
+---
```php
-public function testAll() {
- $items = ['foo', 'bar', 'baz'];
+// tests/src/Kernel/ProcessorTest.php
- $collection = new Collection($items);
+public function testProcessor() {
+ $first_job = Job::create('simple', [
+ 'test' => '1',
+ ]);
- $this->assertEqual($items, $collection->all());
+ $second_job = Job::create('flexible', [
+ 'expected_state' => Job::STATE_SUCCESS,
+ 'expected_message' => 'Done!',
+ ]);
+
+ $third_job = Job::create(
+ 'flexible', ['expected_exception' => 'DB down!'],
+ );
+
+ $fourth_job = Job::create('flexible', [
+ 'expected_state' => Job::STATE_FAILURE,
+ 'expected_message' => 'Failed!',
+ ]);
+
+ ...
+}
+```
+
+---
+
+```php, [.highlight: 6-10]
+// tests/src/Kernel/ProcessorTest.php
+
+public function testProcessor() {
+ ...
+
+ $this->queue->enqueueJob($first_job);
+ $this->queue->enqueueJob($second_job);
+ $this->queue->enqueueJob($third_job);
+ $this->queue->enqueueJob($fourth_job);
+
+ $num_processed = $this->processor->processQueue($this->queue);
+
+ $this->assertEquals(4, $num_processed);
+}
+```
+
+---
+
+```php, [.highlight: 11-13]
+// tests/src/Kernel/ProcessorTest.php
+
+public function testProcessor() {
+ ...
+
+ $this->queue->enqueueJob($first_job);
+ $this->queue->enqueueJob($second_job);
+ $this->queue->enqueueJob($third_job);
+ $this->queue->enqueueJob($fourth_job);
+
+ $num_processed = $this->processor->processQueue($this->queue);
+
+ $this->assertEquals(4, $num_processed);
+}
+```
+
+---
+
+[.header: #53B0EB]
+
+## Functional Tests
+
+- Tests end-to-end functionality
+- UI testing
+- Interacts with database
+- Full Drupal installation
+- Slower to run
+- With/without JavaScript
+
+^ testing profile
+
+---
+
+```php
+// tests/src/Functional/QueueTest.php
+
+namespace Drupal\Tests\advancedqueue\Functional;
+
+use Drupal\advancedqueue\Entity\Queue;
+use Drupal\advancedqueue\Entity\QueueInterface;
+use Drupal\Tests\BrowserTestBase;
+
+class QueueTest extends BrowserTestBase {
+ ...
+}
+```
+
+---
+
+```php, [.highlight: 6-8]
+// tests/src/Functional/QueueTest.php
+
+protected function setUp() {
+ parent::setUp();
+
+ $this->placeBlock('local_tasks_block');
+ $this->placeBlock('local_actions_block');
+ $this->placeBlock('page_title_block');
+
+ $this->adminUser = $this->drupalCreateUser(['administer advancedqueue']);
+ $this->drupalLogin($this->adminUser);
+}
+```
+
+---
+
+```php, [.highlight: 10-11]
+// tests/src/Functional/QueueTest.php
+
+protected function setUp() {
+ parent::setUp();
+
+ $this->placeBlock('local_tasks_block');
+ $this->placeBlock('local_actions_block');
+ $this->placeBlock('page_title_block');
+
+ $this->adminUser = $this->drupalCreateUser(['administer advancedqueue']);
+ $this->drupalLogin($this->adminUser);
+}
+```
+
+---
+
+```php, [.highlight: 4-11]
+// tests/src/Functional/QueueTest.php
+
+public function testQueueDeletion() {
+ $queue = Queue::create([
+ 'id' => 'test',
+ 'label' => 'Test',
+ 'backend' => 'database',
+ 'processor' => QueueInterface::PROCESSOR_DAEMON,
+ 'processing_time' => 100,
+ ]);
+ $queue->save();
+ $this->drupalGet('admin/config/system/queues/manage/' . $queue->id() . '/delete');
+ $this->submitForm([], 'Delete');
+ $this->assertSession()->addressEquals('admin/config/system/queues');
+
+ $queue_exists = (bool) Queue::load('test');
+ $this->assertEmpty($queue_exists, 'The queue has been deleted from the database.');
+}
+```
+
+---
+
+```php, [.highlight: 12-14]
+// tests/src/Functional/QueueTest.php
+
+public function testQueueDeletion() {
+ $queue = Queue::create([
+ 'id' => 'test',
+ 'label' => 'Test',
+ 'backend' => 'database',
+ 'processor' => QueueInterface::PROCESSOR_DAEMON,
+ 'processing_time' => 100,
+ ]);
+ $queue->save();
+ $this->drupalGet('admin/config/system/queues/manage/' . $queue->id() . '/delete');
+ $this->submitForm([], 'Delete');
+ $this->assertSession()->addressEquals('admin/config/system/queues');
+
+ $queue_exists = (bool) Queue::load('test');
+ $this->assertEmpty($queue_exists, 'The queue has been deleted from the database.');
+}
+```
+
+---
+
+```php, [.highlight: 16-17]
+// tests/src/Functional/QueueTest.php
+
+public function testQueueDeletion() {
+ $queue = Queue::create([
+ 'id' => 'test',
+ 'label' => 'Test',
+ 'backend' => 'database',
+ 'processor' => QueueInterface::PROCESSOR_DAEMON,
+ 'processing_time' => 100,
+ ]);
+ $queue->save();
+ $this->drupalGet('admin/config/system/queues/manage/' . $queue->id() . '/delete');
+ $this->submitForm([], 'Delete');
+ $this->assertSession()->addressEquals('admin/config/system/queues');
+
+ $queue_exists = (bool) Queue::load('test');
+ $this->assertEmpty($queue_exists, 'The queue has been deleted from the database.');
}
```
@@ -467,9 +751,21 @@ public function testAll() {
---
-## _Setup (functional)_
+## _Should you test that_
a block is rendered correctly?
-[.hide-footer]
+---
+
+## _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.
+
+---
+
+[.header: #53B0EB]
+
+## Setup (functional)
```
drupalCreateUser()
@@ -504,15 +800,16 @@ assertMail()
---
-## _Assertions_
+[.header: #53B0EB]
-[.hide-footer]
+## Assertions
```php
assertTrue()
assertFalse()
assertEquals()
+assertSame()
assertNull()
assertNotNull()
@@ -525,11 +822,13 @@ assertArraySubset()
---
-## _Assertions (functional)_
+[.header: #53B0EB]
-[.hide-footer]
+## Assertions (functional)
```php
+assertSession()
+
pageTextContains()
pageTextNotContains()
@@ -555,17 +854,30 @@ statusCodeNotEquals()
---
-## _Specification_
+[.header: #53B0EB]
-- Job adverts created on third-party system, needs to create nodes in Drupal, links users to separate application system
-- Adverts need to be linked to offices
-- Advert length specified in number of days
+## Specification
+
+- Job adverts created in Broadbean UI, needs to create nodes in Drupal
+- Application URL links users to separate application system
+- 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
---
-[.hide-footer]
+[.background-color: #FFFFFF]
+
+
+
+---
+
+[.background-color: #FFFFFF]
+
+
+
+---
```php
$data = [
@@ -594,17 +906,33 @@ $data = [
---
-## _Implementation_
+[.header: #53B0EB]
+
+## Implementation
- Added route to accept data from API as XML
-- Added 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`
+- 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*
---
-## _Goals_
+[.header: #53B0EB]
+
+## Implementation
+
+- 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
+
+---
+
+[.header: #53B0EB]
+
+## Testing Goals
- Ensure job nodes are _successfully created_
- Ensure that fields are _mapped correctly_
@@ -613,7 +941,9 @@ $data = [
---
-## _Types of tests_
+[.header: #53B0EB]
+
+## 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
@@ -622,7 +952,9 @@ $data = [
---
-## _Results_
+[.header: #53B0EB]
+
+## Results
- _0 bugs!_
- Reduced debugging time
@@ -636,19 +968,41 @@ $data = [
---
-
+### _Option 1_
+## SimpleTest module (UI)
---
-
+
---
-
+
---
-
+
+
+---
+
+
+
+---
+
+
+
+---
+
+
+
+---
+
+
+
+---
+
+### _Option 2_
+## Core script
---
@@ -662,13 +1016,58 @@ $ php core/scripts/run-tests.sh --class ExampleTest
---
-```
-vendor/bin/phpunit -c core path/to/module
+### _Option 3_
+## PHPUnit
-vendor/bin/phpunit -c core path/to/module --filter testSomething
+---
+
+## Prerequisite _(creating a phpunit.xml file)_
+
+- Configures PHPUnit
+- Needed to run some types of tests
+- Ignored by Git by default
+- Copy _core/phpunit.xml.dist_ to _core/phpunit.xml_
+- Add and change as needed
+ - `SIMPLETEST_BASE_URL`, `SIMPLETEST_DB`, `BROWSERTEST_OUTPUT_DIRECTORY`
+ - `stopOnFailure="true"`
+
+---
-vendor/bin/phpunit -c core path/to/module --verbose
```
+cd web
+
+../vendor/bin/phpunit -c core \
+modules/contrib/examples/phpunit_example
+```
+
+---
+
+```
+cd web/core
+
+../../vendor/bin/phpunit \
+../modules/contrib/examples/phpunit_example
+```
+
+---
+
+```
+--filter
+
+--testsuite
+
+--group
+
+--colors
+
+--stop-on-failure
+
+--verbose --debug
+```
+
+---
+
+
---
@@ -678,12 +1077,15 @@ vendor/bin/phpunit -c core path/to/module --verbose
---
-## _Test Driven Development_
+[.header: #53B0EB]
+
+## Test Driven Development
- Write a test
-- See it fail
-- Write code until test passes
-- Refactor when tests are green
+- Test fails
+- Write code
+- Test passes
+- Refactor
- Repeat
---
@@ -702,7 +1104,9 @@ vendor/bin/phpunit -c core path/to/module --verbose
---
-## _Porting Modules to Drupal 8_
+[.header: #53B0EB]
+
+## Porting Modules to Drupal 8
- Make a new branch
- Add/update the tests
@@ -712,23 +1116,28 @@ vendor/bin/phpunit -c core path/to/module --verbose
---
-## _How I Write Tests - "Outside In"_
+[.header: #53B0EB]
+
+## How I Write Tests - "Outside In"
- Start with functional tests
- Drop down to integration or unit tests where needed
- Programming by wishful thinking
- Write comments first, then fill in the code
-- Write assertions first, sometimes
+- Sometimes write assertions first
---
[.header: alignment(center)]
-## Building a new _Drupal 8 Module_ with _TDD_
+## [fit] _Building a new Drupal 8 Module with_
+## [fit] test driven development
---
-## _Acceptance criteria_
+[.header: #53B0EB]
+
+## Acceptance criteria
- As a site visitor
- I want to see a list of published articles at /blog
@@ -736,7 +1145,9 @@ vendor/bin/phpunit -c core path/to/module --verbose
---
-## _Tasks_
+[.header: #53B0EB]
+
+## Tasks
- Ensure the blog page exists
- Ensure only published articles are shown
@@ -744,7 +1155,9 @@ vendor/bin/phpunit -c core path/to/module --verbose
---
-## _Implementation_
+[.header: #53B0EB]
+
+## Implementation
- Use views module
- Do the mininum amount at each step, make no assumptions, let the tests guide us
@@ -752,28 +1165,27 @@ vendor/bin/phpunit -c core path/to/module --verbose
---
-[.hide-footer]
+### _Step 1_
+## Create the module
+
+---
```yml
# tdd_blog.info.yml
-name: 'TDD Example'
+name: 'TDD Blog'
core: '8.x'
type: 'module'
```
---
-### _Task 1:_
+### _Step 2_
## Ensure the blog page exists
---
-[.hide-footer]
-
```php
-- _There are no filters on the view_
-- Add the filters
-- Export and save the view
+
+
+---
+
+>- _There is no content type filter on the view_
+- Add the filter
+- Re-export and save the view
+
+---
+
+
---
@@ -1562,6 +1970,8 @@ OK (1 test, 6 assertions)
---
+[.build-lists: false]
+
## _Tasks_
- ~~Ensure the blog page exists~~
@@ -1570,12 +1980,11 @@ OK (1 test, 6 assertions)
---
-### _Task 3:_
-## Ensure the articles are shown in the correct order
+### _Step 4_
+## Ensure the articles are ordered by date
---
-[.hide-footer]
```php
// modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php
@@ -1591,17 +2000,16 @@ public function testArticlesAreOrderedByDate() {
---
-[.hide-footer]
```php, [.highlight: 4-9]
// modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php
public function testArticlesAreOrderedByDate() {
// Given that I have numerous articles with different post dates.
- $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+1 day')->getTimestamp()]);
- $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+1 month')->getTimestamp()]);
- $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+3 days')->getTimestamp()]);
- $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+1 hour')->getTimestamp()]);
+ $this->createNode(['type' => 'article', 'created' => (new \DateTime('+1 day'))->getTimestamp()]);
+ $this->createNode(['type' => 'article', 'created' => (new \DateTime('+1 month'))->getTimestamp()]);
+ $this->createNode(['type' => 'article', 'created' => (new \DateTime('+3 days'))->getTimestamp()]);
+ $this->createNode(['type' => 'article', 'created' => (new \DateTime('+1 hour'))->getTimestamp()]);
// When I go to the blog page.
@@ -1611,7 +2019,17 @@ public function testArticlesAreOrderedByDate() {
---
-[.hide-footer]
+```php
+$this->createNode([
+ 'type' => 'article',
+ 'created' => (new \DateTime())->modify('+1 day')->getTimestamp(),
+]);
+```
+
+^ Array of default values
+
+---
+
```php, [.highlight: 10-11]
// modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php
@@ -1632,8 +2050,6 @@ public function testArticlesAreOrderedByDate() {
---
-[.hide-footer]
-
```php, [.highlight:10-15]
// modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php
@@ -1657,7 +2073,6 @@ public function testArticlesAreOrderedByDate() {
---
-[.hide-footer]
```php, [.highlight: 5-9, 17-18]
// modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php
@@ -1683,7 +2098,6 @@ public function testArticlesAreOrderedByDate() {
---
-[.hide-footer]
```
PHPUnit 6.5.8 by Sebastian Bergmann and contributors.
@@ -1705,10 +2119,10 @@ Failed asserting that two arrays are equal.
- 1 => 1
- 2 => 3
- 3 => 2
-+ 0 => '3'
++ 0 => '1'
+ 1 => '2'
-+ 2 => '4'
-+ 3 => '1'
++ 2 => '3'
++ 3 => '4'
/Users/opdavies/Code/drupal-testing-workshop/web/core/tests/Drupal/KernelTests/KernelTestBase.php:1114
/Users/opdavies/Code/drupal-testing-workshop/web/modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php:43
@@ -1719,7 +2133,7 @@ Tests: 1, Assertions: 4, Failures: 1.
---
-[.hide-footer]
+[.text: comic sans]
```[.highlight: 8-26]
PHPUnit 6.5.8 by Sebastian Bergmann and contributors.
@@ -1741,10 +2155,10 @@ Failed asserting that two arrays are equal.
- 1 => 1
- 2 => 3
- 3 => 2
-+ 0 => '3'
++ 0 => '1'
+ 1 => '2'
-+ 2 => '4'
-+ 3 => '1'
++ 2 => '3'
++ 3 => '4'
/Users/opdavies/Code/drupal-testing-workshop/web/core/tests/Drupal/KernelTests/KernelTestBase.php:1114
/Users/opdavies/Code/drupal-testing-workshop/web/modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php:43
@@ -1755,12 +2169,20 @@ Tests: 1, Assertions: 4, Failures: 1.
---
+
+
+---
+
- _There is no sort order defined on the view_
- Add the sort order
- Re-export the view
---
+
+
+---
+
```[.highlight:3-8]
PHPUnit 6.5.8 by Sebastian Bergmann and contributors.
@@ -1774,6 +2196,8 @@ OK (1 test, 5 assertions)
---
+[.build-lists: false]
+
## _Tasks_
- ~~Ensure the blog page exists~~
@@ -1782,6 +2206,21 @@ OK (1 test, 5 assertions)
---
+
+
+---
+
+
+
+^ Using the minimal installation profile
+Post 3 is unpublished
+
+---
+
+
+
+---
+
[.header: alignment(center)]
## Take Aways
@@ -1806,40 +2245,88 @@ Manual testing is still important
---
-[.hide-footer]
+[.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.
+
+---
+
+### _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?
+
+---
+
+### _Other modules can affect things_
+## Tests may pass, but fail when other modules are enabled
+
+---
+
+[.header: alignment(center)]
+
+## [fit] _Testing may add time now_
+## [fit] but save more time in the future
+
+---
+
+[.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.
+
+---
+
+## _Start small_
+## Some tests are better than no tests
+
+---
+
+
+[.background-color: #FFFFFF]
+
+
+
+---
+
+[.background-color: #FFFFFF]
+
+
+
+---
+
[.text: alignment(center)]
> 
---
-## _Resources_
-
-- github.com/opdavies/drupal-module-tdd-dublin
-- drupalize.me/series/testing-drupal-7-simpletest
-- lullabot.com/articles/an-overview-of-testing-in-drupal-8
-- mediacurrent.com/blog/writing-simple-simpletest-tests-your-d7-module
-- mediacurrent.com/blog/writing-simple-phpunit-tests-your-d8-module
-- knpuniversity.com/screencast/phpunit
-- adamwathan.me/test-driven-laravel
-- laracasts.com
-
----
-
-- oliverdavies.uk/_talks_
-- oliverdavies.uk/_twitter_
-- oliverdavies.uk/_drupal_
-- oliverdavies.uk/_github_
-- oliverdavies.uk/_youtube_
-
----
-
[.header: alignment(center)]
-## Questions?
+# Questions?
---
[.header: alignment(center)]
# Thanks
+### _@opdavies_
+### _oliverdavies.uk_
diff --git a/tdd-test-driven-drupal/todo.md b/tdd-test-driven-drupal/todo.md
index 63b93e0..da818b0 100644
--- a/tdd-test-driven-drupal/todo.md
+++ b/tdd-test-driven-drupal/todo.md
@@ -1,2 +1,3 @@
- Show composer.json setup
-- Show `fin phpunit`
+- Add "things you can test" and "things you shouldn't test"
+
diff --git a/using-laravel-collections-outside-laravel/2017-12-21-nomad-php/slides.md b/using-laravel-collections-outside-laravel/2017-12-21-nomad-php/slides.md
index c4935df..4b69727 100644
--- a/using-laravel-collections-outside-laravel/2017-12-21-nomad-php/slides.md
+++ b/using-laravel-collections-outside-laravel/2017-12-21-nomad-php/slides.md
@@ -1,25 +1,25 @@
+theme: poster, 8
autoscale: true
build-lists: true
-theme: simple, 1
+header-emphasis: #53B0EB
+header: alignment(left)
+text: alignment(left)
+text-emphasis: #53B0EB
+code: Operator Mono, line-height(1.5)
-# __Using Laravel Collections...
Outside Laravel__
+[.background-color: #FFFFFF]
+[.hide-footer]
+[.header: #111111, alignment(center)]
+
+## Using Laravel Collections...
Outside Laravel

---
-[.build-lists: false]
+[.header: alignment(center)]
-- Web Developer
-- Drupal, Symfony, Silex, Laravel, Sculpin
-- @opdavies
-- oliverdavies.uk
-
-
-
----
-
-## Collections++
+## Collections :thumbsup:
^ Became a fan of Collections whilst learning Laravel
Powerful object orientated way to interact with arrays
@@ -92,6 +92,8 @@ $collection->filter(function ($person) {
---
+[.background-color: #FFFFFF]
+

^ This is great, but how can I do that in my Drupal code?
@@ -99,13 +101,15 @@ How can I do that?
---
-> There’s a module for that!
-> -- Drupalers
+## There’s a module for that!
+### _- Drupalers_
---
-> There's not a module for that. :(
--- Me
+[.text: alignment(center)]
+
+## [fit] There's not a module for that. :disappointed:
+### _- Me_
---
@@ -116,7 +120,8 @@ How can I do that?
---
-## 1.0: Write my own Collection class
+### _Version 1.0_
+## Write my own Collection class
^ Wrote my own Collection class
Wrote my own tests
@@ -125,7 +130,7 @@ Wrote my own tests

-^ Maybe 70% of what Laravels' could do.
+^ Maybe 70% of what Laravel's could do.
---
@@ -136,23 +141,25 @@ Wrote my own tests
---
-> Collect - Illuminate Collections as a separate package.
-> -- https://packagist.org/packages/tightenco/collect
+### 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
+### Import Laravel's Collections into non-Laravel packages easily, without needing to require the entire Illuminate\Support package.
+#### _https://packagist.org/packages/tightenco/collect_
---
+[.background-color: #FFFFFF]
+

^ Can install via Composer
---
-## `composer require tightenco/collect`
+## _composer require_
tightenco/collect
---

@@ -163,13 +170,15 @@ Wrote my own tests
---
-## ~~1.0: Write my own Collection class~~
-## 2.0: Use someone else’s Collection class
+### _Version 2.0_
+## Use someone else’s Collection class
^ More fully featured, less code to maintain
---
+[.background-color: #FFFFFF]
+

---
@@ -212,12 +221,16 @@ Start using Collections!
---
+[.background-color: #FFFFFF]
+

^ Drupal 8, Sculpin site, PHP libraries
---
-## __Thanks!__
+[.header: alignment(center)]
-## @opdavies
+# Thanks!
+### _@opdavies_
+### _oliverdavies.uk_
diff --git a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/all-the-things.jpg b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/all-the-things.jpg
new file mode 100644
index 0000000..4817029
Binary files /dev/null and b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/all-the-things.jpg differ
diff --git a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/blog-post.png b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/blog-post.png
new file mode 100644
index 0000000..9805f99
Binary files /dev/null and b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/blog-post.png differ
diff --git a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/collection-class-module-project-page-1.png b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/collection-class-module-project-page-1.png
new file mode 100644
index 0000000..5faddee
Binary files /dev/null and b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/collection-class-module-project-page-1.png differ
diff --git a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/collection-class-module-project-page-2.png b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/collection-class-module-project-page-2.png
new file mode 100644
index 0000000..a5bd958
Binary files /dev/null and b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/collection-class-module-project-page-2.png differ
diff --git a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/composer.png b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/composer.png
new file mode 100644
index 0000000..bb95a49
Binary files /dev/null and b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/composer.png differ
diff --git a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/drupal-8.png b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/drupal-8.png
new file mode 100644
index 0000000..a0d7bb9
Binary files /dev/null and b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/drupal-8.png differ
diff --git a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/drupal-issue-1.png b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/drupal-issue-1.png
new file mode 100644
index 0000000..1d79637
Binary files /dev/null and b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/drupal-issue-1.png differ
diff --git a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/drupal-issue-2.png b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/drupal-issue-2.png
new file mode 100644
index 0000000..aabd686
Binary files /dev/null and b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/drupal-issue-2.png differ
diff --git a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/druplicon.png b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/druplicon.png
new file mode 100644
index 0000000..f8ced55
Binary files /dev/null and b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/druplicon.png differ
diff --git a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/laravel.png b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/laravel.png
new file mode 100644
index 0000000..3c83acc
Binary files /dev/null and b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/laravel.png differ
diff --git a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/packagist.png b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/packagist.png
new file mode 100644
index 0000000..c129ae3
Binary files /dev/null and b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/packagist.png differ
diff --git a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/tweet-1.png b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/tweet-1.png
new file mode 100644
index 0000000..e58e63f
Binary files /dev/null and b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/tweet-1.png differ
diff --git a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/yay-open-source.jpg b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/yay-open-source.jpg
new file mode 100644
index 0000000..ab224d2
Binary files /dev/null and b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/yay-open-source.jpg differ
diff --git a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/slides.md b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/slides.md
new file mode 100644
index 0000000..3a522cf
--- /dev/null
+++ b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/slides.md
@@ -0,0 +1,246 @@
+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)]
+
+## Using Laravel Collections...
Outside Laravel
+
+
+
+---
+
+[.header: alignment(center)]
+
+## 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
+
+---
+
+```php
+collect(['foo', 'bar']); // ['foo', 'bar']
+
+collect('foobar'); // ['foobar']
+
+$object = new stdClass();
+$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
+
+---
+
+```php
+$collection = collect(['a', 'b', 1, 'c', 2, 'd', 'e', 3, 4]);
+
+$collection->count(); // 9
+
+$collection->first(); // a
+
+$collection->first(function ($item) {
+ return is_numeric($item);
+}); // 1
+
+$collection->contains(2); // true
+
+$collection->contains([2, 10]); // false
+
+$collection->filter(function ($item) {
+ return $item > 2;
+}); // [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.
+
+---
+
+```php
+$collection = collect([
+ ['name' => 'John', 'email' => 'john@example.com', 'age' => 31],
+ ['name' => 'Jane', 'email' => 'jane@example.com', 'age' => 27],
+]);
+
+$collection->pluck('name'); // ['John', 'Jane']
+
+$collection->pluck('name')->sort(); // ['Jane', 'John']
+
+$collection->filter(function ($person) {
+ return $person['age'] >= 30;
+})->pluck('name'); // ['John']
+```
+
+---
+
+[.background-color: #FFFFFF]
+
+
+
+^ 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_
+
+---
+
+[.text: alignment(center)]
+
+## [fit] There's not a module for that. :disappointed:
+### _- Me_
+
+---
+
+
+
+^ Drupal 7
+
+---
+
+
+### _Version 1.0_
+## Write my own Collection class
+
+^ Wrote my own Collection class
+Wrote my own tests
+
+---
+
+
+
+^ Maybe 70% of what Laravel's could do.
+
+---
+
+
+
+^ Can't remember how, but then I found this.
+
+---
+
+
+### 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_
+
+---
+
+[.background-color: #FFFFFF]
+
+
+
+^ Can install via Composer
+
+---
+
+## _composer require_
tightenco/collect
+
+---
+
+
+---
+
+
+
+---
+
+### _Version 2.0_
+## Use someone else’s Collection class
+
+^ More fully featured, less code to maintain
+
+---
+
+[.background-color: #FFFFFF]
+
+
+
+---
+
+[.build-lists: false]
+
+- Install Composer
+- Require `tightenco/collect`
+- Include `autoload.php`
+- `collect()` away!
+
+---
+
+[.build-lists: false]
+
+- Install Composer
+- Require `tightenco/collect`
+- Include `autoload.php`
+- `collect()` away!
+
+
+
+---
+
+```php
+// index.php
+
+require __DIR__ . '/vendor/autoload.php';
+
+$collection = collect(['foo', 'bar']);
+
+$collection->each(function ($item) {
+ // Do something.
+});
+```
+
+^ Require/include autoload.php
+Start using Collections!
+`collect` function is autoloaded
+
+---
+
+[.background-color: #FFFFFF]
+
+
+
+^ Drupal 8, Sculpin site, PHP libraries
+
+---
+
+[.background-color: #FFFFFF]
+
+
+
+---
+
+
+
+---
+
+[.header: alignment(center)]
+
+# Thanks!
+### _@opdavies_
+### _oliverdavies.uk_
diff --git a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/slides2.pdf b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/slides2.pdf
new file mode 100644
index 0000000..6b9bbfe
Binary files /dev/null and b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/slides2.pdf differ
diff --git a/using-laravel-collections-outside-laravel/abstract.md b/using-laravel-collections-outside-laravel/abstract.md
deleted file mode 100644
index 85c6aee..0000000
--- a/using-laravel-collections-outside-laravel/abstract.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Using Laravel Collections... Outside Laravel
-
-Laravel Collections are a powerful object-orientated way of interacting with PHP arrays, but did you know that they can be used outside of Laravel, in any PHP project? This short talk shows how we can use Composer to include Laravel Collections within a non-Laravel project and put them to use within your own code.