Skip to content

Commit

Permalink
Merge pull request #21 from smithki/development
Browse files Browse the repository at this point in the history
Release v0.11.3
  • Loading branch information
smithki committed Oct 1, 2019
2 parents cbd2f63 + ee071d0 commit d1b55f7
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 68 deletions.
137 changes: 81 additions & 56 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# ---------------------------------------------------------------------------- #
# SETUP INSTRUCTIONS #
# CI INSTRUCTIONS #
# ~~~~~~~~~~~~~~~ #
# This configuration is optimized for continuous delivery of NPM packages #
# using Yarn + TypeScript. #
# ---------------------------------------------------------------------------- #
# #
# 1. Environment variables required in CircleCI: #
Expand All @@ -22,48 +25,77 @@
# #
# lint -- Run a linter against source files. #
# build -- Build output required for publishing to NPM. #
# test -- Run unit tests. #
# test -- Run unit/integration/e2e tests. #
# #
# ---------------------------------------------------------------------------- #
# #
# 4. Ensure the aliases for `&dependency-paths` and `&build-output-paths` #
# below properly reflect the dependency and output directories of your #
# app or module. #
# #
# ---------------------------------------------------------------------------- #
# #
# 5. [OPTIONAL] Configure GREN to your liking using `.grenrc`. #
# #
# See: https://github.com/github-tools/github-release-notes #
# #
# ---------------------------------------------------------------------------- #


version: 2.1

# --- Alias anchor definitions ----------------------------------------------- #

aliases:
- &workspace-root
/home/circleci/project
# --- YAML Aliases ----------------------------------------------------------- #

- &attach-workspace
attach_workspace:
at: *workspace-root

- &dependency-cache-key
v1-dependency-cache-{{ checksum "yarn.lock" }}

- &dependency-paths
paths:
- node_modules
aliases: [
# List of dependency paths that should be persisted to the
# CircleCI workspace.
&dependency-paths [
"node_modules"
],

- &build-output-paths
paths:
- dist
# List of build output paths that should be persisted to the
# CircleCI workspace.
&build-output-paths [
"dist"
],

- &filter-default-branches
filters:
branches:
ignore: /^master$|^next$/
# Yarn lockfile cache key (update "vN" => "vN+1" to cache-bust).
&dependency-cache-key "v1-dependency-cache-{{ checksum \"yarn.lock\" }}",

- &filter-release-branches-only
filters:
branches:
only: master
&workspace-root "/home/circleci/project",

- &filter-prerelease-branches-only
filters:
branches:
only: next
&attach-workspace {
attach_workspace: {
at: *workspace-root
}
},

# Filter pull requests not in "master" or "next" (development code)
&filter-default-branches {
filters: {
branches: {
ignore: "/^master$|^next$/"
}
}
},

# Filter pull requests in "master" only (production code).
&filter-release-branches-only {
filters: {
branches: {
only: "master"
}
}
},

# Filter pull requests in "next" only (pre-release code).
&filter-prerelease-branches-only {
filters: {
branches: {
only: "next"
}
}
},
]

# --- Executor definitions --------------------------------------------------- #

Expand All @@ -75,8 +107,8 @@ executors:
# --- Job definitions -------------------------------------------------------- #

jobs:
# Installs Node dependencies via Yarn, caches them, then persists to the
# workspace.
# Installs Node dependencies via Yarn, caches them, then persists
# to the workspace.
install-dependencies:
executor: default
steps:
Expand All @@ -85,23 +117,23 @@ jobs:
- restore_cache:
key: *dependency-cache-key
- run:
name: Install App Dependencies
command: yarn install --frozen-lockfile
name: Install Module Dependencies
command: yarn install
- save_cache:
<<: *dependency-paths
paths: *dependency-paths
key: *dependency-cache-key
- persist_to_workspace:
<<: *dependency-paths
paths: *dependency-paths
root: *workspace-root

# Runs the linter (tslint) on relevant source files.
# Runs the linter against relevant source files.
lint:
executor: default
steps:
- checkout
- *attach-workspace
- run:
name: Lint TypeScripts
name: Lint source files
command: yarn lint

