Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Finish implementing the myQuery library - all tests pass #2

Open
wants to merge 1 commit into
base: myquery
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions SpecRunner.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<!-- include spec files here... -->
<script type="text/javascript" src="spec/spec-helper.js"></script>
<script type="text/javascript" src="spec/myquery-spec.js"></script>
<script type="text/javascript" src="spec/myqueryfull-spec.js"></script>

</head>

Expand Down
32 changes: 23 additions & 9 deletions spec/myquery-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ describe("myQuery", function () {
});

describe("General each function", function () {
xit("iterates through an array", function () {
it("iterates through an array", function () {
var testResult = [];
var someArray = [10, 20, 30];
$.each(someArray, function (number) {
Expand All @@ -38,31 +38,31 @@ describe("myQuery", function () {

describe("Selectors", function () {

xit("selects an element by id", function() {
it("selects an element by id", function() {
var elem = $('#profile').get(0);
expect(elem.className).toEqual('noice');
});

xit("selects elements by class name", function() {
it("selects elements by class name", function() {
var buttons = $('.button');
expect(buttons.get(0).className).toMatch(/first/);
expect(buttons.get(1).className).toMatch(/second/);
});

xit("selects elements by tag name", function() {
it("selects elements by tag name", function() {
var anchors = $('a');
expect(anchors.length).toEqual(2)
expect(anchors.length).toEqual(2);
expect(anchors.get(0).className).toEqual("button second");
expect(anchors.get(1).className).toEqual("straggler");

var images = $('img');
expect(images.length).toEqual(1)
expect(images.length).toEqual(1);
expect(images.get(0).className).toEqual("avatar");
});
});

describe("Selected elements each function", function () {
xit("iterates through all selected elements", function() {
it("iterates through all selected elements", function() {
var testResult = [];
$('.button').each(function (elem, i) {
testResult.push(elem.className + ' ' + i);
Expand All @@ -76,16 +76,26 @@ describe("myQuery", function () {

describe("Show and Hide", function () {
// TODO: Write tests for .show() and .hide()
it("hides or shows a selected element", function() {
$('.button').hide();
expect( $('.button').get(0).style.display ).toEqual('none');
$('.button').show();
expect( $('.button').get(0).style.display ).toEqual('block');
});
});

describe("addClass", function () {
// TODO: Write tests for addClass
// HINT: Test using .toMatch() like the selector test
it("adds a class to a selected element", function() {
$('.button').addClass('active');
expect( $('.button').get(0).className ).toMatch(/active/);
});
});

describe("Modifying CSS", function () {

xit("can set a single property", function() {
it("can set a single property", function() {
// Ensure they're not already hidden
expect( $('.button').get(0).style.display ).toEqual('');
expect( $('.button').get(1).style.display ).toEqual('');
Expand All @@ -97,7 +107,11 @@ describe("myQuery", function () {
});

// TODO: (`it` without a function are pending tests)
it("can set multiple properties in one call");
it("can set multiple properties in one call", function() {
$('.button').css({'color': 'red', 'display': 'none'});
expect( $('.button').get(0).style.color ).toEqual('red');
expect( $('.button').get(0).style.display ).toEqual('none');
});
});

});
150 changes: 150 additions & 0 deletions spec/myqueryfull-spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
describe("myQuery", function () {

beforeEach(function () {
// `setFixtures` comes from the jasmine-jquery plugin.
// Although *you* are not using jQuery, we use this plugin to
// help us create HTML elements for testing.
//
// Key point: The HTML elements we create here are available
// for our tests to select. They also get destroyed after each test.
setFixtures(
'<div id="profile" class="noice">' +
'<div class="button first"></div>' +
'<img class="avatar" />' +
'<a class="button second"></a>' +
'<a class="straggler"><label>Click meh</label></a>' +
'</div>'
);
});

it("has a version of value 'beta'", function() {
expect($.version).toEqual('beta');
});

describe("General each function", function () {
it("iterates through an array", function () {
var testResult = [];
var someArray = [10, 20, 30];
$.each(someArray, function (number) {
testResult.push(number * number);
});

expect(testResult.length).toEqual(3);
expect(testResult[0]).toEqual(100);
expect(testResult[1]).toEqual(400);
expect(testResult[2]).toEqual(900);
});
});

describe("Selectors", function () {

it("selects an element by id", function() {
var elem = $('#profile').get(0);
expect(elem.className).toEqual('noice');
});

it("selects elements by class name", function() {
var buttons = $('.button');
expect(buttons.get(0).className).toMatch(/first/);
expect(buttons.get(1).className).toMatch(/second/);
});

it("selects elements by tag name", function() {
var anchors = $('a');
expect(anchors.length).toEqual(2)
expect(anchors.get(0).className).toEqual("button second");
expect(anchors.get(1).className).toEqual("straggler");

var images = $('img');
expect(images.length).toEqual(1)
expect(images.get(0).className).toEqual("avatar");
});
});

describe("Selected elements each function", function () {
it("iterates through all selected elements", function() {
var testResult = [];
$('.button').each(function (elem, i) {
testResult.push(elem.className + ' ' + i);
});

expect(testResult.length).toEqual(2);
expect(testResult[0]).toEqual("button first 0");
expect(testResult[1]).toEqual("button second 1");
});
})

describe("Show and Hide", function () {
// TODO: Write tests for .show() and .hide()
it("hides an element", function() {
var button = $('.button').hide();
expect($('.button').get(0).style.display).toEqual("none");
expect($('.button').get(1).style.display).toEqual("none");
});

it("shows an element", function() {
$('.button').hide();
var button = $('.button').show();
expect($('.button').get(0).style.display).toEqual("block");
expect($('.button').get(1).style.display).toEqual("block");
});
});

describe("addClass", function () {
// TODO: Write tests for addClass
// HINT: Test using .toMatch() like the selector test
it("adds a class to an element", function() {
$('.button').addClass('fuzzles');
expect($('.button').get(0).className).toMatch(/fuzzles/);
});

it("does not allow two classes of the same name on an element", function () {
$('.button').addClass('pancake');
$('.button').addClass('pancake');
expect($('.button').get(0).className).not.toMatch(/pancake pancake/);
})
});

describe("Modifying CSS", function () {

it("can set a single property", function() {
// Ensure they're not already hidden
expect( $('.button').get(0).style.display ).toEqual('');
expect( $('.button').get(1).style.display ).toEqual('');

// Now make sure displays have updated
$('.button').css('display', 'none');
expect( $('.button').get(0).style.display ).toEqual('none');
expect( $('.button').get(1).style.display ).toEqual('none');
});

it("can set multiple properties in one call", function() {
$('.button').css({"border": "1px solid red", "height": "100px"});

expect( $('.button').get(0).style.border ).toEqual("1px solid red");
expect( $('.button').get(0).style.height ).toEqual("100px");

expect( $('.button').get(1).style.border ).toEqual("1px solid red");
expect( $('.button').get(1).style.height ).toEqual("100px");
});
});

describe("Chaining", function () {
it("can chain multiple calls", function() {
$('.button').show().hide().show().hide();
expect($('.button').get(0).style.display).toEqual("none");
expect($('.button').get(1).style.display).toEqual("none");
});
});

describe("Software Design Requirements", function () {
it("does not use jQuery", function() {
expect('' + $).not.toMatch(/jQuery/);
});

it("does not use querySelector or querySelectorAll", function() {
expect('' + $).not.toMatch(/querySelector(All)?/);
});
});

});
30 changes: 30 additions & 0 deletions spec/spec-helper.js
Original file line number Diff line number Diff line change
@@ -1 +1,31 @@
// Any test helpers go here


// /**
// * Hide element(s) from DOM
// * @returns {*}
// */
// hide: function () {
// var len = this.length;
// // Here we simply loop through our object (this) and set the css to display none.
// //If you got more that 1 node from DOM selected with querySelectorAll, you would hide them all.
// while (len--) {
// this[len].style.display = 'none';
// }

// // It's important to return this if you want to chain methods!
// return this;
// },

// /**
// * Show element(s) from DOM
// * @returns {*}
// */
// show: function () {
// var len = this.length;
// while (len--) {
// this[len].style.display = 'block';
// }

// return this;
// }
89 changes: 87 additions & 2 deletions src/myquery.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,97 @@

var QueryWrapper = function (elems) {
// TODO
this.get = function(index) {
return elems[index];
};
this.length = elems.length;
this.each = function(func) {
for(var i = 0; i < elems.length; i++) {
func(elems[i], i);
}
};
this.hide = function() {
this.each(function(elems) {
elems.style.display = "none";
});
return this;
};
this.show = function() {
this.each(function(elems) {
elems.style.display = "block";
});
return this;
};
this.addClass = function(className) {
this.each(function(elems) {
elems.className += className;
});
return this;
};
this.css = function(object, property) {

// if (arguments.length === 2) {
if (typeof object == 'string' || object instanceof String) {
this.each(function(elems) {
elems.style[object] = property;
});
} else {
this.each(function(elems) {
for (var prop in object) {
elems.style[prop] = object[prop]
}
});
};
return this;
};
};

var myQuery = function (selector) {
// TODO
if (selector[0] == '#') {
selector = selector.slice(1)
elements = [document.getElementById(selector)]
}
else if (selector[0] == '.') {
class_selector = selector.slice(1)
elements = document.getElementsByClassName(class_selector)
}
else {
elements = document.getElementsByTagName(selector)
}
return new QueryWrapper(elements)
};

window.$ = myQuery;

window.$ = myQuery;
$.version = "beta"

$.each = function(array, func) {
for(var i = 0; i < array.length; i++) {
func(array[i]);
}
};
})();

// FOR EXTENSIONS
// var rexClass = /(\.[_a-z]+[_a-z0-9-:\\]*)/ig;
// var rexId = /(#[a-z]+[_a-z0-9-:\\]*)/ig;
// var rexTag = /([a-z]+[_a-z0-9-:\\]*)/ig;
// var elements = [];

// // for (var i = 0; i < selector.length; i++) {

// if ( selector[i].match(rexId) == selector[i] ) {
// result = document.getElementById(...);
// elements.push(result);
// }
// else if (selector[i].match(rexClass) == selector[i] ) {
// result = document.getElementByClassName(selector[i]);
// elements.push(result);
// }
// else if (selector[i].match(rexTag) == selector[i] ) {
// result = document.getElementByTagName(selector[i]);
// elements.push(result);
// }
// };