LogoLogo
  • FAC Curriculum
  • archive
    • Node & npm introduction
    • developer
      • Programming Paradigms
    • handbook
      • Asking for help
      • Coaching groups
      • Code review
      • Course rules
      • Debugging
      • Employment schedule and material delivered in FAC20
      • GitHub Workflow
      • Glossary or terms
      • Presentation Guidance
      • Equality, Diversity and Inclusion
      • Installation guide
      • Learning circles
      • Mentoring guidance
      • What to expect from your mentors
      • One-day projects
      • Pair programming
      • Portfolio
      • Questions for problem solving
      • Progress Logs
      • Final project report
      • Managing software projects
      • Project Presentations
      • Project roles
      • Projects
      • Retrospectives
      • Role Circles
      • Safeguarding policy
      • Technical Spikes
      • System requirements
      • Tech for Better
      • User Manuals
      • Wellbeing Support
      • project-docs
        • What makes a mentor?
        • Product Handover
        • Sprint Planning
        • Tech for Better Presentations
        • User Research & Usability Testing
    • foundation
      • full-stack
        • Learning Outcomes
        • project
      • testing
        • project
        • spikes
  • docs
    • Contributing to the curriculum
    • Curriculum intent
    • Curriculum process
  • src
    • About our curriculum
    • course
      • Code of Conduct
      • Docker
      • .NET and Umbraco
      • Getting started
      • Founders and Coders coursebook
      • KSB's
      • Mini projects
      • Revision checklist
      • Svelte
      • TypeScript
      • handbook
        • Software Developer Handbook
        • Software Foundation Handbook
      • precourse
        • Before you start the course
        • Installation List
      • syllabus
        • developer
          • app
            • learning-outcomes
            • project
            • schedule
            • spikes
          • introduction
            • learning-outcomes
            • project
            • resources
            • schedule
          • week00-pre-course
            • We'd like you to spend some time before starting the course working on useful fundamentals.
            • spikes
          • week01-project01-basics
            • Employability introduction
            • Homework
            • learning-outcomes
            • Week of September 9th
            • project
            • resources
            • schedule
            • spikes
          • week02-project02-chatbot
            • employability
            • Homework
            • learning-outcomes
            • Week of September 16th
            • project
            • resources
            • schedule
            • spikes
          • week03-project03-server
            • Learning Outcomes
            • Week of September 23th
            • The Amazin' Quizzer API Backend
            • resources
            • schedule
          • week04-project03-frontend
            • learning-outcomes
            • Week of September 30th
            • UI for Quizzer App
            • resources
            • schedule
          • week05-project03-test-deploy
            • Testing and deployment
            • Week of October 7th
            • project
            • resources
            • schedule
          • week06-project04-databases
            • learning-outcomes
            • Week of October 14th
            • project
            • Databases
            • schedule
          • week07-project04-authentication
            • Learning Outcomes
            • Week of October 21st
            • project
            • resources
            • schedule
          • week08-project04-test-deploy
            • Learning Outcomes
            • Week of October 28th
            • project
            • resources
            • schedule
          • week09-reading-week
            • Learning Outcomes
            • overview
            • Project
            • Resources
            • schedule
          • week10-project05-DOTNET-intro
            • Learning Outcomes
            • overview
            • project
            • Resources
            • schedule
          • week11-project05-DOTNET-testing
            • Testing and deployment
            • Week of November 18th
            • project
            • Resources
            • schedule
          • week12-project05-DOTNET-deploy
            • Learning Outcomes
            • Week of November 25th
            • project
            • Resources
            • schedule
            • Spikes
          • week13-TFB-design
            • Learning Outcomes
            • overview
            • Project
            • Resources
            • schedule
            • Design Week Spikes
          • week14-TFB-build
            • Learning Outcomes
            • overview
            • Project
            • DevOps Resources
            • schedule
            • Spikes
          • week15-TFB-build
            • Learning Outcomes
            • overview
            • Project
            • Resources
            • schedule
            • Spikes
          • projects
            • in-house-design
              • Learning Outcomes
              • Project
              • Resources
              • schedule
              • Design Week Spikes
        • foundation
          • Obsolete-full-stack
            • project
          • post-course
            • Homework
            • schedule
        • portfolio
          • fruit-shop
            • learning-outcomes
            • project
            • resources
          • game
            • learning-outcomes
            • project
            • resources
          • hobby-page
            • learning-outcomes
            • project
            • resources
          • movie-data
            • learning-outcomes
            • project
            • resources
          • project-gallery
            • learning-outcomes
            • project
            • resources
          • website
            • learning-outcomes
            • project
            • JavaScript
        • tfb
          • week 1
            • Introduction (45 minutes)
            • Further reading
          • week 10
            • content
            • resources
          • week 11
            • What will we be doing this week?
            • resources
          • week 12
            • What will we be doing this week?
            • Further reading
          • week 2
            • Discover (90 minutes)
            • resources
          • week 3
            • content
            • resources
          • week 4
            • Mapping the user journey (90 minutes)
            • resources
          • week 5
            • Figma Workshop 1 (90 minutes)
            • Further reading
          • week 6
            • Figma Workshop 2 (90 minutes)
            • resources
          • week 7
            • Product pitches & Selection (90 minutes)
            • resources
          • week 8
            • content
            • resources
          • week 9
            • content
            • resources
    • learn
      • DOTNET
        • Introduction to .NET
      • auth
        • Authenticating web apps
      • database
        • Persisting data with SQLite and Node
      • dotnet-two
        • Dependency injections and interfaces in .NET
      • form-validation
        • Form validation
      • react
        • Building client-side apps with React
      • server
        • HTTP servers with Node & Express
      • typescript
        • TypeScript
    • mentoring
      • design-week
        • Analysis Workshop
        • Code planning
        • Definition Workshop
        • Discovery Workshop
        • Figma introduction
        • Usability testing
        • User Research
    • resources
      • http
        • introduction
    • workshops
      • cookie-auth
        • index
      • creating-promises
        • index
      • css-layout
        • index
      • cypress-testing
        • index
      • database-testing
        • index
      • dev-tooling
        • Developer tooling
      • dom-challenge
        • index
      • dom-rendering
        • index
      • es-modules
        • index
      • express-middleware
        • Express middleware
      • first-class-functions
        • index
      • form-validation
        • index
      • functions-callbacks-async
        • Functions, callbacks, & async JavaScript
      • git-intro
        • Introduction to Git
      • git-terminal
        • Using Git in the terminal
      • git-workflow
        • Git workflow
      • github-projects
        • GitHub Projects Workflow Workshop
      • heroku-sql-challenge
        • index
      • html-forms
        • index
      • learn-a11y
        • index
        • starter-files
          • solution
            • Accessibility solution explanation
      • learn-fetch
        • index
      • learn-integration-testing
        • index
      • learn-testing
        • Learn testing in JavaScript
      • learn-unit-testing
        • index
      • node-error-handling
        • Node error-handling
      • node-express-server
        • Node and Express HTTP server
      • node-npm-intro
        • Node & npm introduction
      • node-postgres
        • Learn Postgres with Node
      • node-scripting-challenge
        • index
      • password-security
        • index
      • promise-practice
        • index
      • react-components
        • React components
      • react-fetch
        • index
      • react-forms
        • React forms
      • react-refactor-classes
        • index
      • react-state-effects
        • React state & effects
      • real-world-fetch
        • index
      • scope-challenge
        • Scope debugging challenge
      • semantic-html
        • index
      • server-side-forms
        • Server-side forms
      • session-auth
        • Session authentication
      • sql-intro
        • index
      • tdd-array-methods
        • index