# Builds modules and persists the build output to the workspace.
Expand All @@ -114,10 +146,10 @@ jobs:
name: Build modules
command: yarn build
- persist_to_workspace:
<<: *build-output-paths
paths: *build-output-paths
root: *workspace-root

# Run unit tests.
# Run unit/integration/e2e tests.
test:
executor: default
steps:
Expand Down Expand Up @@ -179,7 +211,7 @@ jobs:
- *attach-workspace
- run:
name: Install github-release-notes package
command: yarn add github-release-notes
command: yarn add -D -W github-release-notes
- run:
name: Generate release notes and publish to GitHub
command: npx gren release --override --token $GITHUB_REPO_TOKEN
Expand All @@ -193,16 +225,14 @@ jobs:
- *attach-workspace
- run:
name: Install github-release-notes package
command: yarn add github-release-notes
command: yarn add -D -W github-release-notes
- run:
name: Generate release notes and publish to GitHub
command: npx gren release --override --prerelease --token $GITHUB_REPO_TOKEN

# --- Workflow definitions --------------------------------------------------- #
# This configuration is optimized for continuous delivery of NPM packages.

workflows:
version: 2.1

# Builds modules, verifies code with the linter, and runs unit tests.
pull-request:
Expand Down Expand Up @@ -239,6 +269,8 @@ workflows:
requires:
- lint

# Manual approval step as a final gatekeeper to prevent
# possible mistakes!
- confirm-release:
type: approval
requires:
Expand All @@ -261,7 +293,7 @@ workflows:

# Builds modules, verifies code with the linter, runs unit tests, and
# publishes a pre-release version of the built package to NPM.
publish-canary-to-npm:
publish-prerelease-to-npm:
jobs:
- install-dependencies: *filter-prerelease-branches-only

Expand All @@ -277,22 +309,15 @@ workflows:
requires:
- lint

- confirm-prerelease:
type: approval
- create-prerelease:
requires:
- build
- test

- create-prerelease:
requires:
- confirm-prerelease

- tag-release:
requires:
- confirm-prerelease
- create-prerelease

- create-prerelease-notes:
requires:
- confirm-prerelease
- tag-release
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ const myLocalStorage = StorageProxy.createLocalStorage('my-namespace', {
},
});

