All Projects → kategengler → Ember Feature Flags

kategengler / Ember Feature Flags

Licence: mit
Ember CLI addon for feature flags

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to Ember Feature Flags

Seo
SEO utilities including a unique field type, sitemap & redirect manager
Stars: ✭ 210 (-0.94%)
Mutual labels:  hacktoberfest
Ach
ACH implements a reader, writer, and validator for Automated Clearing House (ACH) files. The HTTP server is available in a Docker image and the Go package is available.
Stars: ✭ 210 (-0.94%)
Mutual labels:  hacktoberfest
Pytest Qt
pytest plugin for Qt (PyQt4, PyQt5 and PySide) application testing
Stars: ✭ 210 (-0.94%)
Mutual labels:  hacktoberfest
Frankenwm
🖼️ Fast dynamic tiling X11 window manager
Stars: ✭ 209 (-1.42%)
Mutual labels:  hacktoberfest
Tldr
Golang command line client for tldr https://github.com/tldr-pages/tldr
Stars: ✭ 210 (-0.94%)
Mutual labels:  hacktoberfest
Closedxml
ClosedXML is a .NET library for reading, manipulating and writing Excel 2007+ (.xlsx, .xlsm) files. It aims to provide an intuitive and user-friendly interface to dealing with the underlying OpenXML API.
Stars: ✭ 2,799 (+1220.28%)
Mutual labels:  hacktoberfest
Teku
Java Implementation of the Ethereum 2.0 Beacon Chain
Stars: ✭ 209 (-1.42%)
Mutual labels:  hacktoberfest
Doodba
Base image for making the creation of customized Odoo environments a piece of cake
Stars: ✭ 210 (-0.94%)
Mutual labels:  hacktoberfest
Bookmarks
🔖 +4.3K awesome resources for geeks and software crafters 🍺
Stars: ✭ 210 (-0.94%)
Mutual labels:  hacktoberfest
Mercure
Server-sent live updates: protocol and reference implementation
Stars: ✭ 2,608 (+1130.19%)
Mutual labels:  hacktoberfest
Json 2 Csv
Convert JSON to CSV *or* CSV to JSON!
Stars: ✭ 210 (-0.94%)
Mutual labels:  hacktoberfest
Pixieditor
PixiEditor is a lightweight pixel art editor made with .NET 5
Stars: ✭ 210 (-0.94%)
Mutual labels:  hacktoberfest
Oshi
Native Operating System and Hardware Information
Stars: ✭ 2,876 (+1256.6%)
Mutual labels:  hacktoberfest
Eslint Plugin Ava
ESLint rules for AVA
Stars: ✭ 209 (-1.42%)
Mutual labels:  hacktoberfest
Cve Bin Tool
This tool scans for a number of common, vulnerable components (openssl, libpng, libxml2, expat and a few others) to let you know if your system includes common libraries with known vulnerabilities.
Stars: ✭ 211 (-0.47%)
Mutual labels:  hacktoberfest
Add
Разработка с управляемым качеством на 1С
Stars: ✭ 210 (-0.94%)
Mutual labels:  hacktoberfest
Dribbble2react
Transform Dribbble designs to React-Native code | Shop UI Kit >>
Stars: ✭ 2,443 (+1052.36%)
Mutual labels:  hacktoberfest
Osx Push To Talk
OSX status bar application that mute microphone on user key press
Stars: ✭ 209 (-1.42%)
Mutual labels:  hacktoberfest
Vue Morris
VueJS component wrapping Morris.js
Stars: ✭ 212 (+0%)
Mutual labels:  hacktoberfest
Idiomatic Rust
🦀 A peer-reviewed collection of articles/talks/repos which teach concise, idiomatic Rust.
Stars: ✭ 3,130 (+1376.42%)
Mutual labels:  hacktoberfest

ember-feature-flags Build Status Ember Observer Score

An ember-cli addon to provide feature flags.

Note to users of ember.js >= 3.1

Referencing the features service must be done using get as it is a proxy.

Installation

ember install ember-feature-flags

Usage

This addon provides a service named features available for injection into your routes, controllers, components, etc.

For example you may check if a feature is enabled:

Native class syntax:

import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
export default class BillingPlansController extends Controller {
  @service features;
  get plans() {
    if (this.features.isEnabled('newBillingPlans')) {
      // Return new plans
    } else {
      // Return old plans
    }
  }
}

Classic Ember syntax:

import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
export default Controller.extend({
  features: service(),
  plans() {
    if (this.get('features').isEnabled('new-billing-plans')) {
      // Return new plans
    } else {
      // Return old plans
    }
  }
});

Features are also available as properties of features. They are camelized.

Native class syntax:

import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
export default class BillingPlansController extends Controller {
  @service features;
  get plans() {
    if (this.features.get('newBillingPlans')) {
      // Return new plans
    } else {
      // Return old plans
    }
  }
}