Powered by GitBook
On this page
  • TDD process
  • TDD example
  • Workshop
  • Setup
  • map
  • filter
  • every
  • some
  • find
  • reduce
  • Stretch goal: flat
Export as PDF
  1. src
  2. workshops
  3. tdd-array-methods

index

Learn about test-driven development and practice JS array methods

Test-driven development (TDD) is a methodology where you write tests before you write any code. This forces you to think through exactly how your code should behave. It's kind of like planning an essay before you start writing it. The iterative process of writing each test is supposed to help with solving a problem too.

TDD process

TDD generally follows the "red, green, refactor" cycle.

  1. Red

    Write a test that fails. This is important: if you never see your test fail you might have a false positive (a test that passes even if your code is broken).

  2. Green

    Write as little code as possible to make the test pass. Make sure you don't break any existing tests.

  3. Refactor

    Change your code to improve it (if necessary). You have passing tests to tell you if you break anything.

  4. Repeat

    Go through the cycle until you think you have a complete working solution

TDD example

Let's run through the process by creating a double function using TDD. First we write a failing test:

test("double(2) should be 4", () => {
  equal(double(2), 4);
});

Then we write as little code as we need to make the test pass:

function double(x) {
  return 4;
}

This will feel a bit contrived for a problem where we already know what the final code should be. The idea is not to try and solve the whole problem in one go—TDD is a way to help you solve a harder problem by iterating through solutions.

Then we refactor, if needed. Since we can't make this any simpler let's keep going and repeat the cycle. We need another failing test:

test("double(4) should be 8", () => {
  equal(double(4), 8);
});

Once we see that fail we can amend our function to make it pass:

function double(x) {
  if (x === 4) return 8;
  return 4;
}

Once the test passes we can try to refactor our function to remove repetition. Instead of listing every possible input/output, we can see that we need to return the input multiplied by two each time.

function double(x) {
  return x * 2;
}