console.log(myLocalStorage.one.two.three) // => "three"
myLocalStorage.one.two.three.four.five = 'six'; // Works!
console.log(myLocalStorage.one.two.three) // => "three"
myLocalStorage.one.four.five = 'six'; // Works!
```

In TypeScript, you can define the shape of your stored data by passing a [generic type parameter](https://www.typescriptlang.org/docs/handbook/generics.html) to the factory function:
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "storage-proxy",
"version": "0.11.2",
"version": "0.11.3",
"description": "Use web storage (localStorage/sessionStorage) just like plain objects using ES6 Proxies.",
"author": "Ian K Smith <smithki707@gmail.com>",
"license": "MIT",
Expand Down Expand Up @@ -46,6 +46,6 @@
"typescript": "^3.0.3"
},
"dependencies": {
"on-change": "^1.2.0"
"on-change": "^1.6.2"
}
}
83 changes: 79 additions & 4 deletions test/src/storage-proxy.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { StorageProxy, StorageTarget } from '../../src/lib';
const testNamespace = 'qwerty';
const testStr = 'hello world';
const testObj = { monty: 'python', numbers: [1, 2, 3] };
const testArr = [1, 2, 3];

interface TestStorage {
bar: string;
Expand All @@ -19,6 +20,7 @@ interface TestStorage {
example: string;
};
alreadySetDefault: number;
arrayValue: number[];
}

function getItem(storageTarget: StorageTarget, path: string) {
Expand Down Expand Up @@ -48,9 +50,12 @@ export class StorageProxyTestFixture {
public setupFixture() {
localStorage.setItem(
testNamespace,
JSON.stringify({ bar: testStr, test: 999, baz: testObj, alreadySetDefault: 999 }),
JSON.stringify({ bar: testStr, test: 999, baz: testObj, alreadySetDefault: 999, arrayValue: testArr }),
);
sessionStorage.setItem(
testNamespace,
JSON.stringify({ bar: testStr, test: 999, baz: testObj, arrayValue: testArr }),
);
sessionStorage.setItem(testNamespace, JSON.stringify({ bar: testStr, test: 999, baz: testObj }));

this.lStore = StorageProxy.createLocalStorage<TestStorage>(testNamespace, {
defaults: { example: testStr },
Expand All @@ -74,14 +79,14 @@ export class StorageProxyTestFixture {
Expect(this.lStore.alreadySetDefault).toEqual(999);
}

@Test('Set a `localStorage` key')
@Test('Set `localStorage` key')
public setLocalStorageKeyTest() {
this.lStore.fizz = 123;

Expect(getItem(StorageTarget.Local, 'fizz')).toEqual(123);
}

@Test('Set a `sessionStorage` key')
@Test('Set `sessionStorage` key')
public setSessionStorageKeyTest() {
this.sStore.fizz = 123;

Expand All @@ -99,4 +104,74 @@ export class StorageProxyTestFixture {
const data = this.sStore.bar;
Expect(data).toEqual(testStr);
}

@Test('Validate `Array.prototype.push`')
public arrayPushTest() {
this.lStore.baz!.numbers.push(4, 5, 6);
this.lStore.arrayValue!.push(4, 5, 6);
const dataOne = this.lStore.baz!.numbers;
const dataTwo = this.lStore.arrayValue;

const expected = [1, 2, 3, 4, 5, 6];
Expect(dataOne).toEqual(expected);
Expect(dataTwo).toEqual(expected);
Expect(getItem(StorageTarget.Local, 'baz.numbers')).toEqual(expected);
Expect(getItem(StorageTarget.Local, 'arrayValue')).toEqual(expected);
}

@Test('Validate `Array.prototype.pop`')
public arrayPopTest() {
this.lStore.baz!.numbers.pop();
this.lStore.arrayValue!.pop();
const dataOne = this.lStore.baz!.numbers;
const dataTwo = this.lStore.arrayValue;

const expected = [1, 2, 3, 4, 5];
Expect(dataOne).toEqual(expected);
Expect(dataTwo).toEqual(expected);
Expect(getItem(StorageTarget.Local, 'baz.numbers')).toEqual(expected);
Expect(getItem(StorageTarget.Local, 'arrayValue')).toEqual(expected);
}

@Test('Validate `Array.prototype.unshift`')
public arrayUnshiftTest() {
this.lStore.baz!.numbers.unshift(999);
this.lStore.arrayValue!.unshift(999);
const dataOne = this.lStore.baz!.numbers;
const dataTwo = this.lStore.arrayValue;

const expected = [999, 1, 2, 3, 4, 5];
Expect(dataOne).toEqual(expected);
Expect(dataTwo).toEqual(expected);
Expect(getItem(StorageTarget.Local, 'baz.numbers')).toEqual(expected);
Expect(getItem(StorageTarget.Local, 'arrayValue')).toEqual(expected);
}

@Test('Validate `Array.prototype.shift`')
public arrayShiftTest() {
this.lStore.baz!.numbers.shift();
this.lStore.arrayValue!.shift();
const dataOne = this.lStore.baz!.numbers;
const dataTwo = this.lStore.arrayValue;

const expected = [1, 2, 3, 4, 5];
Expect(dataOne).toEqual(expected);
Expect(dataTwo).toEqual(expected);
Expect(getItem(StorageTarget.Local, 'baz.numbers')).toEqual(expected);
Expect(getItem(StorageTarget.Local, 'arrayValue')).toEqual(expected);
}

@Test('Validate `Array.prototype.splice`')
public arraySpliceTest() {
this.lStore.baz!.numbers.splice(1, 2, ...[999, 998]);
this.lStore.arrayValue!.splice(1, 2, ...[999, 998]);
const dataOne = this.lStore.baz!.numbers;
const dataTwo = this.lStore.arrayValue;

const expected = [1, 999, 998, 4, 5];
Expect(dataOne).toEqual(expected);
Expect(dataTwo).toEqual(expected);
Expect(getItem(StorageTarget.Local, 'baz.numbers')).toEqual(expected);
Expect(getItem(StorageTarget.Local, 'arrayValue')).toEqual(expected);
}
}

0 comments on commit d1b55f7

Please sign in to comment.