Skip to content

Instantly share code, notes, and snippets.

@sergeyromanov
Created December 9, 2014 01:30
Show Gist options
  • Save sergeyromanov/266e2b73d805c35f73ec to your computer and use it in GitHub Desktop.
Save sergeyromanov/266e2b73d805c35f73ec to your computer and use it in GitHub Desktop.
// jsbootcamp, task1
// by Sergey Romanov
// simple test function
function ok(got, expect, desc) {
if (got === expect) {
console.log('ok --', desc);
} else {
console.log("fail\n\tgot:", got, "expected:", expect, '--', desc);
}
}
function BookStore() {
this._counter = 1;
this._books = [];
}
var _p = BookStore.prototype;
// _lookup* functions are part of private API, they
// deal with internal representation of an object
// does regex (partial) matching
_p._lookup_lax = function(search_term) {
var result = [];
var books = this._books;
var re = RegExp(search_term, 'i');
for (var i = 0; i < books.length; i++) {
if (books[i].title.match(re)) {
result.push(i);
}
}
return result.length > 0 ? result : null;
}
// does strict matching
_p._lookup_strict = function(search_term) {
var books = this._books;
for (var i = 0; i < books.length; i++) {
if (books[i].title === search_term) {
return i;
}
}
return null;
}
_p._lookup_by_id = function(id) {
var books = this._books;
for (var i = 0; i < books.length; i++) {
if (books[i].id === id) {
return i;
}
}
return null;
}
_p._lookup = function(term, type) {
var result;
if (typeof(term) === 'number') {
result = this._lookup_by_id(term);
} else if (typeof(type) !== 'string' || type !== 'strict') {
result = this._lookup_lax(term);
} else {
result = this._lookup_strict(term);
}
if (result === null) {
return null;
}
switch (typeof(result)) {
case 'number':
return [this._books[result]];
case 'object':
return result.map(function(index) {
return this._books[index];
}, this);
}
}
_p.find = function(search_term) {
if (arguments.length === 0) {
return [];
}
return this._lookup(search_term, 'lax') || [];
}
_p.add = function() {
var result = [];
for (var i = 0; i < arguments.length; i++) {
item = arguments[i];
if (typeof(item) !== 'object' || this._lookup(item.title, 'strict')) {
continue;
}
item.id = this._counter++
this._books.push(item);
result.push(item);
}
return result.length ? result : 0;
}
_p.remove = function() {
var result = [];
for (var i = 0; i < arguments.length; i++) {
var term = arguments[i];
var index = null;
if (typeof(term) === 'number') {
index = this._lookup_by_id(term);
} else if (typeof(term) === 'string') {
index = this._lookup_strict(term);
} else if (typeof(term) === 'object') {
index = this._lookup_strict(term.title);
}
if (index === null) {
continue;
}
result.push(this._books[index]);
this._books.splice(index, 1);
}
return result;
}
_p.all = function() {
return this._books.slice();
}
_p.print = function() {
if (arguments.length === 0) {
this.all().forEach(function(el) {
this.print(el);
}, this);
return null;
}
for (var i = 0; i < arguments.length; i++) {
item = arguments[i];
if (item instanceof Array) {
item.forEach(function(el) {
this.print(el);
}, this);
} else if (typeof(item) === 'object') {
console.log("Title:", item.title);
} else {
continue;
}
}
return null;
}
var store = new BookStore();
var book1 = { title: 'Преступление и наказание' };
var book2 = { title: 'На дне' };
var book3 = { title: 'Обломов' };
var book4 = { title: 'Мы' };
var book5 = { title: "Cat's Cradle" };
ok(store instanceof BookStore, true, 'store object is valid');
ok(store.add(book1).length, 1, 'simple add');
ok(store.add(), 0, 'empty add');
ok(store.add(1, 'foo', book4).length, 1, 'garbage add');
ok(store.add(book1, book2, book3, book4).length, 2, 'multiple add');
ok(store.find('Мы').length, 1, 'lax search [1]');
ok(store.find('на').length, 2, 'lax search [2]');
ok(store.find().length, 0, 'empty search');
ok(store.find(1).length, 1, 'search by id (existing)');
ok(store.find(42).length, 0, 'search by id (missing)');
ok(store.all().length, 4, 'get all');
ok(store.remove(store.find(book3.title)[0].id).length, 1, 'remove by id');
ok(store.all().length, 3, '1 object was removed from store');
ok(store.remove(book1, book2).length, 2, 'remove objects');
ok(store.remove(42).length, 0, 'nop remove');
ok(store.add(book5).length, 1, 'add new book');
ok(store.remove({}, "Hobbit", book5).length, 1, 'mixed remove');
ok(store.all().length, 1, '2 objects were removed from store');
ok(store.remove(book4.title).length, 1, 'remove by title');
ok(store.all().length, 0, 'store is empty');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment