diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index b34cfcfc3..335da9aaf 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1,13 +1,13 @@
-# These are supported funding model platforms
-
-github: CodeYourFuture
-patreon: # Replace with a single Patreon username
-open_collective: # Replace with a single Open Collective username
-ko_fi: # Replace with a single Ko-fi username
-tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
-community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
-liberapay: # Replace with a single Liberapay username
-issuehunt: # Replace with a single IssueHunt username
-otechie: # Replace with a single Otechie username
-lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
-custom: https://codeyourfuture.io/donate
+# These are supported funding model platforms
+
+github: CodeYourFuture
+patreon: # Replace with a single Patreon username
+open_collective: # Replace with a single Open Collective username
+ko_fi: # Replace with a single Ko-fi username
+tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
+community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
+liberapay: # Replace with a single Liberapay username
+issuehunt: # Replace with a single IssueHunt username
+otechie: # Replace with a single Otechie username
+lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
+custom: https://codeyourfuture.io/donate
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index 5fe8ffd09..3e43fc213 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -1,14 +1,14 @@
-blank_issues_enabled: false
-contact_links:
- - name: CYF
- url: contact@codeyourfuture.io
- about: Please report serious issues here.
- - name: Join CYF
- url: https://codeyourfuture.io/volunteers/
- about: Join CYF here
- - name: CYF Slack
- url: codeyourfuture.slack.com
- about: Come to #cyf-syllabus-tech and chat
- - name: CYF Tech Ed
- url: https://github.com/orgs/CodeYourFuture/teams/mentors
- about: CYF mentors on Github
+blank_issues_enabled: false
+contact_links:
+ - name: CYF
+ url: contact@codeyourfuture.io
+ about: Please report serious issues here.
+ - name: Join CYF
+ url: https://codeyourfuture.io/volunteers/
+ about: Join CYF here
+ - name: CYF Slack
+ url: codeyourfuture.slack.com
+ about: Come to #cyf-syllabus-tech and chat
+ - name: CYF Tech Ed
+ url: https://github.com/orgs/CodeYourFuture/teams/mentors
+ about: CYF mentors on Github
diff --git a/.github/ISSUE_TEMPLATE/pd-assignment.yml b/.github/ISSUE_TEMPLATE/pd-assignment.yml
index c8bd22980..3c739f74d 100644
--- a/.github/ISSUE_TEMPLATE/pd-assignment.yml
+++ b/.github/ISSUE_TEMPLATE/pd-assignment.yml
@@ -1,59 +1,59 @@
-name: PD Coursework
-description: Assign a piece of PD coursework
-title: "[PD]
+
+
+
+
+
diff --git a/Sprint-3/quote-generator/jest.setup.js b/Sprint-3/quote-generator/jest.setup.js
index 9e785813a..2223e65df 100644
--- a/Sprint-3/quote-generator/jest.setup.js
+++ b/Sprint-3/quote-generator/jest.setup.js
@@ -1 +1 @@
-require("@testing-library/jest-dom");
+require("@testing-library/jest-dom");
diff --git a/Sprint-3/quote-generator/package.json b/Sprint-3/quote-generator/package.json
index ddfcf15d4..b5a231bc0 100644
--- a/Sprint-3/quote-generator/package.json
+++ b/Sprint-3/quote-generator/package.json
@@ -1,29 +1,29 @@
-{
- "name": "quote-generator",
- "version": "1.0.0",
- "license": "CC-BY-SA-4.0",
- "description": "You must update this package",
- "scripts": {
- "test": "jest"
- },
- "repository": {
- "type": "git",
- "url": "git+https://github.com/CodeYourFuture/CYF-Coursework-Template.git"
- },
- "bugs": {
- "url": "https://github.com/CodeYourFuture/CYF-Coursework-Template/issues"
- },
- "homepage": "https://github.com/CodeYourFuture/CYF-Coursework-Template#readme",
- "devDependencies": {
- "@testing-library/dom": "^8.19.0",
- "@testing-library/jest-dom": "^5.16.5",
- "@testing-library/user-event": "^13.5.0",
- "jest": "^29.2.2",
- "jest-environment-jsdom": "^29.2.2"
- },
- "jest": {
- "setupFilesAfterEnv": [
- "./jest.setup.js"
- ]
- }
-}
+{
+ "name": "quote-generator",
+ "version": "1.0.0",
+ "license": "CC-BY-SA-4.0",
+ "description": "You must update this package",
+ "scripts": {
+ "test": "jest"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/CodeYourFuture/CYF-Coursework-Template.git"
+ },
+ "bugs": {
+ "url": "https://github.com/CodeYourFuture/CYF-Coursework-Template/issues"
+ },
+ "homepage": "https://github.com/CodeYourFuture/CYF-Coursework-Template#readme",
+ "devDependencies": {
+ "@testing-library/dom": "^8.19.0",
+ "@testing-library/jest-dom": "^5.16.5",
+ "@testing-library/user-event": "^13.5.0",
+ "jest": "^29.2.2",
+ "jest-environment-jsdom": "^29.2.2"
+ },
+ "jest": {
+ "setupFilesAfterEnv": [
+ "./jest.setup.js"
+ ]
+ }
+}
diff --git a/Sprint-3/quote-generator/quotes.js b/Sprint-3/quote-generator/quotes.js
index 4a4d04b72..8a24dbedf 100644
--- a/Sprint-3/quote-generator/quotes.js
+++ b/Sprint-3/quote-generator/quotes.js
@@ -1,493 +1,493 @@
-// DO NOT EDIT BELOW HERE
-
-// pickFromArray is a function which will return one item, at
-// random, from the given array.
-//
-// Parameters
-// ----------
-// choices: an array of items to pick from.
-//
-// Returns
-// -------
-// One item at random from the given array.
-//
-// Examples of use
-// ---------------
-// pickFromArray(['a','b','c','d']) // maybe returns 'c'
-
-// You don't need to change this function
-function pickFromArray(choices) {
- return choices[Math.floor(Math.random() * choices.length)];
-}
-
-// A list of quotes you can use in your app.
-// DO NOT modify this array, otherwise the tests may break!
-const quotes = [
- {
- quote: "Life isn't about getting and having, it's about giving and being.",
- author: "Kevin Kruse",
- },
- {
- quote: "Whatever the mind of man can conceive and believe, it can achieve.",
- author: "Napoleon Hill",
- },
- {
- quote: "Strive not to be a success, but rather to be of value.",
- author: "Albert Einstein",
- },
- {
- quote:
- "Two roads diverged in a wood, and I—I took the one less traveled by, And that has made all the difference.",
- author: "Robert Frost",
- },
- {
- quote: "I attribute my success to this: I never gave or took any excuse.",
- author: "Florence Nightingale",
- },
- {
- quote: "You miss 100% of the shots you don't take.",
- author: "Wayne Gretzky",
- },
- {
- quote:
- "I've missed more than 9000 shots in my career. I've lost almost 300 games. 26 times I've been trusted to take the game winning shot and missed. I've failed over and over and over again in my life. And that is why I succeed.",
- author: "Michael Jordan",
- },
- {
- quote:
- "The most difficult thing is the decision to act, the rest is merely tenacity.",
- author: "Amelia Earhart",
- },
- {
- quote: "Every strike brings me closer to the next home run.",
- author: "Babe Ruth",
- },
- {
- quote: "Definiteness of purpose is the starting point of all achievement.",
- author: "W. Clement Stone",
- },
- {
- quote: "We must balance conspicuous consumption with conscious capitalism.",
- author: "Kevin Kruse",
- },
- {
- quote: "Life is what happens to you while you're busy making other plans.",
- author: "John Lennon",
- },
- {
- quote: "We become what we think about.",
- author: "Earl Nightingale",
- },
- {
- quote:
- "Twenty years from now you will be more disappointed by the things that you didn't do than by the ones you did do, so throw off the bowlines, sail away from safe harbor, catch the trade winds in your sails. Explore, Dream, Discover.",
- author: "Mark Twain",
- },
- {
- quote: "Life is 10% what happens to me and 90% of how I react to it.",
- author: "Charles Swindoll",
- },
- {
- quote:
- "The most common way people give up their power is by thinking they don't have any.",
- author: "Alice Walker",
- },
- {
- quote: "The mind is everything. What you think you become.",
- author: "Buddha",
- },
- {
- quote:
- "The best time to plant a tree was 20 years ago. The second best time is now.",
- author: "Chinese Proverb",
- },
- {
- quote: "An unexamined life is not worth living.",
- author: "Socrates",
- },
- {
- quote: "Eighty percent of success is showing up.",
- author: "Woody Allen",
- },
- {
- quote:
- "Your time is limited, so don't waste it living someone else's life.",
- author: "Steve Jobs",
- },
- {
- quote: "Winning isn't everything, but wanting to win is.",
- author: "Vince Lombardi",
- },
- {
- quote:
- "I am not a product of my circumstances. I am a product of my decisions.",
- author: "Stephen Covey",
- },
- {
- quote:
- "Every child is an artist. The problem is how to remain an artist once he grows up.",
- author: "Pablo Picasso",
- },
- {
- quote:
- "You can never cross the ocean until you have the courage to lose sight of the shore.",
- author: "Christopher Columbus",
- },
- {
- quote:
- "I've learned that people will forget what you said, people will forget what you did, but people will never forget how you made them feel.",
- author: "Maya Angelou",
- },
- {
- quote: "Either you run the day, or the day runs you.",
- author: "Jim Rohn",
- },
- {
- quote: "Whether you think you can or you think you can't, you're right.",
- author: "Henry Ford",
- },
- {
- quote:
- "The two most important days in your life are the day you are born and the day you find out why.",
- author: "Mark Twain",
- },
- {
- quote:
- "Whatever you can do, or dream you can, begin it. Boldness has genius, power and magic in it.",
- author: "Johann Wolfgang von Goethe",
- },
- {
- quote: "The best revenge is massive success.",
- author: "Frank Sinatra",
- },
- {
- quote:
- "People often say that motivation doesn't last. Well, neither does bathing. That's why we recommend it daily.",
- author: "Zig Ziglar",
- },
- {
- quote: "Life shrinks or expands in proportion to one's courage.",
- author: "Anais Nin",
- },
- {
- quote:
- "If you hear a voice within you say “you cannot paint,” then by all means paint and that voice will be silenced.",
- author: "Vincent Van Gogh",
- },
- {
- quote:
- "There is only one way to avoid criticism: do nothing, say nothing, and be nothing.",
- author: "Aristotle",
- },
- {
- quote:
- "Ask and it will be given to you; search, and you will find; knock and the door will be opened for you.",
- author: "Jesus",
- },
- {
- quote:
- "The only person you are destined to become is the person you decide to be.",
- author: "Ralph Waldo Emerson",
- },
- {
- quote:
- "Go confidently in the direction of your dreams. Live the life you have imagined.",
- author: "Henry David Thoreau",
- },
- {
- quote:
- "When I stand before God at the end of my life, I would hope that I would not have a single bit of talent left and could say, I used everything you gave me.",
- author: "Erma Bombeck",
- },
- {
- quote:
- "Few things can help an individual more than to place responsibility on him, and to let him know that you trust him.",
- author: "Booker T. Washington",
- },
- {
- quote:
- "Certain things catch your eye, but pursue only those that capture the heart.",
- author: " Ancient Indian Proverb",
- },
- {
- quote: "Believe you can and you're halfway there.",
- author: "Theodore Roosevelt",
- },
- {
- quote: "Everything you've ever wanted is on the other side of fear.",
- author: "George Addair",
- },
- {
- quote:
- "We can easily forgive a child who is afraid of the dark; the real tragedy of life is when men are afraid of the light.",
- author: "Plato",
- },
- {
- quote:
- "Teach thy tongue to say, “I do not know,” and thous shalt progress.",
- author: "Maimonides",
- },
- {
- quote: "Start where you are. Use what you have. Do what you can.",
- author: "Arthur Ashe",
- },
- {
- quote:
- "When I was 5 years old, my mother always told me that happiness was the key to life. When I went to school, they asked me what I wanted to be when I grew up. I wrote down ‘happy'. They told me I didn't understand the assignment, and I told them they didn't understand life.",
- author: "John Lennon",
- },
- {
- quote: "Fall seven times and stand up eight.",
- author: "Japanese Proverb",
- },
- {
- quote:
- "When one door of happiness closes, another opens, but often we look so long at the closed door that we do not see the one that has been opened for us.",
- author: "Helen Keller",
- },
- {
- quote: "Everything has beauty, but not everyone can see.",
- author: "Confucius",
- },
- {
- quote:
- "How wonderful it is that nobody need wait a single moment before starting to improve the world.",
- author: "Anne Frank",
- },
- {
- quote: "When I let go of what I am, I become what I might be.",
- author: "Lao Tzu",
- },
- {
- quote:
- "Life is not measured by the number of breaths we take, but by the moments that take our breath away.",
- author: "Maya Angelou",
- },
- {
- quote:
- "Happiness is not something readymade. It comes from your own actions.",
- author: "Dalai Lama",
- },
- {
- quote:
- "If you're offered a seat on a rocket ship, don't ask what seat! Just get on.",
- author: "Sheryl Sandberg",
- },
- {
- quote:
- "First, have a definite, clear practical ideal; a goal, an objective. Second, have the necessary means to achieve your ends; wisdom, money, materials, and methods. Third, adjust all your means to that end.",
- author: "Aristotle",
- },
- {
- quote: "If the wind will not serve, take to the oars.",
- author: "Latin Proverb",
- },
- {
- quote:
- "You can't fall if you don't climb. But there's no joy in living your whole life on the ground.",
- author: "Unknown",
- },
- {
- quote:
- "We must believe that we are gifted for something, and that this thing, at whatever cost, must be attained.",
- author: "Marie Curie",
- },
- {
- quote:
- "Too many of us are not living our dreams because we are living our fears.",
- author: "Les Brown",
- },
- {
- quote:
- "Challenges are what make life interesting and overcoming them is what makes life meaningful.",
- author: "Joshua J. Marine",
- },
- {
- quote: "If you want to lift yourself up, lift up someone else.",
- author: "Booker T. Washington",
- },
- {
- quote:
- "I have been impressed with the urgency of doing. Knowing is not enough; we must apply. Being willing is not enough; we must do.",
- author: "Leonardo da Vinci",
- },
- {
- quote:
- "Limitations live only in our minds. But if we use our imaginations, our possibilities become limitless.",
- author: "Jamie Paolinetti",
- },
- {
- quote:
- "You take your life in your own hands, and what happens? A terrible thing, no one to blame.",
- author: "Erica Jong",
- },
- {
- quote:
- "What's money? A man is a success if he gets up in the morning and goes to bed at night and in between does what he wants to do.",
- author: "Bob Dylan",
- },
- {
- quote: "I didn't fail the test. I just found 100 ways to do it wrong.",
- author: "Benjamin Franklin",
- },
- {
- quote:
- "In order to succeed, your desire for success should be greater than your fear of failure.",
- author: "Bill Cosby",
- },
- {
- quote: "A person who never made a mistake never tried anything new.",
- author: " Albert Einstein",
- },
- {
- quote:
- "The person who says it cannot be done should not interrupt the person who is doing it.",
- author: "Chinese Proverb",
- },
- {
- quote: "There are no traffic jams along the extra mile.",
- author: "Roger Staubach",
- },
- {
- quote: "It is never too late to be what you might have been.",
- author: "George Eliot",
- },
- {
- quote: "You become what you believe.",
- author: "Oprah Winfrey",
- },
- {
- quote: "I would rather die of passion than of boredom.",
- author: "Vincent van Gogh",
- },
- {
- quote:
- "A truly rich man is one whose children run into his arms when his hands are empty.",
- author: "Unknown",
- },
- {
- quote:
- "It is not what you do for your children, but what you have taught them to do for themselves, that will make them successful human beings.",
- author: "Ann Landers",
- },
- {
- quote:
- "If you want your children to turn out well, spend twice as much time with them, and half as much money.",
- author: "Abigail Van Buren",
- },
- {
- quote:
- "Build your own dreams, or someone else will hire you to build theirs.",
- author: "Farrah Gray",
- },
- {
- quote:
- "The battles that count aren't the ones for gold medals. The struggles within yourself-the invisible battles inside all of us-that's where it's at.",
- author: "Jesse Owens",
- },
- {
- quote: "Education costs money. But then so does ignorance.",
- author: "Sir Claus Moser",
- },
- {
- quote:
- "I have learned over the years that when one's mind is made up, this diminishes fear.",
- author: "Rosa Parks",
- },
- {
- quote: "It does not matter how slowly you go as long as you do not stop.",
- author: "Confucius",
- },
- {
- quote:
- "If you look at what you have in life, you'll always have more. If you look at what you don't have in life, you'll never have enough.",
- author: "Oprah Winfrey",
- },
- {
- quote:
- "Remember that not getting what you want is sometimes a wonderful stroke of luck.",
- author: "Dalai Lama",
- },
- {
- quote: "You can't use up creativity. The more you use, the more you have.",
- author: "Maya Angelou",
- },
- {
- quote: "Dream big and dare to fail.",
- author: "Norman Vaughan",
- },
- {
- quote:
- "Our lives begin to end the day we become silent about things that matter.",
- author: "Martin Luther King Jr.",
- },
- {
- quote: "Do what you can, where you are, with what you have.",
- author: "Teddy Roosevelt",
- },
- {
- quote:
- "If you do what you've always done, you'll get what you've always gotten.",
- author: "Tony Robbins",
- },
- {
- quote: "Dreaming, after all, is a form of planning.",
- author: "Gloria Steinem",
- },
- {
- quote:
- "It's your place in the world; it's your life. Go on and do all you can with it, and make it the life you want to live.",
- author: "Mae Jemison",
- },
- {
- quote:
- "You may be disappointed if you fail, but you are doomed if you don't try.",
- author: "Beverly Sills",
- },
- {
- quote: "Remember no one can make you feel inferior without your consent.",
- author: "Eleanor Roosevelt",
- },
- {
- quote: "Life is what we make it, always has been, always will be.",
- author: "Grandma Moses",
- },
- {
- quote:
- "The question isn't who is going to let me; it's who is going to stop me.",
- author: "Ayn Rand",
- },
- {
- quote:
- "When everything seems to be going against you, remember that the airplane takes off against the wind, not with it.",
- author: "Henry Ford",
- },
- {
- quote:
- "It's not the years in your life that count. It's the life in your years.",
- author: "Abraham Lincoln",
- },
- {
- quote: "Change your thoughts and you change your world.",
- author: "Norman Vincent Peale",
- },
- {
- quote:
- "Either write something worth reading or do something worth writing.",
- author: "Benjamin Franklin",
- },
- {
- quote: "Nothing is impossible, the word itself says, “I'm possible!”",
- author: "-Audrey Hepburn",
- },
- {
- quote: "The only way to do great work is to love what you do.",
- author: "Steve Jobs",
- },
- {
- quote: "If you can dream it, you can achieve it.",
- author: "Zig Ziglar",
- },
-];
-
-// call pickFromArray with the quotes array to check you get a random quote
+// DO NOT EDIT BELOW HERE
+
+// pickFromArray is a function which will return one item, at
+// random, from the given array.
+//
+// Parameters
+// ----------
+// choices: an array of items to pick from.
+//
+// Returns
+// -------
+// One item at random from the given array.
+//
+// Examples of use
+// ---------------
+// pickFromArray(['a','b','c','d']) // maybe returns 'c'
+
+// You don't need to change this function
+function pickFromArray(choices) {
+ return choices[Math.floor(Math.random() * choices.length)];
+}
+
+// A list of quotes you can use in your app.
+// DO NOT modify this array, otherwise the tests may break!
+const quotes = [
+ {
+ quote: "Life isn't about getting and having, it's about giving and being.",
+ author: "Kevin Kruse",
+ },
+ {
+ quote: "Whatever the mind of man can conceive and believe, it can achieve.",
+ author: "Napoleon Hill",
+ },
+ {
+ quote: "Strive not to be a success, but rather to be of value.",
+ author: "Albert Einstein",
+ },
+ {
+ quote:
+ "Two roads diverged in a wood, and I—I took the one less traveled by, And that has made all the difference.",
+ author: "Robert Frost",
+ },
+ {
+ quote: "I attribute my success to this: I never gave or took any excuse.",
+ author: "Florence Nightingale",
+ },
+ {
+ quote: "You miss 100% of the shots you don't take.",
+ author: "Wayne Gretzky",
+ },
+ {
+ quote:
+ "I've missed more than 9000 shots in my career. I've lost almost 300 games. 26 times I've been trusted to take the game winning shot and missed. I've failed over and over and over again in my life. And that is why I succeed.",
+ author: "Michael Jordan",
+ },
+ {
+ quote:
+ "The most difficult thing is the decision to act, the rest is merely tenacity.",
+ author: "Amelia Earhart",
+ },
+ {
+ quote: "Every strike brings me closer to the next home run.",
+ author: "Babe Ruth",
+ },
+ {
+ quote: "Definiteness of purpose is the starting point of all achievement.",
+ author: "W. Clement Stone",
+ },
+ {
+ quote: "We must balance conspicuous consumption with conscious capitalism.",
+ author: "Kevin Kruse",
+ },
+ {
+ quote: "Life is what happens to you while you're busy making other plans.",
+ author: "John Lennon",
+ },
+ {
+ quote: "We become what we think about.",
+ author: "Earl Nightingale",
+ },
+ {
+ quote:
+ "Twenty years from now you will be more disappointed by the things that you didn't do than by the ones you did do, so throw off the bowlines, sail away from safe harbor, catch the trade winds in your sails. Explore, Dream, Discover.",
+ author: "Mark Twain",
+ },
+ {
+ quote: "Life is 10% what happens to me and 90% of how I react to it.",
+ author: "Charles Swindoll",
+ },
+ {
+ quote:
+ "The most common way people give up their power is by thinking they don't have any.",
+ author: "Alice Walker",
+ },
+ {
+ quote: "The mind is everything. What you think you become.",
+ author: "Buddha",
+ },
+ {
+ quote:
+ "The best time to plant a tree was 20 years ago. The second best time is now.",
+ author: "Chinese Proverb",
+ },
+ {
+ quote: "An unexamined life is not worth living.",
+ author: "Socrates",
+ },
+ {
+ quote: "Eighty percent of success is showing up.",
+ author: "Woody Allen",
+ },
+ {
+ quote:
+ "Your time is limited, so don't waste it living someone else's life.",
+ author: "Steve Jobs",
+ },
+ {
+ quote: "Winning isn't everything, but wanting to win is.",
+ author: "Vince Lombardi",
+ },
+ {
+ quote:
+ "I am not a product of my circumstances. I am a product of my decisions.",
+ author: "Stephen Covey",
+ },
+ {
+ quote:
+ "Every child is an artist. The problem is how to remain an artist once he grows up.",
+ author: "Pablo Picasso",
+ },
+ {
+ quote:
+ "You can never cross the ocean until you have the courage to lose sight of the shore.",
+ author: "Christopher Columbus",
+ },
+ {
+ quote:
+ "I've learned that people will forget what you said, people will forget what you did, but people will never forget how you made them feel.",
+ author: "Maya Angelou",
+ },
+ {
+ quote: "Either you run the day, or the day runs you.",
+ author: "Jim Rohn",
+ },
+ {
+ quote: "Whether you think you can or you think you can't, you're right.",
+ author: "Henry Ford",
+ },
+ {
+ quote:
+ "The two most important days in your life are the day you are born and the day you find out why.",
+ author: "Mark Twain",
+ },
+ {
+ quote:
+ "Whatever you can do, or dream you can, begin it. Boldness has genius, power and magic in it.",
+ author: "Johann Wolfgang von Goethe",
+ },
+ {
+ quote: "The best revenge is massive success.",
+ author: "Frank Sinatra",
+ },
+ {
+ quote:
+ "People often say that motivation doesn't last. Well, neither does bathing. That's why we recommend it daily.",
+ author: "Zig Ziglar",
+ },
+ {
+ quote: "Life shrinks or expands in proportion to one's courage.",
+ author: "Anais Nin",
+ },
+ {
+ quote:
+ "If you hear a voice within you say “you cannot paint,” then by all means paint and that voice will be silenced.",
+ author: "Vincent Van Gogh",
+ },
+ {
+ quote:
+ "There is only one way to avoid criticism: do nothing, say nothing, and be nothing.",
+ author: "Aristotle",
+ },
+ {
+ quote:
+ "Ask and it will be given to you; search, and you will find; knock and the door will be opened for you.",
+ author: "Jesus",
+ },
+ {
+ quote:
+ "The only person you are destined to become is the person you decide to be.",
+ author: "Ralph Waldo Emerson",
+ },
+ {
+ quote:
+ "Go confidently in the direction of your dreams. Live the life you have imagined.",
+ author: "Henry David Thoreau",
+ },
+ {
+ quote:
+ "When I stand before God at the end of my life, I would hope that I would not have a single bit of talent left and could say, I used everything you gave me.",
+ author: "Erma Bombeck",
+ },
+ {
+ quote:
+ "Few things can help an individual more than to place responsibility on him, and to let him know that you trust him.",
+ author: "Booker T. Washington",
+ },
+ {
+ quote:
+ "Certain things catch your eye, but pursue only those that capture the heart.",
+ author: " Ancient Indian Proverb",
+ },
+ {
+ quote: "Believe you can and you're halfway there.",
+ author: "Theodore Roosevelt",
+ },
+ {
+ quote: "Everything you've ever wanted is on the other side of fear.",
+ author: "George Addair",
+ },
+ {
+ quote:
+ "We can easily forgive a child who is afraid of the dark; the real tragedy of life is when men are afraid of the light.",
+ author: "Plato",
+ },
+ {
+ quote:
+ "Teach thy tongue to say, “I do not know,” and thous shalt progress.",
+ author: "Maimonides",
+ },
+ {
+ quote: "Start where you are. Use what you have. Do what you can.",
+ author: "Arthur Ashe",
+ },
+ {
+ quote:
+ "When I was 5 years old, my mother always told me that happiness was the key to life. When I went to school, they asked me what I wanted to be when I grew up. I wrote down ‘happy'. They told me I didn't understand the assignment, and I told them they didn't understand life.",
+ author: "John Lennon",
+ },
+ {
+ quote: "Fall seven times and stand up eight.",
+ author: "Japanese Proverb",
+ },
+ {
+ quote:
+ "When one door of happiness closes, another opens, but often we look so long at the closed door that we do not see the one that has been opened for us.",
+ author: "Helen Keller",
+ },
+ {
+ quote: "Everything has beauty, but not everyone can see.",
+ author: "Confucius",
+ },
+ {
+ quote:
+ "How wonderful it is that nobody need wait a single moment before starting to improve the world.",
+ author: "Anne Frank",
+ },
+ {
+ quote: "When I let go of what I am, I become what I might be.",
+ author: "Lao Tzu",
+ },
+ {
+ quote:
+ "Life is not measured by the number of breaths we take, but by the moments that take our breath away.",
+ author: "Maya Angelou",
+ },
+ {
+ quote:
+ "Happiness is not something readymade. It comes from your own actions.",
+ author: "Dalai Lama",
+ },
+ {
+ quote:
+ "If you're offered a seat on a rocket ship, don't ask what seat! Just get on.",
+ author: "Sheryl Sandberg",
+ },
+ {
+ quote:
+ "First, have a definite, clear practical ideal; a goal, an objective. Second, have the necessary means to achieve your ends; wisdom, money, materials, and methods. Third, adjust all your means to that end.",
+ author: "Aristotle",
+ },
+ {
+ quote: "If the wind will not serve, take to the oars.",
+ author: "Latin Proverb",
+ },
+ {
+ quote:
+ "You can't fall if you don't climb. But there's no joy in living your whole life on the ground.",
+ author: "Unknown",
+ },
+ {
+ quote:
+ "We must believe that we are gifted for something, and that this thing, at whatever cost, must be attained.",
+ author: "Marie Curie",
+ },
+ {
+ quote:
+ "Too many of us are not living our dreams because we are living our fears.",
+ author: "Les Brown",
+ },
+ {
+ quote:
+ "Challenges are what make life interesting and overcoming them is what makes life meaningful.",
+ author: "Joshua J. Marine",
+ },
+ {
+ quote: "If you want to lift yourself up, lift up someone else.",
+ author: "Booker T. Washington",
+ },
+ {
+ quote:
+ "I have been impressed with the urgency of doing. Knowing is not enough; we must apply. Being willing is not enough; we must do.",
+ author: "Leonardo da Vinci",
+ },
+ {
+ quote:
+ "Limitations live only in our minds. But if we use our imaginations, our possibilities become limitless.",
+ author: "Jamie Paolinetti",
+ },
+ {
+ quote:
+ "You take your life in your own hands, and what happens? A terrible thing, no one to blame.",
+ author: "Erica Jong",
+ },
+ {
+ quote:
+ "What's money? A man is a success if he gets up in the morning and goes to bed at night and in between does what he wants to do.",
+ author: "Bob Dylan",
+ },
+ {
+ quote: "I didn't fail the test. I just found 100 ways to do it wrong.",
+ author: "Benjamin Franklin",
+ },
+ {
+ quote:
+ "In order to succeed, your desire for success should be greater than your fear of failure.",
+ author: "Bill Cosby",
+ },
+ {
+ quote: "A person who never made a mistake never tried anything new.",
+ author: " Albert Einstein",
+ },
+ {
+ quote:
+ "The person who says it cannot be done should not interrupt the person who is doing it.",
+ author: "Chinese Proverb",
+ },
+ {
+ quote: "There are no traffic jams along the extra mile.",
+ author: "Roger Staubach",
+ },
+ {
+ quote: "It is never too late to be what you might have been.",
+ author: "George Eliot",
+ },
+ {
+ quote: "You become what you believe.",
+ author: "Oprah Winfrey",
+ },
+ {
+ quote: "I would rather die of passion than of boredom.",
+ author: "Vincent van Gogh",
+ },
+ {
+ quote:
+ "A truly rich man is one whose children run into his arms when his hands are empty.",
+ author: "Unknown",
+ },
+ {
+ quote:
+ "It is not what you do for your children, but what you have taught them to do for themselves, that will make them successful human beings.",
+ author: "Ann Landers",
+ },
+ {
+ quote:
+ "If you want your children to turn out well, spend twice as much time with them, and half as much money.",
+ author: "Abigail Van Buren",
+ },
+ {
+ quote:
+ "Build your own dreams, or someone else will hire you to build theirs.",
+ author: "Farrah Gray",
+ },
+ {
+ quote:
+ "The battles that count aren't the ones for gold medals. The struggles within yourself-the invisible battles inside all of us-that's where it's at.",
+ author: "Jesse Owens",
+ },
+ {
+ quote: "Education costs money. But then so does ignorance.",
+ author: "Sir Claus Moser",
+ },
+ {
+ quote:
+ "I have learned over the years that when one's mind is made up, this diminishes fear.",
+ author: "Rosa Parks",
+ },
+ {
+ quote: "It does not matter how slowly you go as long as you do not stop.",
+ author: "Confucius",
+ },
+ {
+ quote:
+ "If you look at what you have in life, you'll always have more. If you look at what you don't have in life, you'll never have enough.",
+ author: "Oprah Winfrey",
+ },
+ {
+ quote:
+ "Remember that not getting what you want is sometimes a wonderful stroke of luck.",
+ author: "Dalai Lama",
+ },
+ {
+ quote: "You can't use up creativity. The more you use, the more you have.",
+ author: "Maya Angelou",
+ },
+ {
+ quote: "Dream big and dare to fail.",
+ author: "Norman Vaughan",
+ },
+ {
+ quote:
+ "Our lives begin to end the day we become silent about things that matter.",
+ author: "Martin Luther King Jr.",
+ },
+ {
+ quote: "Do what you can, where you are, with what you have.",
+ author: "Teddy Roosevelt",
+ },
+ {
+ quote:
+ "If you do what you've always done, you'll get what you've always gotten.",
+ author: "Tony Robbins",
+ },
+ {
+ quote: "Dreaming, after all, is a form of planning.",
+ author: "Gloria Steinem",
+ },
+ {
+ quote:
+ "It's your place in the world; it's your life. Go on and do all you can with it, and make it the life you want to live.",
+ author: "Mae Jemison",
+ },
+ {
+ quote:
+ "You may be disappointed if you fail, but you are doomed if you don't try.",
+ author: "Beverly Sills",
+ },
+ {
+ quote: "Remember no one can make you feel inferior without your consent.",
+ author: "Eleanor Roosevelt",
+ },
+ {
+ quote: "Life is what we make it, always has been, always will be.",
+ author: "Grandma Moses",
+ },
+ {
+ quote:
+ "The question isn't who is going to let me; it's who is going to stop me.",
+ author: "Ayn Rand",
+ },
+ {
+ quote:
+ "When everything seems to be going against you, remember that the airplane takes off against the wind, not with it.",
+ author: "Henry Ford",
+ },
+ {
+ quote:
+ "It's not the years in your life that count. It's the life in your years.",
+ author: "Abraham Lincoln",
+ },
+ {
+ quote: "Change your thoughts and you change your world.",
+ author: "Norman Vincent Peale",
+ },
+ {
+ quote:
+ "Either write something worth reading or do something worth writing.",
+ author: "Benjamin Franklin",
+ },
+ {
+ quote: "Nothing is impossible, the word itself says, “I'm possible!”",
+ author: "-Audrey Hepburn",
+ },
+ {
+ quote: "The only way to do great work is to love what you do.",
+ author: "Steve Jobs",
+ },
+ {
+ quote: "If you can dream it, you can achieve it.",
+ author: "Zig Ziglar",
+ },
+];
+
+// call pickFromArray with the quotes array to check you get a random quote
diff --git a/Sprint-3/quote-generator/quotes.test.js b/Sprint-3/quote-generator/quotes.test.js
index 288ab4651..e7183c37d 100644
--- a/Sprint-3/quote-generator/quotes.test.js
+++ b/Sprint-3/quote-generator/quotes.test.js
@@ -1,78 +1,78 @@
-/* ======= TESTS - DO NOT MODIFY =====
-There are some Tests in this file that will help you work out if your code is working.
-*/
-
-const path = require("path");
-const { JSDOM } = require("jsdom");
-const { default: userEvent } = require("@testing-library/user-event");
-
-let page = null;
-
-beforeEach(async () => {
- page = await JSDOM.fromFile(path.join(__dirname, "index.html"), {
- resources: "usable",
- runScripts: "dangerously",
- });
-
- // do this so students can use element.innerText which jsdom does not implement
- Object.defineProperty(page.window.HTMLElement.prototype, "innerText", {
- get() {
- return this.textContent;
- },
- set(value) {
- this.textContent = value;
- },
- });
-
- jest
- .spyOn(page.window.Math, "random")
- .mockReturnValueOnce(0.02) // random number to target Albert Einstein quote [index: 2]
- .mockReturnValueOnce(0.25) // random number to target Maya Angelou quote [index: 25]
- .mockReturnValueOnce(0.79); // random number to target Rosa Parks quote [index: 80]
-
- return new Promise((res) => {
- page.window.document.addEventListener("load", res);
- });
-});
-
-afterEach(() => {
- page = null;
- jest.restoreAllMocks();
-});
-
-describe("Quote generator", () => {
- test("initially displays quote and author", () => {
- const quoteP = page.window.document.querySelector("#quote");
- const authorP = page.window.document.querySelector("#author");
-
- expect(quoteP).toHaveTextContent(
- "Strive not to be a success, but rather to be of value."
- );
- expect(authorP).toHaveTextContent("Albert Einstein");
- });
- test("can change quote to another random quote", () => {
- const quoteP = page.window.document.querySelector("#quote");
- const authorP = page.window.document.querySelector("#author");
- const newQuoteBtn = page.window.document.querySelector("#new-quote");
-
- expect(quoteP).toHaveTextContent(
- "Strive not to be a success, but rather to be of value."
- );
- expect(authorP).toHaveTextContent("Albert Einstein");
- expect(newQuoteBtn).toHaveTextContent("New quote");
-
- userEvent.click(newQuoteBtn);
-
- expect(quoteP).toHaveTextContent(
- "I've learned that people will forget what you said, people will forget what you did, but people will never forget how you made them feel."
- );
- expect(authorP).toHaveTextContent("Maya Angelou");
-
- userEvent.click(newQuoteBtn);
-
- expect(quoteP).toHaveTextContent(
- "I have learned over the years that when one's mind is made up, this diminishes fear."
- );
- expect(authorP).toHaveTextContent("Rosa Parks");
- });
-});
+/* ======= TESTS - DO NOT MODIFY =====
+There are some Tests in this file that will help you work out if your code is working.
+*/
+
+const path = require("path");
+const { JSDOM } = require("jsdom");
+const { default: userEvent } = require("@testing-library/user-event");
+
+let page = null;
+
+beforeEach(async () => {
+ page = await JSDOM.fromFile(path.join(__dirname, "index.html"), {
+ resources: "usable",
+ runScripts: "dangerously",
+ });
+
+ // do this so students can use element.innerText which jsdom does not implement
+ Object.defineProperty(page.window.HTMLElement.prototype, "innerText", {
+ get() {
+ return this.textContent;
+ },
+ set(value) {
+ this.textContent = value;
+ },
+ });
+
+ jest
+ .spyOn(page.window.Math, "random")
+ .mockReturnValueOnce(0.02) // random number to target Albert Einstein quote [index: 2]
+ .mockReturnValueOnce(0.25) // random number to target Maya Angelou quote [index: 25]
+ .mockReturnValueOnce(0.79); // random number to target Rosa Parks quote [index: 80]
+
+ return new Promise((res) => {
+ page.window.document.addEventListener("load", res);
+ });
+});
+
+afterEach(() => {
+ page = null;
+ jest.restoreAllMocks();
+});
+
+describe("Quote generator", () => {
+ test("initially displays quote and author", () => {
+ const quoteP = page.window.document.querySelector("#quote");
+ const authorP = page.window.document.querySelector("#author");
+
+ expect(quoteP).toHaveTextContent(
+ "Strive not to be a success, but rather to be of value."
+ );
+ expect(authorP).toHaveTextContent("Albert Einstein");
+ });
+ test("can change quote to another random quote", () => {
+ const quoteP = page.window.document.querySelector("#quote");
+ const authorP = page.window.document.querySelector("#author");
+ const newQuoteBtn = page.window.document.querySelector("#new-quote");
+
+ expect(quoteP).toHaveTextContent(
+ "Strive not to be a success, but rather to be of value."
+ );
+ expect(authorP).toHaveTextContent("Albert Einstein");
+ expect(newQuoteBtn).toHaveTextContent("New quote");
+
+ userEvent.click(newQuoteBtn);
+
+ expect(quoteP).toHaveTextContent(
+ "I've learned that people will forget what you said, people will forget what you did, but people will never forget how you made them feel."
+ );
+ expect(authorP).toHaveTextContent("Maya Angelou");
+
+ userEvent.click(newQuoteBtn);
+
+ expect(quoteP).toHaveTextContent(
+ "I have learned over the years that when one's mind is made up, this diminishes fear."
+ );
+ expect(authorP).toHaveTextContent("Rosa Parks");
+ });
+});
diff --git a/Sprint-3/quote-generator/readme.md b/Sprint-3/quote-generator/readme.md
index 868291958..54a3b7c02 100644
--- a/Sprint-3/quote-generator/readme.md
+++ b/Sprint-3/quote-generator/readme.md
@@ -1,43 +1,43 @@
-# Make a Quote Generator
-
-In this folder you will find the basic setup of a quote generator.
-
-You can change any of the files in this project.
-
-First off, once you've branched off `main`, then update the title element in `index.html` to "Quote generator app"
-
-## How the Quote Generator should work
-
-When the page loads it should show a random quote from the `quotes` array on the screen. It should also show who said the quote.
-
-When you click a button on the screen it should change the quote on the screen.
-
-It can look however you like but there is an example in this folder at `quote_generator_example.png`
-
-## Need Help?
-
-- If you can't work out how to find a random element from the array, either:
- - (advanced) try to use `Math.random()`
- - OR
- - (basic) use the `pickFromArray()` function supplied in the javascript file.
-
-## Stretch
-
-Only attempt the stretch once you've attempted the other sections.
-
-### Add auto-play to your quote generator
-
-For this task you will return to your quote generator and improve it with "auto-generate" functionality:
-
-- Add a toggle-switch or checkbox input to your existing quote generator.
-- When the switch is ON:
- - ... the generator should pick and display a new quote every 60 seconds. (When testing you will probably want to reduce this to every 5 seconds.)
- - ... the generator should display "auto-play:ON" somewhere on the page.
-- When the switch is OFF
- - ... the generator should NOT change quote automatically
-
-## Hints:
-
-Use https://rot13.com/ to decipher this hint:
-
-`Pubbfr bar bs frgGvzrbhg be frgVagreiny.`
+# Make a Quote Generator
+
+In this folder you will find the basic setup of a quote generator.
+
+You can change any of the files in this project.
+
+First off, once you've branched off `main`, then update the title element in `index.html` to "Quote generator app"
+
+## How the Quote Generator should work
+
+When the page loads it should show a random quote from the `quotes` array on the screen. It should also show who said the quote.
+
+When you click a button on the screen it should change the quote on the screen.
+
+It can look however you like but there is an example in this folder at `quote_generator_example.png`
+
+## Need Help?
+
+- If you can't work out how to find a random element from the array, either:
+ - (advanced) try to use `Math.random()`
+ - OR
+ - (basic) use the `pickFromArray()` function supplied in the javascript file.
+
+## Stretch
+
+Only attempt the stretch once you've attempted the other sections.
+
+### Add auto-play to your quote generator
+
+For this task you will return to your quote generator and improve it with "auto-generate" functionality:
+
+- Add a toggle-switch or checkbox input to your existing quote generator.
+- When the switch is ON:
+ - ... the generator should pick and display a new quote every 60 seconds. (When testing you will probably want to reduce this to every 5 seconds.)
+ - ... the generator should display "auto-play:ON" somewhere on the page.
+- When the switch is OFF
+ - ... the generator should NOT change quote automatically
+
+## Hints:
+
+Use https://rot13.com/ to decipher this hint:
+
+`Pubbfr bar bs frgGvzrbhg be frgVagreiny.`
diff --git a/Sprint-3/quote-generator/style.css b/Sprint-3/quote-generator/style.css
index 63cedf2d2..36fd81a54 100644
--- a/Sprint-3/quote-generator/style.css
+++ b/Sprint-3/quote-generator/style.css
@@ -1 +1 @@
-/** Write your CSS in here **/
+/** Write your CSS in here **/
diff --git a/Sprint-3/reading-list/README.md b/Sprint-3/reading-list/README.md
index 98d75532d..2c24c9b67 100644
--- a/Sprint-3/reading-list/README.md
+++ b/Sprint-3/reading-list/README.md
@@ -1,3 +1,39 @@
+<<<<<<< Updated upstream
+# Reading List
+
+First off, once you've branched off `main`, then update the title element in `index.html` to "Reading list app"
+
+The function **readingList** takes an array of book objects:
+
+```js
+const books = [
+ {
+ title: 'The Design of Everyday Things',
+ author: 'Don Norman',
+ alreadyRead: false,
+ bookCoverImage: 'https://blackwells.co.uk/jacket/l/9780465050659.jpg',
+ },
+ {
+ title: 'The Most Human Human',
+ author: 'Brian Christian',
+ alreadyRead: true,
+ bookCoverImage:
+ 'https://images-na.ssl-images-amazon.com/images/I/41m1rQjm5tL._SX322_BO1,204,203,200_.jpg',
+ },
+ ...
+];
+```
+
+Render the list of books on the page. Each book should have a title, author and image and a background colour that is set dependent on whether we have read the book or not.
+
+## 🧭 Strategy
+
+Try and outline your strategy / approach for solving this problem before you get started. There is also a test suite provided to help you meet the acceptance criteria in the issue.
+
+The end result should look something like this
+
+
+=======
# Reading List
First off, once you've branched off `main`, then update the title element in `index.html` to "Reading list app"
@@ -24,7 +60,7 @@ const books = [
```
Render the list of books on the page. Each book should have a title, author and image and a background colour that is set dependent on whether we have read the book or not.
-
+//title author image. background-colour = red if read before
## 🧭 Strategy
Try and outline your strategy / approach for solving this problem before you get started. There is also a test suite provided to help you meet the acceptance criteria in the issue.
@@ -32,3 +68,4 @@ Try and outline your strategy / approach for solving this problem before you get
The end result should look something like this

+>>>>>>> Stashed changes
diff --git a/Sprint-3/reading-list/index.html b/Sprint-3/reading-list/index.html
index dbdb0f471..555253063 100644
--- a/Sprint-3/reading-list/index.html
+++ b/Sprint-3/reading-list/index.html
@@ -1,10 +1,27 @@
+<<<<<<< Updated upstream
+
+
+
+
+
+
+ Title here
+
+
+
+
+
+
+
+
+=======
- Title here
+ Reading list app
@@ -13,3 +30,4 @@
+>>>>>>> Stashed changes
diff --git a/Sprint-3/reading-list/jest.setup.js b/Sprint-3/reading-list/jest.setup.js
index 9e785813a..2223e65df 100644
--- a/Sprint-3/reading-list/jest.setup.js
+++ b/Sprint-3/reading-list/jest.setup.js
@@ -1 +1 @@
-require("@testing-library/jest-dom");
+require("@testing-library/jest-dom");
diff --git a/Sprint-3/reading-list/package.json b/Sprint-3/reading-list/package.json
index d11906db8..1d372950a 100644
--- a/Sprint-3/reading-list/package.json
+++ b/Sprint-3/reading-list/package.json
@@ -1,3 +1,34 @@
+<<<<<<< Updated upstream
+{
+ "name": "readinglist",
+ "version": "1.0.0",
+ "license": "CC-BY-SA-4.0",
+ "description": "You must update this package",
+ "scripts": {
+ "test": "jest"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/CodeYourFuture/CYF-Coursework-Template.git"
+ },
+ "bugs": {
+ "url": "https://github.com/CodeYourFuture/CYF-Coursework-Template/issues"
+ },
+ "homepage": "https://github.com/CodeYourFuture/CYF-Coursework-Template#readme",
+ "devDependencies": {
+ "@testing-library/dom": "^8.19.0",
+ "@testing-library/jest-dom": "^5.16.5",
+ "@testing-library/user-event": "^13.5.0",
+ "jest": "^29.2.2",
+ "jest-environment-jsdom": "^29.2.2"
+ },
+ "jest": {
+ "setupFilesAfterEnv": [
+ "./jest.setup.js"
+ ]
+ }
+}
+=======
{
"name": "readinglist",
"version": "1.0.0",
@@ -18,7 +49,7 @@
"@testing-library/dom": "^8.19.0",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/user-event": "^13.5.0",
- "jest": "^29.2.2",
+ "jest": "^29.7.0",
"jest-environment-jsdom": "^29.2.2"
},
"jest": {
@@ -27,3 +58,4 @@
]
}
}
+>>>>>>> Stashed changes
diff --git a/Sprint-3/reading-list/script.js b/Sprint-3/reading-list/script.js
index 6024d73a0..f0ef31b43 100644
--- a/Sprint-3/reading-list/script.js
+++ b/Sprint-3/reading-list/script.js
@@ -1,4 +1,60 @@
+<<<<<<< Updated upstream
+// for the tests, do not modify this array of books
+const books = [
+ {
+ title: "The Design of Everyday Things",
+ author: "Don Norman",
+ alreadyRead: false,
+ bookCoverImage: "https://blackwells.co.uk/jacket/l/9780465050659.jpg",
+ },
+ {
+ title: "The Most Human Human",
+ author: "Brian Christian",
+ alreadyRead: true,
+ bookCoverImage:
+ "https://images-na.ssl-images-amazon.com/images/I/41m1rQjm5tL._SX322_BO1,204,203,200_.jpg",
+ },
+ {
+ title: "The Pragmatic Programmer",
+ author: "Andrew Hunt",
+ alreadyRead: true,
+ bookCoverImage: "https://blackwells.co.uk/jacket/l/9780135957059.jpg",
+ },
+];
+
+=======
// for the tests, do not modify this array of books
+
+function renderBooks(){
+ const readingList = document.createElement("div");
+ // bookList.className = "book-list"; the fault in my stars.
+ readingList.id = "reading-list";
+
+ books.forEach((book) => {
+ const bookItem = document.createElement("div");
+ bookItem.className = "book-item";
+ bookItem.style.backgroundColor = book.alreadyRead ? "red" : "white" ;
+
+ const bookTitle = document.createElement("h2");
+ bookTitle.innerText = `Title: ${book.title}`;
+
+ const bookAuthor = document.createElement("p");
+ bookAuthor.innerText = `Author: ${book.author}`;
+
+ const bookImage = document.createElement("img");
+ bookImage.src = book.bookCoverImage;
+ bookImage.alt = `Image missing ${book.title}`;
+
+ bookItem.appendChild(bookTitle);
+ bookItem.appendChild(bookAuthor);
+ bookItem.appendChild(bookImage);
+ readingList.appendChild(bookItem);
+ });
+ document.body.appendChild(readingList);
+}
+
+window.onload = renderBooks;
+
const books = [
{
title: "The Design of Everyday Things",
@@ -21,3 +77,4 @@ const books = [
},
];
+>>>>>>> Stashed changes
diff --git a/Sprint-3/reading-list/script.test.js b/Sprint-3/reading-list/script.test.js
index 4e3d7367d..ee05e6210 100644
--- a/Sprint-3/reading-list/script.test.js
+++ b/Sprint-3/reading-list/script.test.js
@@ -1,83 +1,83 @@
-const path = require("path");
-const { JSDOM } = require("jsdom");
-const { default: userEvent } = require("@testing-library/user-event");
-
-let page = null;
-
-beforeEach(async () => {
- page = await JSDOM.fromFile(path.join(__dirname, "index.html"), {
- resources: "usable",
- runScripts: "dangerously",
- });
-
- // do this so students can use element.innerText which jsdom does not implement
- Object.defineProperty(page.window.HTMLElement.prototype, "innerText", {
- get() {
- return this.textContent;
- },
- set(value) {
- this.textContent = value;
- },
- });
-
- return new Promise((res) => {
- page.window.document.addEventListener("load", res);
- });
-});
-
-afterEach(() => {
- page = null;
-});
-
-describe("Reading list", () => {
- test("renders a list of books with author and title", () => {
- const readingList = page.window.document.querySelector("#reading-list");
-
- expect(readingList).toHaveTextContent("The Design of Everyday Things");
- expect(readingList).toHaveTextContent("Don Norman");
-
- expect(readingList).toHaveTextContent("The Most Human Human");
- expect(readingList).toHaveTextContent("Brian Christian");
-
- expect(readingList).toHaveTextContent("The Pragmatic Programmer");
- expect(readingList).toHaveTextContent("Andrew Hunt");
- });
- test("each book in the list has an image", () => {
- const firstLi = page.window.document.querySelector(
- "#reading-list > :first-child"
- );
- expect(firstLi).toContainHTML(
- ``
- );
-
- const secondLi = page.window.document.querySelector(
- "#reading-list > :nth-child(2)"
- );
- expect(secondLi).toContainHTML(
- ``
- );
-
- const thirdLi = page.window.document.querySelector(
- "#reading-list > :nth-child(3)"
- );
- expect(thirdLi).toContainHTML(
- ``
- );
- });
- test("background color changes depending on whether book has been read", () => {
- const firstLi = page.window.document.querySelector(
- "#reading-list > :first-child"
- );
- expect(firstLi).toHaveStyle({ backgroundColor: "red" });
-
- const secondLi = page.window.document.querySelector(
- "#reading-list > :nth-child(2)"
- );
- expect(secondLi).toHaveStyle({ backgroundColor: "green" });
-
- const thirdLi = page.window.document.querySelector(
- "#reading-list > :nth-child(3)"
- );
- expect(thirdLi).toHaveStyle({ backgroundColor: "green" });
- });
-});
+const path = require("path");
+const { JSDOM } = require("jsdom");
+const { default: userEvent } = require("@testing-library/user-event");
+
+let page = null;
+
+beforeEach(async () => {
+ page = await JSDOM.fromFile(path.join(__dirname, "index.html"), {
+ resources: "usable",
+ runScripts: "dangerously",
+ });
+
+ // do this so students can use element.innerText which jsdom does not implement
+ Object.defineProperty(page.window.HTMLElement.prototype, "innerText", {
+ get() {
+ return this.textContent;
+ },
+ set(value) {
+ this.textContent = value;
+ },
+ });
+
+ return new Promise((res) => {
+ page.window.document.addEventListener("load", res);
+ });
+});
+
+afterEach(() => {
+ page = null;
+});
+
+describe("Reading list", () => {
+ test("renders a list of books with author and title", () => {
+ const readingList = page.window.document.querySelector("#reading-list");
+
+ expect(readingList).toHaveTextContent("The Design of Everyday Things");
+ expect(readingList).toHaveTextContent("Don Norman");
+
+ expect(readingList).toHaveTextContent("The Most Human Human");
+ expect(readingList).toHaveTextContent("Brian Christian");
+
+ expect(readingList).toHaveTextContent("The Pragmatic Programmer");
+ expect(readingList).toHaveTextContent("Andrew Hunt");
+ });
+ test("each book in the list has an image", () => {
+ const firstLi = page.window.document.querySelector(
+ "#reading-list > :first-child"
+ );
+ expect(firstLi).toContainHTML(
+ ``
+ );
+
+ const secondLi = page.window.document.querySelector(
+ "#reading-list > :nth-child(2)"
+ );
+ expect(secondLi).toContainHTML(
+ ``
+ );
+
+ const thirdLi = page.window.document.querySelector(
+ "#reading-list > :nth-child(3)"
+ );
+ expect(thirdLi).toContainHTML(
+ ``
+ );
+ });
+ test("background color changes depending on whether book has been read", () => {
+ const firstLi = page.window.document.querySelector(
+ "#reading-list > :first-child"
+ );
+ expect(firstLi).toHaveStyle({ backgroundColor: "red" });
+
+ const secondLi = page.window.document.querySelector(
+ "#reading-list > :nth-child(2)"
+ );
+ expect(secondLi).toHaveStyle({ backgroundColor: "green" });
+
+ const thirdLi = page.window.document.querySelector(
+ "#reading-list > :nth-child(3)"
+ );
+ expect(thirdLi).toHaveStyle({ backgroundColor: "green" });
+ });
+});
diff --git a/Sprint-3/reading-list/style.css b/Sprint-3/reading-list/style.css
index 74406e64f..8e6f8d63b 100644
--- a/Sprint-3/reading-list/style.css
+++ b/Sprint-3/reading-list/style.css
@@ -1,9 +1,172 @@
+<<<<<<< Updated upstream
+/**
+ * Base styles to use at the start of the class
+ *
+ * Module: HTML/CSS
+ * Lesson: 1,2
+ * Class: Scotland 2017
+ */
+
+html,
+body {
+ font-family: "Source Sans Pro", -apple-system, system-ui, BlinkMacSystemFont,
+ "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
+}
+
+.site-footer {
+ margin-top: 4em;
+}
+
+.site-footer p {
+ border-top: 1px solid #dccdc6;
+ padding-top: 2em;
+ padding-bottom: 2em;
+}
+
+.navbar-brand > img {
+ max-height: 40px;
+ width: auto;
+}
+
+.navbar-light .navbar-nav .nav-link {
+ color: #292b2c;
+ font-weight: 600;
+ text-transform: uppercase;
+}
+
+/* Buttons */
+.btn {
+ border-radius: 0.15em;
+}
+
+/* Alert */
+.alert {
+ position: relative;
+ margin-top: 2em;
+ margin-bottom: 3em;
+ padding-top: 1.5em;
+ padding-bottom: 1.5em;
+ border: 1px solid #dccdc6;
+ border-radius: 0;
+ font-size: 0.85rem;
+ line-height: 1.3em;
+ background: transparent;
+ color: #292b2c;
+}
+
+.alert:before {
+ content: "";
+ position: absolute;
+ left: -1px;
+ top: 0;
+ height: 100%;
+ width: 1px;
+ background: #ce5f31;
+}
+
+/* Jumbotron */
+.jumbotron {
+ border-radius: 0;
+}
+
+/* Headings */
+.heading-underline {
+ position: relative;
+ margin-bottom: 2em;
+ padding-bottom: 0.5em;
+ border-bottom: 1px solid #dccdc6;
+ font-size: 1rem;
+ font-weight: 600;
+ text-transform: uppercase;
+}
+
+.heading-underline:before {
+ content: "";
+ position: absolute;
+ bottom: -1px;
+ left: 0;
+ width: 25%;
+ height: 1px;
+ max-width: 100px;
+ background: #ce5f31;
+}
+
+/* Article */
+.article {
+ margin-bottom: 2em;
+}
+
+.article-title {
+ margin-bottom: 0.5em;
+ font-weight: 700;
+}
+
+.article-read-more a {
+ font-size: 0.85em;
+ font-weight: 700;
+ text-decoration: uppercase;
+}
+
+.article-read-more a:hover,
+.article-read-more a:focus {
+ text-decoration: none;
+}
+
+.article-read-more .fa {
+ margin-right: 0.5em;
+ color: #ce5f31;
+}
+
+.article-read-more:last-child {
+ margin-bottom: 0;
+}
+
+.red {
+ background-color: red;
+}
+
+.addArticle {
+ margin-bottom: 10px;
+}
+
+#addArticleBtn {
+ margin-left: 20px;
+ height: 37px;
+}
+
+.colorButton {
+ margin-bottom: 20px;
+ margin-right: 20px;
+ width: 100px;
+ height: 50px;
+}
+
+#blueBtn {
+ background: #588fbd;
+}
+
+#orangeBtn {
+ background: #f0ad4e;
+}
+
+#greenBtn {
+ background: #87ca8a;
+}
+
+@media screen and (min-width: 992px) {
+ .navbar-brand > img {
+ max-height: 80px;
+ }
+}
+=======
/**
* Base styles to use at the start of the class
*
* Module: HTML/CSS
* Lesson: 1,2
* Class: Scotland 2017
+
+ i just left this css as is.
*/
html,
@@ -157,3 +320,4 @@ body {
max-height: 80px;
}
}
+>>>>>>> Stashed changes
diff --git a/Sprint-3/slideshow-extra/readme.md b/Sprint-3/slideshow-extra/readme.md
index 9a667a69e..989b48105 100644
--- a/Sprint-3/slideshow-extra/readme.md
+++ b/Sprint-3/slideshow-extra/readme.md
@@ -1,9 +1,9 @@
-# Extra Task for Slideshow
-
-## Optional: Add UI for delay time
-
-Add UI so that the user can specify how long to wait between images.
-
-## Advanced Challenge: Make it look good
-
-Now is a good time to make it look good with CSS, colour, typography, images, and creativity. Maybe you could ask someone to collaborate with you on those aspects.
+# Extra Task for Slideshow
+
+## Optional: Add UI for delay time
+
+Add UI so that the user can specify how long to wait between images.
+
+## Advanced Challenge: Make it look good
+
+Now is a good time to make it look good with CSS, colour, typography, images, and creativity. Maybe you could ask someone to collaborate with you on those aspects.
diff --git a/Sprint-3/slideshow/index.html b/Sprint-3/slideshow/index.html
index 50f2eb1c0..ef20dd8d6 100644
--- a/Sprint-3/slideshow/index.html
+++ b/Sprint-3/slideshow/index.html
@@ -1,14 +1,14 @@
-
-
-
-
-
- Title here
-
-
-
-
-
-
-
-
+
+
+
+
+
+ Title here
+
+
+
+
+
+
+
+
diff --git a/Sprint-3/slideshow/jest.setup.js b/Sprint-3/slideshow/jest.setup.js
index 9e785813a..2223e65df 100644
--- a/Sprint-3/slideshow/jest.setup.js
+++ b/Sprint-3/slideshow/jest.setup.js
@@ -1 +1 @@
-require("@testing-library/jest-dom");
+require("@testing-library/jest-dom");
diff --git a/Sprint-3/slideshow/package.json b/Sprint-3/slideshow/package.json
index 6928d825f..a02dc1c08 100644
--- a/Sprint-3/slideshow/package.json
+++ b/Sprint-3/slideshow/package.json
@@ -1,29 +1,29 @@
-{
- "name": "slideshow",
- "version": "1.0.0",
- "license": "CC-BY-SA-4.0",
- "description": "You must update this package",
- "scripts": {
- "test": "jest"
- },
- "repository": {
- "type": "git",
- "url": "git+https://github.com/CodeYourFuture/CYF-Coursework-Template.git"
- },
- "bugs": {
- "url": "https://github.com/CodeYourFuture/CYF-Coursework-Template/issues"
- },
- "homepage": "https://github.com/CodeYourFuture/CYF-Coursework-Template#readme",
- "devDependencies": {
- "@testing-library/dom": "^8.19.0",
- "@testing-library/jest-dom": "^5.16.5",
- "@testing-library/user-event": "^13.5.0",
- "jest": "^29.2.2",
- "jest-environment-jsdom": "^29.2.2"
- },
- "jest": {
- "setupFilesAfterEnv": [
- "./jest.setup.js"
- ]
- }
-}
+{
+ "name": "slideshow",
+ "version": "1.0.0",
+ "license": "CC-BY-SA-4.0",
+ "description": "You must update this package",
+ "scripts": {
+ "test": "jest"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/CodeYourFuture/CYF-Coursework-Template.git"
+ },
+ "bugs": {
+ "url": "https://github.com/CodeYourFuture/CYF-Coursework-Template/issues"
+ },
+ "homepage": "https://github.com/CodeYourFuture/CYF-Coursework-Template#readme",
+ "devDependencies": {
+ "@testing-library/dom": "^8.19.0",
+ "@testing-library/jest-dom": "^5.16.5",
+ "@testing-library/user-event": "^13.5.0",
+ "jest": "^29.2.2",
+ "jest-environment-jsdom": "^29.2.2"
+ },
+ "jest": {
+ "setupFilesAfterEnv": [
+ "./jest.setup.js"
+ ]
+ }
+}
diff --git a/Sprint-3/slideshow/readme.md b/Sprint-3/slideshow/readme.md
index a0c06e4ff..38cf3ac9f 100644
--- a/Sprint-3/slideshow/readme.md
+++ b/Sprint-3/slideshow/readme.md
@@ -1,82 +1,82 @@
-# Challenge: "Image Carousel"
-
-First off, once you've branched off `main`, then update the title element in `index.html` to "Image carousel"
-
-## Challenge Overview
-
-Make a website which allows the user to navigate a set of images (first manually, then with an auto-playing slideshow).
-
-[Try this live demo!](https://cyf-image-carousel.netlify.app/)
-
-# Level 1 Challenge
-
-Make forward and back buttons to move _manually_ in that direction through a list of at least 4 images.
-
-(e.g. When the user presses forward once, the display should move ONCE to the next image.)
-
-You can use any images.
-
-You can store the images within your app or you can use links to images hosted elsewhere ("hotlinking").
-
-[Unsplash](https://unsplash.com/) is a good source of images for this challenge.
-
-Level 1 challenge screenshot example.
-
-
-
-# Level 2 Challenge
-
-Make auto-forward and auto-back buttons to _automatically_ move in that direction through the list of images.
-
-Here's a screenshot example from a completed level 2 challenge.
-
-
-
-## Try to finish the rest by yourself
-
-If you want a harder challenge, don't read the rest of this document but instead try to build the app by yourself.
-
-If you want hints, then you will find some below.
-
-## Suggested approach
-
-Here's one approach you might take to building this app.
-
-### Task: Design your layout _on paper_
-
-Design your layout on paper. Keep it very simple - this is a JavaScript challenge, not a CSS challenge.
-
-Use a layout that will be ok on a phone (but _don't_ spend time on responsive design).
-
-Keep this drawing around for reference later.
-
-### Task: Convert your layout to HTML
-
-Convert the drawing to HTML (on codepen or elsewhere) and check the buttons appear correctly.
-
-_DON'T_ add any CSS or extra markup to make it look good just now. That will only make it more difficult for you to think about your app during development.
-
-#### Task: Make the buttons work
-
-Make your buttons work to navigate forwards and backwards, manually.
-
-### Task: more buttons - automated slideshow
-
-Add the following buttons:
-
-- auto-forward
-- stop
-- auto-backwards
-
-These should allow automatic navigation through the images, say every 5 seconds.
-
-### End of basic challenge!
-
-Congratulations, you've finished the basics!
-
-- Make sure you can access it and play with it on a smartphone!
-- Celebrate!
-
-## Further work
-
-See the `extra` folder of homework for further ideas for your Slideshow.
+# Challenge: "Image Carousel"
+
+First off, once you've branched off `main`, then update the title element in `index.html` to "Image carousel"
+
+## Challenge Overview
+
+Make a website which allows the user to navigate a set of images (first manually, then with an auto-playing slideshow).
+
+[Try this live demo!](https://cyf-image-carousel.netlify.app/)
+
+# Level 1 Challenge
+
+Make forward and back buttons to move _manually_ in that direction through a list of at least 4 images.
+
+(e.g. When the user presses forward once, the display should move ONCE to the next image.)
+
+You can use any images.
+
+You can store the images within your app or you can use links to images hosted elsewhere ("hotlinking").
+
+[Unsplash](https://unsplash.com/) is a good source of images for this challenge.
+
+Level 1 challenge screenshot example.
+
+
+
+# Level 2 Challenge
+
+Make auto-forward and auto-back buttons to _automatically_ move in that direction through the list of images.
+
+Here's a screenshot example from a completed level 2 challenge.
+
+
+
+## Try to finish the rest by yourself
+
+If you want a harder challenge, don't read the rest of this document but instead try to build the app by yourself.
+
+If you want hints, then you will find some below.
+
+## Suggested approach
+
+Here's one approach you might take to building this app.
+
+### Task: Design your layout _on paper_
+
+Design your layout on paper. Keep it very simple - this is a JavaScript challenge, not a CSS challenge.
+
+Use a layout that will be ok on a phone (but _don't_ spend time on responsive design).
+
+Keep this drawing around for reference later.
+
+### Task: Convert your layout to HTML
+
+Convert the drawing to HTML (on codepen or elsewhere) and check the buttons appear correctly.
+
+_DON'T_ add any CSS or extra markup to make it look good just now. That will only make it more difficult for you to think about your app during development.
+
+#### Task: Make the buttons work
+
+Make your buttons work to navigate forwards and backwards, manually.
+
+### Task: more buttons - automated slideshow
+
+Add the following buttons:
+
+- auto-forward
+- stop
+- auto-backwards
+
+These should allow automatic navigation through the images, say every 5 seconds.
+
+### End of basic challenge!
+
+Congratulations, you've finished the basics!
+
+- Make sure you can access it and play with it on a smartphone!
+- Celebrate!
+
+## Further work
+
+See the `extra` folder of homework for further ideas for your Slideshow.
diff --git a/Sprint-3/slideshow/slideshow.js b/Sprint-3/slideshow/slideshow.js
index 063ceefb5..aa2b14f0f 100644
--- a/Sprint-3/slideshow/slideshow.js
+++ b/Sprint-3/slideshow/slideshow.js
@@ -1,8 +1,8 @@
-const images = [
- "./assets/cute-cat-a.png",
- "./assets/cute-cat-b.jpg",
- "./assets/cute-cat-c.jpg",
-];
-
-
+const images = [
+ "./assets/cute-cat-a.png",
+ "./assets/cute-cat-b.jpg",
+ "./assets/cute-cat-c.jpg",
+];
+
+
// Write your code here
\ No newline at end of file
diff --git a/Sprint-3/slideshow/slideshow.test.js b/Sprint-3/slideshow/slideshow.test.js
index 34f802a3e..19cc2b041 100644
--- a/Sprint-3/slideshow/slideshow.test.js
+++ b/Sprint-3/slideshow/slideshow.test.js
@@ -1,227 +1,227 @@
-/* ======= TESTS - DO NOT MODIFY =====
-There are some Tests in this file that will help you work out if your code is working.
-*/
-
-const path = require("path");
-const { JSDOM } = require("jsdom");
-const { default: userEvent } = require("@testing-library/user-event");
-
-let page = null;
-
-beforeEach(async () => {
- page = await JSDOM.fromFile(path.join(__dirname, "index.html"), {
- resources: "usable",
- runScripts: "dangerously",
- });
-
- // do this so students can use element.innerText which jsdom does not implement
- Object.defineProperty(page.window.HTMLElement.prototype, "innerText", {
- get() {
- return this.textContent;
- },
- set(value) {
- this.textContent = value;
- },
- });
-
- return new Promise((res) => {
- page.window.document.addEventListener("load", res);
- });
-});
-
-afterEach(() => {
- page = null;
-});
-
-describe("Level 1 challenge", () => {
- test("renders the first image with control buttons", () => {
- const images = [
- "./assets/cute-cat-a.png",
- "./assets/cute-cat-b.jpg",
- "./assets/cute-cat-c.jpg",
- ];
- const image = page.window.document.querySelector("#carousel-img");
- const forwardBtn = page.window.document.querySelector("#forward-btn");
- const backwardBtn = page.window.document.querySelector("#backward-btn");
-
- expect(image).toHaveAttribute("src", images[0]);
- expect(forwardBtn).toBeInTheDocument();
- expect(backwardBtn).toBeInTheDocument();
- });
- test("can move the image forwards once", () => {
- const images = [
- "./assets/cute-cat-a.png",
- "./assets/cute-cat-b.jpg",
- "./assets/cute-cat-c.jpg",
- ];
- const image = page.window.document.querySelector("#carousel-img");
- const forwardBtn = page.window.document.querySelector("#forward-btn");
-
- expect(image).toHaveAttribute("src", images[0]);
-
- userEvent.click(forwardBtn);
-
- expect(image).toHaveAttribute("src", images[1]);
- });
-
- test("can move the image forwards multiple times", () => {
- const images = [
- "./assets/cute-cat-a.png",
- "./assets/cute-cat-b.jpg",
- "./assets/cute-cat-c.jpg",
- ];
- const image = page.window.document.querySelector("#carousel-img");
- const forwardBtn = page.window.document.querySelector("#forward-btn");
-
- userEvent.click(forwardBtn);
- userEvent.click(forwardBtn);
-
- expect(image).toHaveAttribute("src", images[2]);
- });
-
- test("can move the image backwards to the end", () => {
- const images = [
- "./assets/cute-cat-a.png",
- "./assets/cute-cat-b.jpg",
- "./assets/cute-cat-c.jpg",
- ];
- const image = page.window.document.querySelector("#carousel-img");
- const backwardBtn = page.window.document.querySelector("#backward-btn");
-
- expect(image).toHaveAttribute("src", images[0]);
-
- userEvent.click(backwardBtn);
-
- expect(image).toHaveAttribute("src", images[2]);
- });
-
- test("can move the image backwards multiple times", () => {
- const images = [
- "./assets/cute-cat-a.png",
- "./assets/cute-cat-b.jpg",
- "./assets/cute-cat-c.jpg",
- ];
- const image = page.window.document.querySelector("#carousel-img");
- const backwardBtn = page.window.document.querySelector("#backward-btn");
- expect(image).toHaveAttribute("src", images[0]);
-
- userEvent.click(backwardBtn);
- userEvent.click(backwardBtn);
-
- expect(image).toHaveAttribute("src", images[1]);
- });
-
- test("moving forwards will eventually wrap around to the start", () => {
- const images = [
- "./assets/cute-cat-a.png",
- "./assets/cute-cat-b.jpg",
- "./assets/cute-cat-c.jpg",
- ];
- const image = page.window.document.querySelector("#carousel-img");
- const forwardBtn = page.window.document.querySelector("#forward-btn");
-
- expect(image).toHaveAttribute("src", images[0]);
-
- userEvent.click(forwardBtn);
- userEvent.click(forwardBtn);
- userEvent.click(forwardBtn);
-
- expect(image).toHaveAttribute("src", images[0]);
- });
-});
-
-describe("Level 2 challenge", () => {
- beforeEach(() => {
- jest.useFakeTimers();
- });
- afterEach(() => {
- jest.useRealTimers();
- });
- test("can start moving images forward automatically", () => {
- const images = [
- "./assets/cute-cat-a.png",
- "./assets/cute-cat-b.jpg",
- "./assets/cute-cat-c.jpg",
- ];
- const image = page.window.document.querySelector("#carousel-img");
- const autoForwardBtn = page.window.document.querySelector("#auto-forward");
- const autoBackBtn = page.window.document.querySelector("#auto-backward");
- const interval = 2000;
-
- expect(image).toHaveAttribute("src", images[0]);
-
- userEvent.click(autoForwardBtn);
-
- expect(autoForwardBtn).toBeDisabled();
- expect(autoBackBtn).toBeDisabled();
-
- jest.advanceTimersByTime(interval);
- expect(image).toHaveAttribute("src", images[1]);
-
- jest.advanceTimersByTime(interval);
- expect(image).toHaveAttribute("src", images[2]);
-
- jest.advanceTimersByTime(interval);
- expect(image).toHaveAttribute("src", images[0]);
- });
- test("can start moving images backward automatically", () => {
- const images = [
- "./assets/cute-cat-a.png",
- "./assets/cute-cat-b.jpg",
- "./assets/cute-cat-c.jpg",
- ];
- const image = page.window.document.querySelector("#carousel-img");
- const autoForwardBtn = page.window.document.querySelector("#auto-forward");
- const autoBackBtn = page.window.document.querySelector("#auto-backward");
- const interval = 2000;
-
- expect(image).toHaveAttribute("src", images[0]);
-
- userEvent.click(autoBackBtn);
-
- expect(autoForwardBtn).toBeDisabled();
- expect(autoBackBtn).toBeDisabled();
-
- jest.advanceTimersByTime(interval);
- expect(image).toHaveAttribute("src", images[2]);
-
- jest.advanceTimersByTime(interval);
- expect(image).toHaveAttribute("src", images[1]);
-
- jest.advanceTimersByTime(interval);
- expect(image).toHaveAttribute("src", images[0]);
- });
- test("can stop the automatic timer", () => {
- const images = [
- "./assets/cute-cat-a.png",
- "./assets/cute-cat-b.jpg",
- "./assets/cute-cat-c.jpg",
- ];
- const image = page.window.document.querySelector("#carousel-img");
- const autoForwardBtn = page.window.document.querySelector("#auto-forward");
- const autoBackBtn = page.window.document.querySelector("#auto-backward");
- const stopBtn = page.window.document.querySelector("#stop");
- const interval = 2000;
-
- expect(image).toHaveAttribute("src", images[0]);
-
- userEvent.click(autoForwardBtn);
-
- expect(autoForwardBtn).toBeDisabled();
- expect(autoBackBtn).toBeDisabled();
-
- jest.advanceTimersByTime(interval);
- expect(image).toHaveAttribute("src", images[1]);
-
- jest.advanceTimersByTime(interval);
- expect(image).toHaveAttribute("src", images[2]);
-
- userEvent.click(stopBtn);
-
- expect(autoForwardBtn).toBeEnabled();
- expect(autoBackBtn).toBeEnabled();
-
- jest.runOnlyPendingTimers();
- expect(image).toHaveAttribute("src", images[2]);
- });
-});
+/* ======= TESTS - DO NOT MODIFY =====
+There are some Tests in this file that will help you work out if your code is working.
+*/
+
+const path = require("path");
+const { JSDOM } = require("jsdom");
+const { default: userEvent } = require("@testing-library/user-event");
+
+let page = null;
+
+beforeEach(async () => {
+ page = await JSDOM.fromFile(path.join(__dirname, "index.html"), {
+ resources: "usable",
+ runScripts: "dangerously",
+ });
+
+ // do this so students can use element.innerText which jsdom does not implement
+ Object.defineProperty(page.window.HTMLElement.prototype, "innerText", {
+ get() {
+ return this.textContent;
+ },
+ set(value) {
+ this.textContent = value;
+ },
+ });
+
+ return new Promise((res) => {
+ page.window.document.addEventListener("load", res);
+ });
+});
+
+afterEach(() => {
+ page = null;
+});
+
+describe("Level 1 challenge", () => {
+ test("renders the first image with control buttons", () => {
+ const images = [
+ "./assets/cute-cat-a.png",
+ "./assets/cute-cat-b.jpg",
+ "./assets/cute-cat-c.jpg",
+ ];
+ const image = page.window.document.querySelector("#carousel-img");
+ const forwardBtn = page.window.document.querySelector("#forward-btn");
+ const backwardBtn = page.window.document.querySelector("#backward-btn");
+
+ expect(image).toHaveAttribute("src", images[0]);
+ expect(forwardBtn).toBeInTheDocument();
+ expect(backwardBtn).toBeInTheDocument();
+ });
+ test("can move the image forwards once", () => {
+ const images = [
+ "./assets/cute-cat-a.png",
+ "./assets/cute-cat-b.jpg",
+ "./assets/cute-cat-c.jpg",
+ ];
+ const image = page.window.document.querySelector("#carousel-img");
+ const forwardBtn = page.window.document.querySelector("#forward-btn");
+
+ expect(image).toHaveAttribute("src", images[0]);
+
+ userEvent.click(forwardBtn);
+
+ expect(image).toHaveAttribute("src", images[1]);
+ });
+
+ test("can move the image forwards multiple times", () => {
+ const images = [
+ "./assets/cute-cat-a.png",
+ "./assets/cute-cat-b.jpg",
+ "./assets/cute-cat-c.jpg",
+ ];
+ const image = page.window.document.querySelector("#carousel-img");
+ const forwardBtn = page.window.document.querySelector("#forward-btn");
+
+ userEvent.click(forwardBtn);
+ userEvent.click(forwardBtn);
+
+ expect(image).toHaveAttribute("src", images[2]);
+ });
+
+ test("can move the image backwards to the end", () => {
+ const images = [
+ "./assets/cute-cat-a.png",
+ "./assets/cute-cat-b.jpg",
+ "./assets/cute-cat-c.jpg",
+ ];
+ const image = page.window.document.querySelector("#carousel-img");
+ const backwardBtn = page.window.document.querySelector("#backward-btn");
+
+ expect(image).toHaveAttribute("src", images[0]);
+
+ userEvent.click(backwardBtn);
+
+ expect(image).toHaveAttribute("src", images[2]);
+ });
+
+ test("can move the image backwards multiple times", () => {
+ const images = [
+ "./assets/cute-cat-a.png",
+ "./assets/cute-cat-b.jpg",
+ "./assets/cute-cat-c.jpg",
+ ];
+ const image = page.window.document.querySelector("#carousel-img");
+ const backwardBtn = page.window.document.querySelector("#backward-btn");
+ expect(image).toHaveAttribute("src", images[0]);
+
+ userEvent.click(backwardBtn);
+ userEvent.click(backwardBtn);
+
+ expect(image).toHaveAttribute("src", images[1]);
+ });
+
+ test("moving forwards will eventually wrap around to the start", () => {
+ const images = [
+ "./assets/cute-cat-a.png",
+ "./assets/cute-cat-b.jpg",
+ "./assets/cute-cat-c.jpg",
+ ];
+ const image = page.window.document.querySelector("#carousel-img");
+ const forwardBtn = page.window.document.querySelector("#forward-btn");
+
+ expect(image).toHaveAttribute("src", images[0]);
+
+ userEvent.click(forwardBtn);
+ userEvent.click(forwardBtn);
+ userEvent.click(forwardBtn);
+
+ expect(image).toHaveAttribute("src", images[0]);
+ });
+});
+
+describe("Level 2 challenge", () => {
+ beforeEach(() => {
+ jest.useFakeTimers();
+ });
+ afterEach(() => {
+ jest.useRealTimers();
+ });
+ test("can start moving images forward automatically", () => {
+ const images = [
+ "./assets/cute-cat-a.png",
+ "./assets/cute-cat-b.jpg",
+ "./assets/cute-cat-c.jpg",
+ ];
+ const image = page.window.document.querySelector("#carousel-img");
+ const autoForwardBtn = page.window.document.querySelector("#auto-forward");
+ const autoBackBtn = page.window.document.querySelector("#auto-backward");
+ const interval = 2000;
+
+ expect(image).toHaveAttribute("src", images[0]);
+
+ userEvent.click(autoForwardBtn);
+
+ expect(autoForwardBtn).toBeDisabled();
+ expect(autoBackBtn).toBeDisabled();
+
+ jest.advanceTimersByTime(interval);
+ expect(image).toHaveAttribute("src", images[1]);
+
+ jest.advanceTimersByTime(interval);
+ expect(image).toHaveAttribute("src", images[2]);
+
+ jest.advanceTimersByTime(interval);
+ expect(image).toHaveAttribute("src", images[0]);
+ });
+ test("can start moving images backward automatically", () => {
+ const images = [
+ "./assets/cute-cat-a.png",
+ "./assets/cute-cat-b.jpg",
+ "./assets/cute-cat-c.jpg",
+ ];
+ const image = page.window.document.querySelector("#carousel-img");
+ const autoForwardBtn = page.window.document.querySelector("#auto-forward");
+ const autoBackBtn = page.window.document.querySelector("#auto-backward");
+ const interval = 2000;
+
+ expect(image).toHaveAttribute("src", images[0]);
+
+ userEvent.click(autoBackBtn);
+
+ expect(autoForwardBtn).toBeDisabled();
+ expect(autoBackBtn).toBeDisabled();
+
+ jest.advanceTimersByTime(interval);
+ expect(image).toHaveAttribute("src", images[2]);
+
+ jest.advanceTimersByTime(interval);
+ expect(image).toHaveAttribute("src", images[1]);
+
+ jest.advanceTimersByTime(interval);
+ expect(image).toHaveAttribute("src", images[0]);
+ });
+ test("can stop the automatic timer", () => {
+ const images = [
+ "./assets/cute-cat-a.png",
+ "./assets/cute-cat-b.jpg",
+ "./assets/cute-cat-c.jpg",
+ ];
+ const image = page.window.document.querySelector("#carousel-img");
+ const autoForwardBtn = page.window.document.querySelector("#auto-forward");
+ const autoBackBtn = page.window.document.querySelector("#auto-backward");
+ const stopBtn = page.window.document.querySelector("#stop");
+ const interval = 2000;
+
+ expect(image).toHaveAttribute("src", images[0]);
+
+ userEvent.click(autoForwardBtn);
+
+ expect(autoForwardBtn).toBeDisabled();
+ expect(autoBackBtn).toBeDisabled();
+
+ jest.advanceTimersByTime(interval);
+ expect(image).toHaveAttribute("src", images[1]);
+
+ jest.advanceTimersByTime(interval);
+ expect(image).toHaveAttribute("src", images[2]);
+
+ userEvent.click(stopBtn);
+
+ expect(autoForwardBtn).toBeEnabled();
+ expect(autoBackBtn).toBeEnabled();
+
+ jest.runOnlyPendingTimers();
+ expect(image).toHaveAttribute("src", images[2]);
+ });
+});
diff --git a/Sprint-3/slideshow/style.css b/Sprint-3/slideshow/style.css
index 63cedf2d2..36fd81a54 100644
--- a/Sprint-3/slideshow/style.css
+++ b/Sprint-3/slideshow/style.css
@@ -1 +1 @@
-/** Write your CSS in here **/
+/** Write your CSS in here **/
diff --git a/Sprint-3/todo-list/README.md b/Sprint-3/todo-list/README.md
index 7c6a25c41..c716964e6 100644
--- a/Sprint-3/todo-list/README.md
+++ b/Sprint-3/todo-list/README.md
@@ -1,66 +1,66 @@
-# Todo-list
-
-## Explanation
-
-This is a super handy, super simple to do list.
-
-You will be given a list of tasks which are "To Do". We call these tasks "ToDos"
-
-Each item in the list should have 2 buttons:
-
-- One to click when the ToDo has been completed - it will apply a line-through style to the text of the ToDo.
-- A second to delete the ToDo. This could be used to delete completed ToDos from the list, or remove ToDos that we are no longer interested in doing.
-
-We also want to be able to add ToDos to the list using an input field and a button. When ToDos are created this way they should be added to the list with the 2 above buttons.
-
-More details for the implementation of this challenge can be found in `script.js`
-
-## Installation
-
-To view the website, open index.html in a browser.
-
-## Example Solution
-
-A basic example of this can website can be found here
-
-https://chrisowen101.github.io/ToDoListSolution/
-
-This covers only the basic tasks, not the advanced tasks.
-
-## Instructions
-
-The `populateTodoList()` function should iterate over the list of todos that we are given at the start, it should create a `
` for the todo along with some other stuff that you can find in index.html and below.
-
-The items in the todo list are currently hard-coded into the HTML, refactor the code so that this function creates them and adds the following functionality to them:
-
-Each todo should have this HTML inside it:
-
-```html
-
-
-
-
-```
-
-The first `` tag needs an event listener that applies a line-through text-decoration styling to the text of the todo. It should remove the styling if it is clicked again.
-
-The second `` tag needs an event listener that deletes the parent `
` element from the `
`.
-
-## Advanced Challenge
-
-### Mass delete of completed ToDos
-
-Develop the ToDo list further and allow users to delete all completed ToDos.
-
-Add a button that users can click that will iterate through the list of ToDos and then delete them only if they have been completed.
-
-## Extra Advanced Challenge
-
-### Set deadlines for ToDos
-
-We want users to be able to set, and see, deadlines for their ToDos.
-
-When creating ToDos we want the user to be able to use a datepicker input so they can see when they need to complete the ToDo. The date can be added to the ToDo in the list. If there is no date set when the ToDo is created then this can be skipped.
-
-EXTRA CHALLENGE: instead of displaying the date on the ToDo, implement a countdown of days left until the deadline. You can use the Javascript Date reference to accomplish this:
-https://www.w3schools.com/jsref/jsref_obj_date.asp
+# Todo-list
+
+## Explanation
+
+This is a super handy, super simple to do list.
+
+You will be given a list of tasks which are "To Do". We call these tasks "ToDos"
+
+Each item in the list should have 2 buttons:
+
+- One to click when the ToDo has been completed - it will apply a line-through style to the text of the ToDo.
+- A second to delete the ToDo. This could be used to delete completed ToDos from the list, or remove ToDos that we are no longer interested in doing.
+
+We also want to be able to add ToDos to the list using an input field and a button. When ToDos are created this way they should be added to the list with the 2 above buttons.
+
+More details for the implementation of this challenge can be found in `script.js`
+
+## Installation
+
+To view the website, open index.html in a browser.
+
+## Example Solution
+
+A basic example of this can website can be found here
+
+https://chrisowen101.github.io/ToDoListSolution/
+
+This covers only the basic tasks, not the advanced tasks.
+
+## Instructions
+
+The `populateTodoList()` function should iterate over the list of todos that we are given at the start, it should create a `
` for the todo along with some other stuff that you can find in index.html and below.
+
+The items in the todo list are currently hard-coded into the HTML, refactor the code so that this function creates them and adds the following functionality to them:
+
+Each todo should have this HTML inside it:
+
+```html
+
+
+
+
+```
+
+The first `` tag needs an event listener that applies a line-through text-decoration styling to the text of the todo. It should remove the styling if it is clicked again.
+
+The second `` tag needs an event listener that deletes the parent `
` element from the `
`.
+
+## Advanced Challenge
+
+### Mass delete of completed ToDos
+
+Develop the ToDo list further and allow users to delete all completed ToDos.
+
+Add a button that users can click that will iterate through the list of ToDos and then delete them only if they have been completed.
+
+## Extra Advanced Challenge
+
+### Set deadlines for ToDos
+
+We want users to be able to set, and see, deadlines for their ToDos.
+
+When creating ToDos we want the user to be able to use a datepicker input so they can see when they need to complete the ToDo. The date can be added to the ToDo in the list. If there is no date set when the ToDo is created then this can be skipped.
+
+EXTRA CHALLENGE: instead of displaying the date on the ToDo, implement a countdown of days left until the deadline. You can use the Javascript Date reference to accomplish this:
+https://www.w3schools.com/jsref/jsref_obj_date.asp
diff --git a/Sprint-3/todo-list/index.html b/Sprint-3/todo-list/index.html
index ee3ef64fd..9bc6b6f38 100644
--- a/Sprint-3/todo-list/index.html
+++ b/Sprint-3/todo-list/index.html
@@ -1,27 +1,27 @@
-
-
-
-
-
- Title here
-
-
-
-
-
-
-
+
+
+
+
+
+ Title here
+
+
+
+
+
+
+
diff --git a/Sprint-3/todo-list/jest.setup.js b/Sprint-3/todo-list/jest.setup.js
index 9e785813a..2223e65df 100644
--- a/Sprint-3/todo-list/jest.setup.js
+++ b/Sprint-3/todo-list/jest.setup.js
@@ -1 +1 @@
-require("@testing-library/jest-dom");
+require("@testing-library/jest-dom");
diff --git a/Sprint-3/todo-list/package.json b/Sprint-3/todo-list/package.json
index adf75c4df..088d98b2b 100644
--- a/Sprint-3/todo-list/package.json
+++ b/Sprint-3/todo-list/package.json
@@ -1,29 +1,29 @@
-{
- "name": "todo-list",
- "version": "1.0.0",
- "license": "CC-BY-SA-4.0",
- "description": "You must update this package",
- "scripts": {
- "test": "jest"
- },
- "repository": {
- "type": "git",
- "url": "git+https://github.com/CodeYourFuture/CYF-Coursework-Template.git"
- },
- "bugs": {
- "url": "https://github.com/CodeYourFuture/CYF-Coursework-Template/issues"
- },
- "homepage": "https://github.com/CodeYourFuture/CYF-Coursework-Template#readme",
- "devDependencies": {
- "@testing-library/dom": "^8.19.0",
- "@testing-library/jest-dom": "^5.16.5",
- "@testing-library/user-event": "^13.5.0",
- "jest": "^29.2.2",
- "jest-environment-jsdom": "^29.2.2"
- },
- "jest": {
- "setupFilesAfterEnv": [
- "./jest.setup.js"
- ]
- }
-}
+{
+ "name": "todo-list",
+ "version": "1.0.0",
+ "license": "CC-BY-SA-4.0",
+ "description": "You must update this package",
+ "scripts": {
+ "test": "jest"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/CodeYourFuture/CYF-Coursework-Template.git"
+ },
+ "bugs": {
+ "url": "https://github.com/CodeYourFuture/CYF-Coursework-Template/issues"
+ },
+ "homepage": "https://github.com/CodeYourFuture/CYF-Coursework-Template#readme",
+ "devDependencies": {
+ "@testing-library/dom": "^8.19.0",
+ "@testing-library/jest-dom": "^5.16.5",
+ "@testing-library/user-event": "^13.5.0",
+ "jest": "^29.2.2",
+ "jest-environment-jsdom": "^29.2.2"
+ },
+ "jest": {
+ "setupFilesAfterEnv": [
+ "./jest.setup.js"
+ ]
+ }
+}
diff --git a/Sprint-3/todo-list/script.js b/Sprint-3/todo-list/script.js
index 61982a54f..42613050d 100644
--- a/Sprint-3/todo-list/script.js
+++ b/Sprint-3/todo-list/script.js
@@ -1,25 +1,25 @@
-function populateTodoList(todos) {
- let list = document.getElementById("todo-list");
- // Write your code to create todo list elements with completed and delete buttons here, all todos should display inside the "todo-list" element.
-}
-
-// These are the same todos that currently display in the HTML
-// You will want to remove the ones in the current HTML after you have created them using JavaScript
-let todos = [
- { task: "Wash the dishes", completed: false },
- { task: "Do the shopping", completed: false },
-];
-
-populateTodoList(todos);
-
-// This function will take the value of the input field and add it as a new todo to the bottom of the todo list. These new todos will need the completed and delete buttons adding like normal.
-function addNewTodo(event) {
- // The code below prevents the page from refreshing when we click the 'Add Todo' button.
- event.preventDefault();
- // Write your code here... and remember to reset the input field to be blank after creating a todo!
-}
-
-// Advanced challenge: Write a fucntion that checks the todos in the todo list and deletes the completed ones (we can check which ones are completed by seeing if they have the line-through styling applied or not).
-function deleteAllCompletedTodos() {
- // Write your code here...
-}
+function populateTodoList(todos) {
+ let list = document.getElementById("todo-list");
+ // Write your code to create todo list elements with completed and delete buttons here, all todos should display inside the "todo-list" element.
+}
+
+// These are the same todos that currently display in the HTML
+// You will want to remove the ones in the current HTML after you have created them using JavaScript
+let todos = [
+ { task: "Wash the dishes", completed: false },
+ { task: "Do the shopping", completed: false },
+];
+
+populateTodoList(todos);
+
+// This function will take the value of the input field and add it as a new todo to the bottom of the todo list. These new todos will need the completed and delete buttons adding like normal.
+function addNewTodo(event) {
+ // The code below prevents the page from refreshing when we click the 'Add Todo' button.
+ event.preventDefault();
+ // Write your code here... and remember to reset the input field to be blank after creating a todo!
+}
+
+// Advanced challenge: Write a fucntion that checks the todos in the todo list and deletes the completed ones (we can check which ones are completed by seeing if they have the line-through styling applied or not).
+function deleteAllCompletedTodos() {
+ // Write your code here...
+}
diff --git a/Sprint-3/todo-list/script.test.js b/Sprint-3/todo-list/script.test.js
index 13c897bf0..2e8679f05 100644
--- a/Sprint-3/todo-list/script.test.js
+++ b/Sprint-3/todo-list/script.test.js
@@ -1,162 +1,162 @@
-const path = require("path");
-const { JSDOM } = require("jsdom");
-const { default: userEvent } = require("@testing-library/user-event");
-
-let page = null;
-
-beforeEach(async () => {
- page = await JSDOM.fromFile(path.join(__dirname, "index.html"), {
- resources: "usable",
- runScripts: "dangerously",
- });
-
- // do this so students can use element.innerText which jsdom does not implement
- Object.defineProperty(page.window.HTMLElement.prototype, "innerText", {
- get() {
- return this.textContent;
- },
- set(value) {
- this.textContent = value;
- },
- });
-
- return new Promise((res) => {
- page.window.document.addEventListener("load", res);
- });
-});
-
-afterEach(() => {
- page = null;
-});
-
-describe("Mandatory tasks", () => {
- test("displays the initial list of todos", () => {
- const todoList = page.window.document.querySelector("#todo-list");
- const listItems = [...page.window.document.querySelectorAll("li")];
-
- expect(todoList).toHaveTextContent("Wash the dishes");
- expect(todoList).toHaveTextContent("Do the shopping");
- expect(listItems.length).toBe(2);
- });
-
- test("each todo has a delete and tick icon", () => {
- const listItems = [...page.window.document.querySelectorAll("li")];
-
- listItems.forEach((_, index) => {
- const tickIcon = page.window.document.querySelector(
- `li:nth-child(${index + 1}) i.fa-check`
- );
- const binIcon = page.window.document.querySelector(
- `li:nth-child(${index + 1}) i.fa-trash`
- );
-
- expect(tickIcon).toBeInTheDocument();
- expect(binIcon).toBeInTheDocument();
- });
- });
-
- test("can add a new todo to the list", () => {
- const todoList = page.window.document.querySelector("#todo-list");
- const button = page.window.document.querySelector(".btn");
- const input = page.window.document.querySelector("#todoInput");
- const todoText = "Do CYF coursework";
-
- userEvent.type(input, todoText);
- userEvent.click(button);
-
- expect(todoList).toHaveTextContent(todoText);
-
- const listItems = [...page.window.document.querySelectorAll("li")];
- expect(listItems.length).toBe(3);
- });
-
- test("can strike through a todo when it is completed", () => {
- const li = page.window.document.querySelector("li");
- const tickIcon = page.window.document.querySelector("li i");
-
- userEvent.click(tickIcon);
-
- expect(li).toHaveStyle({
- textDecoration: "line-through",
- });
- });
-
- test("can undo a strikethrough on a todo", () => {
- const li = page.window.document.querySelector("li");
- const tickIcon = page.window.document.querySelector("li i");
- userEvent.click(tickIcon);
-
- expect(li).toHaveStyle({
- textDecoration: "line-through",
- });
-
- userEvent.click(tickIcon);
-
- expect(li).not.toHaveStyle({
- textDecoration: "line-through",
- });
- });
-
- test("can delete a todo from the list", () => {
- const todoList = page.window.document.querySelector("#todo-list");
- const button = page.window.document.querySelector(".btn");
- const input = page.window.document.querySelector("#todoInput");
- const todoText = "Do CYF coursework";
-
- userEvent.type(input, todoText);
- userEvent.click(button);
-
- expect(todoList).toHaveTextContent(todoText);
- const listItems = [...page.window.document.querySelectorAll("li")];
- expect(listItems.length).toBe(3);
-
- const binIcon = page.window.document.querySelector(
- "li:nth-child(3) i.fa-trash"
- );
- userEvent.click(binIcon);
-
- expect(todoList).not.toHaveTextContent(todoText);
- });
-});
-
-describe("Advanced tasks", () => {
- test("can remove all completed todos", () => {
- const todoList = page.window.document.querySelector("#todo-list");
- const button = page.window.document.querySelector(".btn");
- const input = page.window.document.querySelector("#todoInput");
-
- userEvent.type(input, "Do CYF coursework");
- userEvent.click(button);
-
- userEvent.clear(input);
- userEvent.type(input, "Make a sandwich");
- userEvent.click(button);
-
- userEvent.clear(input);
- userEvent.type(input, "Take a break");
- userEvent.click(button);
-
- const tickIcon2 = page.window.document.querySelector(
- "li:nth-child(2) i.fa-check"
- );
- userEvent.click(tickIcon2);
- const tickIcon4 = page.window.document.querySelector(
- "li:nth-child(4) i.fa-check"
- );
- userEvent.click(tickIcon4);
-
- const removeAllCompletedButton = page.window.document.querySelector(
- "#remove-all-completed"
- );
- userEvent.click(removeAllCompletedButton);
-
- const listItems = [...page.window.document.querySelectorAll("li")];
- expect(listItems.length).toBe(3);
- expect(todoList).toHaveTextContent("Wash the dishes");
- expect(todoList).toHaveTextContent("Do CYF coursework");
- expect(todoList).toHaveTextContent("Take a break");
-
- expect(todoList).not.toHaveTextContent("Do the shopping");
- expect(todoList).not.toHaveTextContent("Make a sandwich");
- });
-});
+const path = require("path");
+const { JSDOM } = require("jsdom");
+const { default: userEvent } = require("@testing-library/user-event");
+
+let page = null;
+
+beforeEach(async () => {
+ page = await JSDOM.fromFile(path.join(__dirname, "index.html"), {
+ resources: "usable",
+ runScripts: "dangerously",
+ });
+
+ // do this so students can use element.innerText which jsdom does not implement
+ Object.defineProperty(page.window.HTMLElement.prototype, "innerText", {
+ get() {
+ return this.textContent;
+ },
+ set(value) {
+ this.textContent = value;
+ },
+ });
+
+ return new Promise((res) => {
+ page.window.document.addEventListener("load", res);
+ });
+});
+
+afterEach(() => {
+ page = null;
+});
+
+describe("Mandatory tasks", () => {
+ test("displays the initial list of todos", () => {
+ const todoList = page.window.document.querySelector("#todo-list");
+ const listItems = [...page.window.document.querySelectorAll("li")];
+
+ expect(todoList).toHaveTextContent("Wash the dishes");
+ expect(todoList).toHaveTextContent("Do the shopping");
+ expect(listItems.length).toBe(2);
+ });
+
+ test("each todo has a delete and tick icon", () => {
+ const listItems = [...page.window.document.querySelectorAll("li")];
+
+ listItems.forEach((_, index) => {
+ const tickIcon = page.window.document.querySelector(
+ `li:nth-child(${index + 1}) i.fa-check`
+ );
+ const binIcon = page.window.document.querySelector(
+ `li:nth-child(${index + 1}) i.fa-trash`
+ );
+
+ expect(tickIcon).toBeInTheDocument();
+ expect(binIcon).toBeInTheDocument();
+ });
+ });
+
+ test("can add a new todo to the list", () => {
+ const todoList = page.window.document.querySelector("#todo-list");
+ const button = page.window.document.querySelector(".btn");
+ const input = page.window.document.querySelector("#todoInput");
+ const todoText = "Do CYF coursework";
+
+ userEvent.type(input, todoText);
+ userEvent.click(button);
+
+ expect(todoList).toHaveTextContent(todoText);
+
+ const listItems = [...page.window.document.querySelectorAll("li")];
+ expect(listItems.length).toBe(3);
+ });
+
+ test("can strike through a todo when it is completed", () => {
+ const li = page.window.document.querySelector("li");
+ const tickIcon = page.window.document.querySelector("li i");
+
+ userEvent.click(tickIcon);
+
+ expect(li).toHaveStyle({
+ textDecoration: "line-through",
+ });
+ });
+
+ test("can undo a strikethrough on a todo", () => {
+ const li = page.window.document.querySelector("li");
+ const tickIcon = page.window.document.querySelector("li i");
+ userEvent.click(tickIcon);
+
+ expect(li).toHaveStyle({
+ textDecoration: "line-through",
+ });
+
+ userEvent.click(tickIcon);
+
+ expect(li).not.toHaveStyle({
+ textDecoration: "line-through",
+ });
+ });
+
+ test("can delete a todo from the list", () => {
+ const todoList = page.window.document.querySelector("#todo-list");
+ const button = page.window.document.querySelector(".btn");
+ const input = page.window.document.querySelector("#todoInput");
+ const todoText = "Do CYF coursework";
+
+ userEvent.type(input, todoText);
+ userEvent.click(button);
+
+ expect(todoList).toHaveTextContent(todoText);
+ const listItems = [...page.window.document.querySelectorAll("li")];
+ expect(listItems.length).toBe(3);
+
+ const binIcon = page.window.document.querySelector(
+ "li:nth-child(3) i.fa-trash"
+ );
+ userEvent.click(binIcon);
+
+ expect(todoList).not.toHaveTextContent(todoText);
+ });
+});
+
+describe("Advanced tasks", () => {
+ test("can remove all completed todos", () => {
+ const todoList = page.window.document.querySelector("#todo-list");
+ const button = page.window.document.querySelector(".btn");
+ const input = page.window.document.querySelector("#todoInput");
+
+ userEvent.type(input, "Do CYF coursework");
+ userEvent.click(button);
+
+ userEvent.clear(input);
+ userEvent.type(input, "Make a sandwich");
+ userEvent.click(button);
+
+ userEvent.clear(input);
+ userEvent.type(input, "Take a break");
+ userEvent.click(button);
+
+ const tickIcon2 = page.window.document.querySelector(
+ "li:nth-child(2) i.fa-check"
+ );
+ userEvent.click(tickIcon2);
+ const tickIcon4 = page.window.document.querySelector(
+ "li:nth-child(4) i.fa-check"
+ );
+ userEvent.click(tickIcon4);
+
+ const removeAllCompletedButton = page.window.document.querySelector(
+ "#remove-all-completed"
+ );
+ userEvent.click(removeAllCompletedButton);
+
+ const listItems = [...page.window.document.querySelectorAll("li")];
+ expect(listItems.length).toBe(3);
+ expect(todoList).toHaveTextContent("Wash the dishes");
+ expect(todoList).toHaveTextContent("Do CYF coursework");
+ expect(todoList).toHaveTextContent("Take a break");
+
+ expect(todoList).not.toHaveTextContent("Do the shopping");
+ expect(todoList).not.toHaveTextContent("Make a sandwich");
+ });
+});
diff --git a/Sprint-3/todo-list/style.css b/Sprint-3/todo-list/style.css
index 8b1378917..d3f5a12fa 100644
--- a/Sprint-3/todo-list/style.css
+++ b/Sprint-3/todo-list/style.css
@@ -1 +1 @@
-
+
diff --git a/contributing.md b/contributing.md
index f3c4a9a12..19e7e7d77 100644
--- a/contributing.md
+++ b/contributing.md
@@ -1,17 +1,17 @@
-
-
-# How To Submit Your Coursework
-
-Use Git & Github to submit your coursework as a pull request.
-
-[Creating a pull request](https://curriculum.codeyourfuture.io/guides/create-a-pull-request/)
-
-## Questions & Help
-
-Contributing to a remote codebase is a necessary skill for a professional developer. Opening PRs is mandatory at CYF. It is part of the coursework.
-
-If you cannot submit your coursework you **must** post on Slack to get unblocked.
+
+
+# How To Submit Your Coursework
+
+Use Git & Github to submit your coursework as a pull request.
+
+[Creating a pull request](https://curriculum.codeyourfuture.io/guides/create-a-pull-request/)
+
+## Questions & Help
+
+Contributing to a remote codebase is a necessary skill for a professional developer. Opening PRs is mandatory at CYF. It is part of the coursework.
+
+If you cannot submit your coursework you **must** post on Slack to get unblocked.
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 000000000..55cde53eb
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,6 @@
+{
+ "name": "Module-Data-Groups",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {}
+}
diff --git a/readme.md b/readme.md
index b9d0c065e..b47ec5f73 100644
--- a/readme.md
+++ b/readme.md
@@ -1,19 +1,19 @@
-# Coursework
-
-Like learning a musical instrument, programming requires daily practice.
-
-## Setting up your code editor
-
-There are some tools that will help you to write code. One of these, [Prettier](https://prettier.io/), formats your code, making it easier for you and others to read.
-
-### 1. Using prettier
-
-- In Visual Studio open the extensions panel (see https://code.visualstudio.com/docs/editor/extension-gallery#_browse-and-install-extensions)
-- Search for `Prettier - Code formatter`
-- Click install on the top result
-
-### 2. Enable formatting on save
-
-- In Visual Studio open the settings file (see https://code.visualstudio.com/docs/getstarted/settings#_creating-user-and-workspace-settings)
-- Search for `editor format`
-- Set `editor.formatOnSave` and `editor.formatOnPaste` to true
+# Coursework
+
+Like learning a musical instrument, programming requires daily practice.
+
+## Setting up your code editor
+
+There are some tools that will help you to write code. One of these, [Prettier](https://prettier.io/), formats your code, making it easier for you and others to read.
+
+### 1. Using prettier
+
+- In Visual Studio open the extensions panel (see https://code.visualstudio.com/docs/editor/extension-gallery#_browse-and-install-extensions)
+- Search for `Prettier - Code formatter`
+- Click install on the top result
+
+### 2. Enable formatting on save
+
+- In Visual Studio open the settings file (see https://code.visualstudio.com/docs/getstarted/settings#_creating-user-and-workspace-settings)
+- Search for `editor format`
+- Set `editor.formatOnSave` and `editor.formatOnPaste` to true