This solution looks complete, so we can end the TDD cycle here. It might be worth adding more tests for edge-cases (e.g. what happens when you don't pass any argument), but TDD has helped us solve the problem itself.

If you're confused about the TDD process at the end of the workshop there's a fully explained starter-files/solution/tdd-explanation.js version of the solution that walks through the process step-by-step.

Workshop

We're going to re-create some useful JavaScript array methods using TDD. For example if we're re-creating the array.map method we should use other JS features (like for loops) to create a function that does the same thing as .map, without using .map itself.

For each method you should use TDD to write tests first, then write the actual code. Work in pairs and alternate: person 1 writes a test, then person 2 makes it pass. Then person 2 writes the next test and person 1 makes that pass.

Setup

  1. Clone this repo

  2. Open index.html in your browser

  3. Alternate writing tests and code in index.test.js and index.js

  4. You can see test results in the console

map

const arr = [1, 2, 3];
const newArr = arr.map((x) => x + 1); // [2, 3, 4]

Use TDD to write your own map function that behaves like the built-in one. The only difference should be that yours takes the array as the first argument:

const arr = [1, 2, 3];
const newArr = map(arr, (x) => x + 1); // [2, 3, 4]

There is one passing test and one failing test to get you started.

filter

const arr = [1, 2, 3];
arr.filter((x) => x > 1); // [2, 3]

Use TDD to write your own filter function that behaves like the built-in one. The only difference should be that yours takes the array as the first argument:

const arr = [1, 2, 3];
const greaterThanOne = filter(arr, (x) => x > 1); // [2, 3]

every

const arr = [1, 2, 3];
const allPositive = arr.every((x) => x > 0); // true
const allNegative = arr.every((x) => x < 0); // false

Use TDD to write your own every function that behaves like the built-in one. The only difference should be that yours takes the array as the first argument:

const arr = [1, 2, 3];
const allPositive = every(arr, (x) => x > 0); // true
const allNegative = every(arr, (x) => x < 0); // false

some

const arr = [1, 2, 3];
const atLeastOneGreaterThanTwo = arr.some((x) => x > 2); // true
const atLeastOneNegative = arr.some((x) => x < 0); // false

Use TDD to write your own some function that behaves like the built-in one. The only difference should be that yours takes the array as the first argument:

const arr = [1, 2, 3];
const atLeastOneGreaterThanTwo = some(arr, (x) => x > 2); // true
const atLeastOneNegative = some(arr, (x) => x < 0); // false

find

const arr = [1, 2, 3];
const firstElementOverOne = arr.find((x) => x > 1); // 2

Use TDD to write your own find function that behaves like the built-in one. The only difference should be that yours takes the array as the first argument:

const arr = [1, 2, 3];
const firstElementOverOne = find(arr, (x) => x > 1); // 2

reduce

The function is called with the current value of the accumulator and the current element. Whatever you return from the function is used as the accumulator value for the next iteration. After the final element the final accumulator value is returned.

const arr = [1, 2, 3];
const finalTotal = arr.reduce((total, x) => total + x, 0);
// 1st loop (total = 0, x = 1) => 0 + 1; returns new total: 1
// 2nd loop (total = 1, x = 2) => 1 + 2; returns new total: 3
// 3rd loop (total = 3, x = 3) => 3 + 3; returns new total: 6

Use TDD to write your own reduce function that behaves like the built-in one. The only difference should be that yours takes the array as the first argument:

const arr = [1, 2, 3];
const finalTotal = reduce(arr, (total, x) => total + x, 0); // 6

Stretch goal: flat

const arr = [1, [2, [3]]];
const oneLevelFlatter = arr.flat(); // [1, 2, [3]]
const fullyFlattened = arr.flat(2); // [1, 2, 3]

Use TDD to write your own flat function that behaves like the built-in one. The only difference should be that yours takes the array as the first argument:

const arr = [1, [2, [3]]];
const oneLevelFlatter = flat(arr); // [1, 2, [3]]
const fullyFlattened = flat(arr, 2); // [1, 2, 3]

Hint: recursion or while loops will be helpful.

Previoustdd-array-methods

Last updated 3 years ago

is used to transform each value in an array. It takes a function as an argument, then loops over each element in the array and calls the function with each one. Whatever that function returns is used as a new value in a new array.

is used to remove elements you don't want from an array. It takes a function as an argument, then loops over each element in the array and calls the function with each one. If the function returns true the element is kept, otherwise it is filtered out.

is used to check whether every element in an array meets a certain criteria. It takes a function as an argument, then loops over each element in the array and calls the function with each one. If the function returns false for any of the elements the iteration stops and false is immediately returned. If the function returns true for every element then true is returned.

is used to check whether at least one element in an array meets a certain criteria. It takes a function as an argument, then loops over each element in the array and calls the function with each one. If the function returns true for any of the elements the iteration stops and true is immediately returned. Otherwise it returns false.

is used to get the first element in an array that meets a certain criteria. It takes a function as an argument, then loops over each element in the array and calls the function with each one. If the function returns true for the element the iteration stops and the element is immediately returned. If the function returns false for every element then undefined is returned.

is used to transform an array into a single value. It takes a function and an initial "accumulator" value as arguments. It loops over the array, building up the accumulator on each loop.

is used to turn nested arrays into "flattened" ones. It takes an optional depth argument to flatten arrays nested more than one level down.

Array.map()
Array.filter()
Array.every()
Array.some()
Array.find()
Array.reduce()
Array.flat()