Classic Ember syntax:

import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
import { computed } from '@ember/object';
export default Controller.extend({
  features: service(),
  plans: computed('features.newBillingPlans', function(){
    if (this.get('features.newBillingPlans')) {
      // Return new plans
    } else {
      // Return old plans
    }
  })
});

Check whether a feature is enabled in a template (be sure to inject the features service into the template's backing JavaScript):

// templates/components/homepage-link.hbs
{{#if features.newHomepage}}
  {{link-to "new.homepage"}}
{{else}}
  {{link-to "old.homepage"}}
{{/if}}

NOTE: features service must be injected into the respective component:

Native class syntax:

// components/homepage-link.js
export default class HomepageLink extends Component {
  @service features;
}

Classic Ember syntax:

// components/homepage-link.js
export default Component.extend({
  features: service()
});

Alternatively you can use a template helper named feature-flag:

// templates/components/homepage-link.hbs
{{#if (feature-flag 'newHomepage')}}
  {{link-to "new.homepage"}}
{{else}}
  {{link-to "old.homepage"}}
{{/if}}

Features can be toggled at runtime, and are bound:

Native class syntax:

  this.features.enable('newHomepage');
  this.features.disable('newHomepage');

Classic Ember syntax:

this.get('features').enable('newHomepage');
this.get('features').disable('newHomepage');

Features can be set in bulk:

Native class syntax:

this.features.setup({
  "new-billing-plans": true,
  "new-homepage": false
})

Classic Ember syntax:

this.get('features').setup({
  "new-billing-plans": true,
  "new-homepage": false
});

You may want to set the flags based on the result of a fetch:

// routes/application.js
features: inject(),
beforeModel() {
   return fetch('/my-flag/api').then((data) => {
     features.setup(data.json());
  });
}

NOTE: setup methods reset previously setup flags and their state.

You can get list of known feature flags via flags computed property:

this.get('features').setup({
  "new-billing-plans": true,
  "new-homepage": false
});

this.get('features.flags') // ['newBillingPlans', 'newHomepage']

Configuration

config.featureFlags

You can configure a set of initial feature flags in your app's config/environment.js file. This is an easy way to change settings for a given environment. For example:

// config/environment.js
module.exports = function(environment) {
  var ENV = {
    featureFlags: {
      'show-spinners': true,
      'download-cats': false
    }
  };

  if (environment === 'production') {
    ENV.featureFlags['download-cats'] = true;
  }

  return ENV;
};

ENV.LOG_FEATURE_FLAG_MISS

Will log when a feature flag is queried and found to be off, useful to prevent cursing at the app, wondering why your feature is not working.

Test Helpers

enableFeature / disableFeature

Turns on or off a feature for the test in which it is called. Requires ember-cli-qunit >= 4.1.0 and the newer style of tests that use setupTest, setupRenderingTest, setupApplicationTest.

Example:

import { enableFeature, disableFeature } from 'ember-feature-flags/test-support';

module('Acceptance | Awesome page', function(hooks) {
  setupApplicationTest(hooks);

  test('it displays the expected welcome message', async function (assert) {
    enableFeature('new-welcome-message');

    await visit('/');

    assert.dom('h1.welcome-message').hasText('Welcome to the new website!');

    disableFeature('new-welcome-message');

    await settled();

    assert.dom('h1.welcome-message').hasText('This is our old website, upgrade coming soon');
  });
});

withFeature

"Old"-style acceptance tests can utilize withFeature test helper to turn on a feature for the test. To use, import into your test-helper.js: import 'ember-feature-flags/test-support/helpers/with-feature' and add to your test .jshintrc, it will now be available in all of your tests.

Example:

import 'ember-feature-flags/test-support/helpers/with-feature';

test( "links go to the new homepage", function () {
  withFeature( 'new-homepage' );

  visit('/');
  click('a.home');
  andThen(function(){
    equal(currentRoute(), 'new.homepage', 'Should be on the new homepage');
  });
});

Integration Tests

If you use this.features.isEnabled() in components under integration test, you will need to inject a stub service in your tests. Using ember-qunit 0.4.16 or later, here's how to do this:

let featuresService = Service.extend({
  isEnabled() {
    return false;
  }
});

moduleForComponent('my-component', 'Integration | Component | my component', {
  integration: true,
  beforeEach() {
    this.register('service:features', featuresService);
    getOwner(this).inject('component', 'features', 'service:features');
  }
});

Note: for Ember before 2.3.0, you'll need to use ember-getowner-polyfill.

Development

Installation

  • git clone this repository
  • cd ember-feature-flags`
  • yarn install

Running

Running Tests

  • ember try:each (Test against multiple ember versions)
  • ember test
  • ember test --server

Deploying

  • See RELEASE.md
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].